import { useEffect } from 'react';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';

import { useModal } from '@material-hu/hooks/useModal';
import Stack from '@material-hu/mui/Stack';

import CroppingModal from '@material-hu/components/composed-components/CroppingModal';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuFileCard from '@material-hu/components/design-system/FileCard';
import { FileCardType } from '@material-hu/components/design-system/FileCard/types';
import HuFormUploader from '@material-hu/components/design-system/Uploader/form';

import { useLokaliseTranslation } from 'src/utils/i18n';

type Props = {
  name: string;
  recommendedWidth?: number;
  recommendedHeight?: number;
};

type UploaderFormValues = {
  files: FileCardType[];
};

enum UploaderFormFields {
  FILES = 'files',
}

const DEFAULT_WIDTH = 1200;
const DEFAULT_HEIGHT = 630;

const FormImagePreviewer = (props: Props) => {
  const {
    name,
    recommendedWidth = DEFAULT_WIDTH,
    recommendedHeight = DEFAULT_HEIGHT,
  } = props;
  const { t } = useLokaliseTranslation('events');

  const coverPictureForm = useFormContext();
  const coverPicture = coverPictureForm.watch(name);

  const uploaderForm = useForm<UploaderFormValues>({
    defaultValues: {
      files: [],
    },
  });

  useEffect(() => {
    uploaderForm.setValue(
      UploaderFormFields.FILES,
      coverPicture ? [coverPicture] : [],
    );
  }, [coverPicture, uploaderForm.setValue]);

  const onHandleSave = (file: File) => {
    coverPictureForm.setValue(
      name,
      { file, status: 'success' },
      {
        shouldValidate: true,
        shouldDirty: true,
      },
    );
  };

  const {
    modal: croppingModal,
    showModal: showCroppingModal,
    closeModal,
  } = useModal(
    ({ fileToCrop }: { fileToCrop: File }) => (
      <CroppingModal
        cancelLabel={t('CANCEL')}
        saveLabel={t('SAVE')}
        file={fileToCrop}
        onClose={closeModal}
        onSave={onHandleSave}
        recommendedWidth={recommendedWidth}
        recommendedHeight={recommendedHeight}
      />
    ),
    {
      fullWidth: true,
      maxWidth: 'md',
    },
  );

  const onHandleDropAccepted = (filesAccepted: File[]) => {
    uploaderForm.setValue(UploaderFormFields.FILES, []);
    showCroppingModal({ fileToCrop: filesAccepted[0] });
  };

  const onHandleRemove = () => {
    coverPictureForm.setValue(name, null);
  };

  return (
    <>
      {croppingModal}
      <FormProvider {...uploaderForm}>
        {!coverPicture && (
          <HuFormUploader
            name={'files'}
            uploaderProps={{
              onDropAccepted: onHandleDropAccepted,
              acceptedTypes: ['image'],
              sx: { width: '100%' },
              maxFiles: 1,
              helperText: t('IMAGE_PREVIEW_HELPER_TEXT', {
                width: recommendedWidth,
                height: recommendedHeight,
              }),
              uploadFunction: file =>
                new Promise(resolve =>
                  resolve({
                    status: 'uploading',
                    file,
                  }),
                ),
            }}
          />
        )}
      </FormProvider>
      {coverPicture && (
        <HuCardContainer
          sx={{
            width: '100%',
            maxWidth: recommendedWidth,
            gap: 1,
            p: 0,
            '& > .MuiCardContent-root': { p: 0 },
            margin: '0 auto',
          }}
        >
          <HuFileCard
            file={coverPicture.file}
            attachment={coverPicture.attachment}
            status={coverPicture.status}
            onRemove={onHandleRemove}
            sx={{
              maxWidth: recommendedWidth,
              width: '100%',
              border: 'none',
              '& .MuiTypography-root': {
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap',
                maxWidth: recommendedWidth / 1.5,
              },
            }}
          />
          <Stack
            sx={{
              width: '100%',
              height: '100%',
              maxHeight: recommendedHeight,
              maxWidth: recommendedWidth,
              justifyContent: 'center',
              aspectRatio: `${recommendedWidth}/${recommendedHeight}`,
            }}
          >
            <img
              src={coverPicture?.url || URL.createObjectURL(coverPicture.file!)}
              alt={t('COVER_PICTURE_ALT')}
            />
          </Stack>
        </HuCardContainer>
      )}
    </>
  );
};

export default FormImagePreviewer;
