/**
 * @deprecated Use `@material-hu/components/composed-components/CoverPictureUploader/form` instead
 */
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { useMutation } from 'react-query';

import { useDropzone } from '@humanddev/material-hu/dropzone';
import { useModal } from '@material-hu/hooks/useModal';
import CloudUploadIcon from '@material-hu/icons/material/CloudUpload';
import Alert from '@material-hu/mui/Alert';
import Box from '@material-hu/mui/Box';
import Stack from '@material-hu/mui/Stack';
import { alpha } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

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

import useAuth from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import * as instancesService from 'src/services/instancesService';
import * as usersService from 'src/services/usersService';
import { type Instance } from 'src/types/instance';
import {
  megabytesToBytes,
  removeURLParams,
  signedUpload,
} from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import Cropping from 'src/components/Cropping';

import CoverSteps from './CoverSteps';

const BUCKET_ERROR_KEY = 'BucketUrl';

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

const FormCommunityCover = ({
  onUpdate,
  name,
  recommendedWidth = 1100,
  recommendedHeight = 300,
}: Props) => {
  const { t } = useLokaliseTranslation('backoffice_only');
  const { enqueueSnackbar } = useHuSnackbar();
  const {
    watch,
    setValue,
    formState: { errors },
  } = useFormContext();
  const { instance, updateInstance } = useAuth();
  const showGeneralError = useGeneralError();

  const coverPicture = watch(name);

  const hasBucketUrlError = (error: any) =>
    error?.data?.some((item: any) => Object.hasOwn(item, BUCKET_ERROR_KEY));

  const showOnError = (err: any) => {
    if (hasBucketUrlError(err.response)) {
      return showGeneralError(
        err,
        t('backoffice_only:form_community_cover.invalid_cover_image'),
      );
    }
    return showGeneralError(err, t(`ERROR ${err}`));
  };

  const coverMutation = useMutation(
    async ({ url }: { url: string }) => {
      await instancesService.updateInstance(instance?.id as number, {
        defaultCoverPicture: url,
      });
    },
    {
      onSuccess: () => {
        updateInstance?.({
          ...instance,
          defaultCoverPicture: coverPicture,
        } as Instance);
        enqueueSnackbar({
          title: t('backoffice_only:form_community_cover.updated_success'),
          variant: 'success',
        });
      },
      onError: (err: any) => {
        showOnError(err);
      },
    },
  );

  const bulkCoverMutation = useMutation(
    async ({ url }: { url: string }) => {
      await usersService.updateBulkCover(url);
    },
    {
      onSuccess: () => {
        updateInstance?.({
          ...instance,
          defaultCoverPicture: coverPicture,
        } as Instance);
        enqueueSnackbar({
          title: t('backoffice_only:form_community_cover.bulk_success'),
          variant: 'success',
        });
      },
      onError: (err: any) => {
        showOnError(err);
      },
    },
  );

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

    if (onUpdate) {
      await onUpdate(coverP);
    }

    try {
      const signedURL = removeURLParams(
        await signedUpload(coverP, true, false),
      );
      await coverMutation.mutateAsync({ url: signedURL });
      setValue(name, URL.createObjectURL(coverP), {
        shouldValidate: true,
        shouldDirty: true,
      });
      return true;
    } catch (error) {
      return false;
    }
  };

  const [cover, setCover] = useState<File | null>(null);
  const [activeStep, setActiveStep] = useState(0);

  const {
    modal: coverStepsModal,
    showModal: showCoverStepsModal,
    closeModal: closeCoverStepsModal,
  } = useModal(
    CoverSteps,
    { fullWidth: true, maxWidth: 'sm', disableEscapeKeyDown: activeStep === 0 },
    {
      onSave: () => handleCoverSave(cover!),
      onReplace: async () =>
        bulkCoverMutation.mutate({
          url: removeURLParams(await signedUpload(cover!, true, false)),
        }),
      onClose: () => {
        setActiveStep(0);
        closeCoverStepsModal();
      },
      step: activeStep,
      setStep: setActiveStep,
    },
  );

  const handleCover = async (coverP: File) => {
    setCover(coverP);
    showCoverStepsModal({ coverPicture: URL.createObjectURL(coverP) });
  };

  const {
    modal: croppingModal,
    showModal: showCroppingModal,
    closeModal,
  } = useModal(
    Cropping,
    { fullWidth: true, maxWidth: 'md' },
    {
      onSave: handleCover,
      onClose: () => {
        closeModal();
      },
      recommendedWidth,
      recommendedHeight,
      title: t('backoffice_only:form_community_cover.edit_coverpicture'),
    },
  );

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

  return (
    <>
      <Box
        sx={{
          mx: 'auto',
          width: '100%',
          maxHeight: recommendedHeight,
          maxWidth: recommendedWidth,
        }}
      >
        {croppingModal}
        {coverStepsModal}
        {coverPicture ? (
          <>
            <Stack
              sx={{
                justifyContent: 'top',
                height: '80px',
                aspectRatio: 'auto',
                '& img': {
                  display: 'block',
                  objectFit: 'cover',
                  width: '100%',
                  height: '70px',
                  borderRadius: '10px',
                },
              }}
            >
              <img
                src={coverPicture}
                alt=""
              />
            </Stack>
            <Button
              onClick={open}
              sx={{ p: 0, pl: 1 }}
            >
              <input {...getInputProps()} />
              <Typography
                variant="subtitle2"
                color="black"
                sx={{ fontSize: '13px' }}
              >
                {t('backoffice_only:form_community_cover.modify_picture')}
              </Typography>
            </Button>
          </>
        ) : (
          <Box
            sx={{
              border: 1,
              borderRadius: 1,
              borderColor: 'divider',
              backgroundColor: theme =>
                alpha(theme.palette.action.active, isDragActive ? 0.1 : 0.05),
              borderStyle: 'dashed',
              width: '100%',
              height: '100%',
              aspectRatio: `${recommendedWidth}/${recommendedHeight}`,
            }}
          >
            <Stack
              {...getRootProps()}
              sx={{
                height: '100%',
                alignItems: 'center',
                justifyContent: 'center',
                cursor: 'pointer',
                '&:hover': {
                  opacity: 0.5,
                },
              }}
            >
              <input {...getInputProps()} />
              <CloudUploadIcon fontSize="large" />
            </Stack>
          </Box>
        )}
      </Box>
      {errors[name] && (
        <Alert
          sx={{ my: 1 }}
          severity="error"
        >
          {errors[name]?.message as string}
        </Alert>
      )}
    </>
  );
};

export default FormCommunityCover;
