import React, {useCallback} from 'react';
import {useTranslation} from 'react-i18next';
import {useNavigation} from '@react-navigation/native';
import {useTapDebounce} from '@hooks/useTapDebounce';
import {FileDisplayer} from '@modules/chats/components';
import {DocumentAsset} from '@modules/chats/interfaces';
import {useChatFile} from '@modules/chats/hooks';
import {fileHandler} from '@modules/chats/instances/FileHandler';
import {ERROR_MESSAGES} from '@modules/chats/constants';
import {showSnackbar} from '@redux/dispatchers';
import {isIos, openPdfInAppViewer} from '@shared/utils';

interface AttachmentMessageDisplayerProps {
  attachment: DocumentAsset;
  messageId: string;
  channel: string;
}
export const AttachmentMessageDisplayer = ({
  attachment,
  messageId,
  channel,
}: AttachmentMessageDisplayerProps) => {
  const {t} = useTranslation();
  const {setOptions} = useNavigation();
  const {url, isLoading, isError, retryDownload, asset} = useChatFile({
    assetId: attachment.id,
    messageId,
    channel,
  });
  const isUrlValid = !!url && !isError;
  const scheduleTap = useTapDebounce();

  const setNavigationGestureEnabled = (enabled: boolean) => {
    if (isIos) {
      setOptions({gestureEnabled: enabled});
    }
  };

  const openAttachment = async () => {
    try {
      await fileHandler.openFile({
        assetId: attachment.id,
        messageId,
        filename: attachment.filename,
        remoteUrl: attachment.url,
        url: isUrlValid ? url : null,
        asset: asset!,
        channel,
        willOpen: () => {
          // Hack (iOS), when the ViewController is closing, disable the gesture to prevent screen freezing
          // for the case, when a user closed the FileViewer and swiped back (the screen freezes)
          setNavigationGestureEnabled(false);
        },
        didClose: () => {
          setNavigationGestureEnabled(true);
        },
      });
    } catch (error) {
      setNavigationGestureEnabled(true);
      const err = error as Error;
      if (err.message === ERROR_MESSAGES.NO_APP_ASSOCIATED) {
        const isPdf = attachment.filename.toLowerCase().endsWith('.pdf');
        if (!isIos && isPdf) {
          const fileUri = isUrlValid ? url : attachment.url;
          openPdfInAppViewer({uri: fileUri, title: attachment.filename});
          return;
        }
        showSnackbar({
          title: t('general.application_missing'),
          variant: 'error',
        });
        return;
      }
      showSnackbar({
        title: t('errors.api.404'),
        variant: 'error',
      });
    }
  };

  const onPress = () => {
    if (isLoading) return;
    if (isError) {
      retryDownload();
      return;
    }
    scheduleTap(openAttachment);
  };

  // Tap-to-cancel for the in-progress download. Documents can be
  // arbitrarily large and have no timeout — letting the user abort
  // mid-download is the only way out short of leaving the screen.
  const onCancel = useCallback(() => {
    fileHandler.cancelDownload(attachment.id);
  }, [attachment.id]);

  return (
    <FileDisplayer
      onPress={onPress}
      bytesSize={attachment.size}
      fileName={attachment.filename}
      isLoading={isLoading}
      onCancel={isLoading ? onCancel : undefined}
      showDownload={!isUrlValid}
      showCheck={isUrlValid}
    />
  );
};
