import { type FC, useEffect, useState } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';

import { type AxiosError } from 'axios';
import { useModal } from '@material-hu/hooks/useModal';
import Stack from '@material-hu/mui/Stack';
import * as animations from '@material-hu/utils/animations';

import PdfVisualizer from '@material-hu/components/composed-components/PdfVisualizer';
import HuSignDialog from '@material-hu/components/composed-components/sign/documents/SignDialog';
import Button from '@material-hu/components/design-system/Buttons/Button';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import { logEvent } from 'src/config/amplitude';
import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useAskForPassword from 'src/pages/dashboard/documents/hooks/useAskForPassword';
import useGetDocument from 'src/pages/dashboard/documents/hooks/useGetDocument';
import useGetDocumentUrl from 'src/pages/dashboard/documents/hooks/useGetDocumentUrl';
import useSignDocument from 'src/pages/dashboard/documents/hooks/useSignDocument';
import useUploadSignature from 'src/pages/dashboard/documents/hooks/useUploadSignature';
import { signUrl } from 'src/services/attachments';
import { EventName } from 'src/types/amplitude';
import { FileTypes } from 'src/types/attachments';
import { DocumentErrorCodes } from 'src/types/documents';
import { type ResponseError } from 'src/types/services';
import { useLokaliseTranslation } from 'src/utils/i18n';

import FocusNavbar from 'src/components/FocusNavbar';

import { invalidatePendingDocumentList } from './queries';
import { documentsRoutes } from './routes';

type LocationState = {
  prevPath: string;
};

const MIN_STROKES_REQUIRED = 20;

const SignDocument: FC = () => {
  const { state } = useLocation();
  const { prevPath } = (state as LocationState) || {};
  const { enqueueSnackbar } = useHuSnackbar();
  const navigate = useNavigate();
  const HuGoThemeProvider = useHuGoTheme();
  const [inDisagreement, setInDisagreement] = useState(false);
  const showGeneralError = useGeneralError();

  const { id: documentId } = useParams();
  const { t } = useLokaliseTranslation(['documents', 'errors']);

  const handleGoBack = () => {
    navigate(prevPath || '..', { replace: true });
  };

  const {
    askForPassword,
    shouldGivePassword,
    modal: passwordModal,
  } = useAskForPassword({
    onCancel: handleGoBack,
  });

  useEffect(() => {
    askForPassword();
  }, []);

  const { data: document, isLoading: isLoadingRequest } = useGetDocument({
    documentId,
  });

  const { data: pdfUrl, isLoading: isLoadingPdfUrl } = useGetDocumentUrl({
    source: document?.source,
  });

  const { mutateAsync: signDocument, isLoading: isSigning } = useSignDocument({
    onSuccess(data) {
      logEvent(EventName.DOCUMENT_SIGN, {
        fileId: data.data.id,
        folderId: data.data.folderId,
        inDisagreement,
      });

      enqueueSnackbar({
        title: t('success_document_sign'),
        variant: 'success',
      });

      invalidatePendingDocumentList();
      navigate(documentsRoutes.documents());
      closeModal();
    },
    onError(error: AxiosError<ResponseError>) {
      if (
        error?.response?.data?.code ===
        DocumentErrorCodes.SIGNATURE_INVALID_COORDINATES
      ) {
        showGeneralError(
          error,
          t('errors:api.codes.SIGNATURE_INVALID_COORDINATES'),
        );
        return;
      }

      showGeneralError(error, t('documents:error_document_sign'));
    },
  });

  const { mutateAsync: uploadSignature, isLoading: isUploading } =
    useUploadSignature();

  const onHandleSave = async (signature: string | undefined) => {
    if (!signature) return;

    const trimDataUrl = signature.slice(22);

    let signedUrl: string;
    let uploadedSignature: string;

    try {
      signedUrl = await signUrl('image.png', FileTypes.IMAGE, 'image/png');
      uploadedSignature = await uploadSignature({
        image: trimDataUrl,
        signedUrl,
      });
    } catch (error) {
      showGeneralError(error, t('documents:error_document_sign'));
      return;
    }

    await signDocument({
      id: Number(documentId),
      signatureUrl: uploadedSignature,
      inDisagreement,
    });
  };

  const {
    modal: modalSign,
    showModal,
    closeModal,
  } = useModal(
    HuSignDialog,
    { fullWidth: true },
    {
      onSave: onHandleSave,
      onClose: () => closeModal(),
      loading: isUploading || isSigning,
      minStrokes: MIN_STROKES_REQUIRED,
    },
  );

  return (
    <HuGoThemeProvider>
      {modalSign}
      {passwordModal}
      <FocusNavbar
        bottomBarSx={{
          borderTop: '1px solid',
          borderColor: theme => theme.palette.new.border.neutral.default,
        }}
        sx={{ animation: `${animations.fadeIn} 0.3s ease` }}
        navbarProps={{
          title: document?.name || '',
          onClick: () => navigate(documentsRoutes.documents()),
          sx: { height: 64, p: 2 },
        }}
        loadingProps={{
          isLoading: isLoadingRequest || isLoadingPdfUrl,
        }}
        content={
          !isLoadingPdfUrl &&
          !shouldGivePassword && (
            <PdfVisualizer
              file={pdfUrl || ''}
              slotProps={{
                pdfDimensions: { baseWidth: 700 },
              }}
            />
          )
        }
        bottomBarContent={
          <Stack
            sx={{
              width: '100%',
              maxWidth: 1036,
              flexDirection: 'row',
              justifyContent: 'flex-end',
              gap: 3,
            }}
          >
            {document?.allowDisagreement && (
              <Button
                onClick={() => {
                  showModal();
                  setInDisagreement(true);
                }}
                size="large"
                variant="secondary"
                sx={{ minWidth: 248 }}
              >
                {t('documents:sign_document_disagreement')}
              </Button>
            )}
            <Button
              onClick={() => showModal()}
              variant="primary"
              size="large"
              sx={{ minWidth: 248 }}
            >
              {t('documents:sign_document')}
            </Button>
          </Stack>
        }
      />
    </HuGoThemeProvider>
  );
};

export default SignDocument;
