import {
  pick,
  types,
  isErrorWithCode,
  errorCodes,
} from '@react-native-documents/picker';
import {ImageOrVideo} from 'react-native-image-crop-picker';
import {HuGoFile} from '@components/_HuGo/interfaces';
import {trackCustomHumandError} from '@hooks/useGeneralError';
import {getFileNameFromUrl, getUuid} from '@shared/utils';

import {
  VALID_TYPES_MAPPER,
  UploaderValidTypes,
  UploaderInputs,
  UploaderInputFlags,
} from './interfaces';

import type {DocumentPickerOptions} from '@react-native-documents/picker';

export const formatValidTypes = (
  validTypes?: UploaderValidTypes[],
): DocumentPickerOptions['type'] => {
  return validTypes?.map(type => VALID_TYPES_MAPPER[type]);
};

export const hasImageType = (validTypes?: UploaderValidTypes[]) => {
  return validTypes?.some(type => type === UploaderValidTypes.Image);
};

export const formatAssetToFile = (asset: ImageOrVideo): HuGoFile => {
  const path = asset.sourceURL || asset.path;
  return {
    hasError: !path,
    id: getUuid(),
    isUploading: !!path,
    mime: asset.mime,
    name: asset.filename || getFileNameFromUrl(path),
    width: asset.width,
    height: asset.height,
    path,
    size: asset.size,
    type: asset.mime.includes('image') ? 'IMAGE' : 'FILE',
  };
};

export const pickFiles = async (
  pickerOptions: DocumentPickerOptions,
): Promise<HuGoFile[]> => {
  try {
    const files = await pick({
      type: [types.allFiles],
      allowMultiSelection: false,
      ...pickerOptions,
    });
    return files.map(file => {
      const hasError = !file.size || !file.type;
      return {
        hasError,
        id: getUuid(),
        isUploading: !hasError,
        mime: file.type!,
        name: file.name || getFileNameFromUrl(file.uri),
        path: file.uri,
        size: file.size || 0,
        type: 'FILE',
      };
    });
  } catch (err: unknown) {
    if (!(isErrorWithCode(err) && err.code === errorCodes.OPERATION_CANCELED)) {
      trackCustomHumandError(err, 'PickFilesError');
    }
    return [];
  }
};

export const getUploaderInputFlags = (
  inputs: UploaderInputs[],
): UploaderInputFlags => ({
  documents: inputs.includes(UploaderInputs.Documents),
  video: inputs.includes(UploaderInputs.Video),
  gallery: inputs.includes(UploaderInputs.Gallery),
  camera: inputs.includes(UploaderInputs.Camera),
});

export const isDocumentsOnly = (inputs: UploaderInputs[]): boolean =>
  inputs.length === 1 && inputs[0] === UploaderInputs.Documents;
