import { type FC, useRef, useState } from 'react';
import { useMutation } from 'react-query';
import SignatureScreen from 'react-signature-canvas';

import CloseIcon from '@material-hu/icons/material/Close';
import Box from '@material-hu/mui/Box';
import Container from '@material-hu/mui/Container';
import IconButton from '@material-hu/mui/IconButton';
import { styled, useTheme } from '@material-hu/mui/styles';

import Button from '@material-hu/components/design-system/Buttons/Button';

import useGeneralError from 'src/hooks/useGeneralError';
import { signUrl } from 'src/services/attachments';
import { uploadDigitalSignature } from 'src/services/forms';
import { type Attachment, FileTypes } from 'src/types/attachments';
import {
  getDefaultTrimDataUrl,
  type InputDigitalSign,
} from 'src/utils/documents';
import { useLokaliseTranslation } from 'src/utils/i18n';

import AcceptCancelDialog from 'src/components/AcceptCancelDialog';

const Dialog = styled(AcceptCancelDialog)({
  '& .MuiPaper-root': {
    width: '50%',
    height: '50%',
  },
});

const ContainerSignature = styled(Container)(({ theme }) => ({
  width: '100%',
  height: '100%',
  '& .signature': {
    border: `1px solid ${theme.palette.new.border.neutral.default}`,
    width: '100%',
    height: '100%',
  },
}));

const SigImage = styled('img')({
  width: '100px',
  height: '100px',
});

type DigitalSignInputProps = {
  onChange: (values: any) => void;
  inputDigitalSign?: InputDigitalSign;
  answerInput?: Attachment[];
  disabled: boolean;
  showPreviewSignature?: boolean;
  signOnPdf?: boolean;
  pdfSignWidth?: string;
  pdfSignHeight?: string;
  required?: boolean;
  acceptLabel?: string;
  cancelLabel?: string;
  titleModalLabel?: string;
  buttonLabel?: string;
  onSubmitDigitalSign?: () => void;
  variantButton?: 'text' | 'outlined' | 'contained';
};

const DigitalSignInput: FC<DigitalSignInputProps> = ({
  onChange,
  inputDigitalSign,
  answerInput,
  disabled,
  showPreviewSignature = true,
  acceptLabel,
  cancelLabel,
  titleModalLabel,
  buttonLabel,
  onSubmitDigitalSign,
  signOnPdf,
  required,
  variantButton = 'outlined',
}) => {
  const [open, setOpen] = useState(false);
  const [trimDataUrl, setTrimDataUrl] = useState(
    getDefaultTrimDataUrl(answerInput, inputDigitalSign),
  );
  const digitalSign = useRef() as React.MutableRefObject<any>;
  const { t } = useLokaliseTranslation('forms');
  const showGeneralError = useGeneralError();
  const theme = useTheme();

  const imageMutation = useMutation(
    async (img: string) => {
      const signedUrl = await signUrl(
        'image.png',
        FileTypes.IMAGE,
        'image/png',
      );

      const res = await uploadDigitalSignature(img, signedUrl);

      return res;
    },
    {
      onSuccess: response => {
        onChange({
          answer: [{ url: response, type: FileTypes.IMAGE }],
          trimDataUrl,
        });
        setOpen(false);
      },
      onError: err => {
        showGeneralError(err, t('ERROR_LOAD_SIGN'));
      },
    },
  );

  const handleOnEnd = () => {
    const { current } = digitalSign;
    if (current) {
      setTrimDataUrl(current.getCanvas().toDataURL('image/png'));
    }
  };

  const handleOnCancel = () => {
    const { current } = digitalSign;
    if (current) {
      current.clear();
    }
    setTrimDataUrl('');
    onChange(undefined);
    setOpen(false);
  };

  const getSignImageAndChangeAnswer = async () => {
    await imageMutation.mutateAsync(trimDataUrl.slice(22));
  };

  const handleOnAccept = async () => {
    if (onSubmitDigitalSign) {
      if (trimDataUrl) {
        await getSignImageAndChangeAnswer();
      }
      onSubmitDigitalSign();
    } else {
      getSignImageAndChangeAnswer();
    }
  };

  const pdfSign =
    trimDataUrl && showPreviewSignature ? (
      <>
        {!disabled && (
          <IconButton
            sx={{
              position: 'absolute',
              top: '-10px',
              left: '-10px',
              backgroundColor: theme.palette.new.background.layout.tertiary,
              border: `1px solid ${theme.palette.new.border.neutral.brand}`,
              width: '20px',
              height: '20px',
              '&:hover': {
                backgroundColor: theme.palette.new.background.layout.tertiary,
              },
            }}
            size="small"
            onClick={handleOnCancel}
          >
            <CloseIcon sx={{ width: '14px', height: '14px' }} />
          </IconButton>
        )}
        <img
          alt="signature"
          src={trimDataUrl}
          height="100%"
          width="100%"
        />
      </>
    ) : (
      <Button
        color="primary"
        onClick={() => setOpen(true)}
        sx={{ padding: 0, fontSize: '12px', height: '100%', width: '100%' }}
      >
        {`${t('DIGITAL_SIGN_INPUT')}${required ? '*' : ''}`}
      </Button>
    );

  return (
    <>
      {signOnPdf ? (
        pdfSign
      ) : (
        <Box
          sx={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
          }}
        >
          <Button
            variant={variantButton}
            size="large"
            color="primary"
            onClick={() => setOpen(true)}
            sx={{ my: 2, width: '30%' }}
            disabled={disabled}
          >
            {buttonLabel || t('DIGITAL_SIGN_INPUT')}
          </Button>
          {trimDataUrl && showPreviewSignature && (
            <Container
              sx={{
                display: 'inherit',
                flexDirection: 'column-reverse',
                alignItems: 'inherit',
                width: 'fit-content',
              }}
            >
              <SigImage
                alt="signature"
                src={trimDataUrl}
                sx={{
                  height: '100px',
                  width: '150px',
                }}
              />
              {!disabled && (
                <IconButton
                  size="small"
                  onClick={handleOnCancel}
                  sx={{
                    alignSelf: 'flex-end',
                  }}
                >
                  <CloseIcon />
                </IconButton>
              )}
            </Container>
          )}
        </Box>
      )}
      <Dialog
        open={open}
        title={titleModalLabel || t('DIGITAL_SIGN_TITLE')}
        onCancel={handleOnCancel}
        onAccept={handleOnAccept}
        showCancel
        acceptLabel={acceptLabel}
        cancelLabel={cancelLabel}
        disabled={imageMutation.isLoading}
      >
        <ContainerSignature>
          <SignatureScreen
            ref={digitalSign}
            onEnd={handleOnEnd}
            canvasProps={{ className: 'signature' }}
          />
        </ContainerSignature>
      </Dialog>
    </>
  );
};

export default DigitalSignInput;
