import { useFormContext } from 'react-hook-form';

import { useDropzone } from '@humanddev/material-hu/dropzone';
import { useModal } from '@material-hu/hooks/useModal';
import { IconUpload } from '@material-hu/icons/tabler';
import Button from '@material-hu/mui/Button/Button';
import IconButton from '@material-hu/mui/IconButton';
import Paper from '@material-hu/mui/Paper';
import Stack from '@material-hu/mui/Stack';
import { alpha } from '@material-hu/mui/styles';
import Tooltip from '@material-hu/mui/Tooltip';
import Typography from '@material-hu/mui/Typography';

import CroppingModalHU from '@material-hu/components/composed-components/CroppingModal';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import ImageIcon from 'src/icons/Image';
import TrashIcon from 'src/icons/Trash';
import { megabytesToBytes } from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';

type Props = {
  onDelete?: () => void;
  onUpdate?: (cover: File) => void;
  name: string;
  recommendedWidth?: number;
  recommendedHeight?: number;
};

const FormCoverPicture = ({
  onDelete,
  onUpdate,
  name,
  recommendedWidth = 1100,
  recommendedHeight = 300,
}: Props) => {
  const { t } = useLokaliseTranslation('web_only');
  const { enqueueSnackbar } = useSnackbar();
  const { watch, setValue } = useFormContext();
  const coverPicture = watch(name);

  const handleCoverSave = async (coverP: File) => {
    if (coverP.size > megabytesToBytes(5)) {
      enqueueSnackbar({
        title: t('form_inputs.file_too_large'),
        variant: 'error',
      });
      return null;
    }

    if (onUpdate) {
      onUpdate(coverP);
    }

    return setValue(
      name,
      { file: coverP, url: null },
      { shouldValidate: true, shouldDirty: true },
    );
  };

  const {
    modal: croppingModal,
    showModal: showCroppingModal,
    closeModal,
  } = useModal<{ file: File }>(
    ({ file }) => (
      <CroppingModalHU
        cancelLabel={t('general:cancel')}
        saveLabel={t('general:save')}
        onSave={handleCoverSave}
        file={file}
        onClose={closeModal}
        recommendedWidth={recommendedWidth}
        recommendedHeight={recommendedHeight}
        title={t('form_inputs.edit_coverpicture')}
      />
    ),
    { fullWidth: true, maxWidth: 'md' },
  );

  const { getRootProps, getInputProps, open, isDragActive } = useDropzone({
    onDrop: files => {
      if (files[0]) {
        showCroppingModal({ file: files[0] });
      }
    },
    accept: {
      'image/jpeg': [],
      'image/png': [],
    },
    maxFiles: 1,
    noClick: true,
  });

  return (
    <>
      {croppingModal}
      <Stack
        {...getRootProps()}
        sx={{
          mx: 'auto',
          width: '100%',
          height: '100%',
          position: 'relative',
          outline: 'none',
          ...(isDragActive &&
            !!coverPicture && {
              '&::after': {
                content: '""',
                position: 'absolute',
                top: 0,
                left: 0,
                right: 0,
                bottom: 0,
                border: 2,
                borderColor: 'primary.main',
                borderStyle: 'dashed',
                borderRadius: 1,
                zIndex: 10,
                pointerEvents: 'none',
                backgroundColor: theme =>
                  alpha(theme.palette.new.background.layout.tertiary, 0.5),
              },
            }),
        }}
      >
        <input {...getInputProps()} />
        {coverPicture ? (
          <>
            <Stack
              sx={{
                justifyContent: 'center',
                aspectRatio: `${recommendedWidth}/${recommendedHeight}`,
                '& img': {
                  borderRadius: 1,
                  aspectRatio: `${recommendedWidth}/${recommendedHeight}`,
                  display: 'block',
                  objectFit: 'cover',
                },
              }}
            >
              <img
                src={coverPicture.url || URL.createObjectURL(coverPicture.file)}
                alt=""
              />
            </Stack>
            <Paper sx={{ ml: 'auto', width: 'fit-content', px: 1.5 }}>
              <Tooltip title={t('form_inputs.replace_image')}>
                <IconButton
                  edge="start"
                  onClick={open}
                >
                  <ImageIcon fontSize="small" />
                </IconButton>
              </Tooltip>
              <Tooltip title={t('form_inputs.remove_image')}>
                <IconButton
                  edge="end"
                  onClick={
                    onDelete ||
                    (() =>
                      setValue(name, null, {
                        shouldDirty: true,
                        shouldValidate: true,
                      }))
                  }
                >
                  <TrashIcon fontSize="small" />
                </IconButton>
              </Tooltip>
            </Paper>
          </>
        ) : (
          <Stack
            sx={{
              border: 1,
              borderRadius: 1,
              borderColor: theme =>
                isDragActive
                  ? theme.palette.primary.main
                  : theme.palette.new.border.neutral.default,
              borderStyle: 'dashed',
              width: '100%',
              height: '100%',
              aspectRatio: `${recommendedWidth}/${recommendedHeight}`,
            }}
          >
            <Stack
              sx={{
                height: '100%',
                alignItems: 'center',
                justifyContent: 'center',
                gap: 1,
              }}
            >
              <Stack sx={{ alignItems: 'center' }}>
                <Typography
                  variant="globalS"
                  fontWeight="fontWeightSemiBold"
                >
                  {t('form_inputs.drag_cover_picture')}
                </Typography>
                <Typography variant="globalXS">
                  {t('form_inputs.drag_cover_picture_description', {
                    width: recommendedWidth,
                    height: recommendedHeight,
                  })}
                </Typography>
              </Stack>
              <Button
                variant="outlined"
                color="primary"
                onClick={open}
                sx={{
                  color: theme => theme.palette.new.text.neutral.default,
                }}
                endIcon={<IconUpload />}
              >
                {t('general:attachment.upload.title')}
              </Button>
            </Stack>
          </Stack>
        )}
      </Stack>
    </>
  );
};

export default FormCoverPicture;
