import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useMutation, useQuery } from 'react-query';
import { useNavigate, useParams } from 'react-router-dom';

import Card from '@material-hu/mui/Card';
import CardActions from '@material-hu/mui/CardActions';
import CardContent from '@material-hu/mui/CardContent';
import CardHeader from '@material-hu/mui/CardHeader';
import Container from '@material-hu/mui/Container';
import Typography from '@material-hu/mui/Typography';

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

import ArrowLeftIcon from 'src/icons/ArrowLeft';
import {
  createAcknowledgementsProduct,
  getAcknowledgementsProduct,
  updateAcknowledgementsProduct,
} from 'src/services/acknowledgementsService';
import { removeURLParams, signedUpload } from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  validateMinRule,
  validateRequiredStringRule,
} from 'src/utils/validation';

import CenteredCircularProgress from 'src/components/CircularProgress';
import FormFileDropZone from 'src/components/FormInputs/FormFileDropzone';
import FormTextField from 'src/components/FormInputs/FormTextField';

import { acknowledgementsKeys } from '../queries';
import { acknowledgementsRoutes } from '../routes';

type ProductFormValues = {
  name: string;
  coverPicture?: { url?: string; file?: File } | null;
  cost: number;
  description: string;
};

const Product = () => {
  const { t } = useLokaliseTranslation('acknowledgements');
  const { t: tLokalise } = useLokaliseTranslation();
  const { enqueueSnackbar } = useSnackbar();
  const navigate = useNavigate();
  const productId = parseInt(useParams().id || '0');
  const goBack = () => navigate(acknowledgementsRoutes.acknowledgements());

  const form = useForm<ProductFormValues>({
    defaultValues: {
      name: '',
      coverPicture: null,
      cost: 1,
      description: '',
    },
    mode: 'onChange',
  });

  const {
    control,
    formState: { isDirty, isValid },
  } = form;

  const hasCoverPicture = !!useWatch({
    name: 'coverPicture',
    control,
  });

  const { isLoading } = useQuery(
    acknowledgementsKeys.product(productId),
    () => getAcknowledgementsProduct(productId),
    {
      enabled: !!productId,
      select: r => r.data,
      onSuccess: product => {
        form.reset({
          name: product.name,
          cost: product.cost,
          description: product.description || '',
          coverPicture: product.coverPicture
            ? { url: product.coverPicture }
            : null,
        });
      },
    },
  );

  const mutation = useMutation(
    async () => {
      const values = form.getValues();
      values.description = values.description || '';
      values.cost = Number(values.cost);

      let coverPictureUrl = values.coverPicture?.url;
      if (values.coverPicture?.file) {
        const signedFileUrl = await signedUpload(values.coverPicture.file);
        coverPictureUrl = removeURLParams(signedFileUrl);
      }

      const payload = {
        ...values,
        coverPicture: coverPictureUrl,
      };

      if (productId) return updateAcknowledgementsProduct(productId, payload);
      return createAcknowledgementsProduct(payload);
    },
    {
      onSuccess: () => {
        enqueueSnackbar({
          title: t('products_form.product_saved'),
          variant: 'success',
        });
        goBack();
      },
    },
  );

  if (isLoading) {
    return <CenteredCircularProgress centered />;
  }

  return (
    <FormProvider {...form}>
      <Container
        maxWidth="md"
        sx={{ py: 3 }}
      >
        <Button
          startIcon={<ArrowLeftIcon fontSize="small" />}
          onClick={() => goBack()}
          variant="outlined"
        >
          {tLokalise('general:go_back')}
        </Button>
        <Card sx={{ mt: 2 }}>
          <CardHeader
            titleTypographyProps={{ variant: 'h5', mb: 2 }}
            title={t('products_form.new_product')}
          />
          <CardContent
            sx={{
              pt: 0,
              display: 'flex',
              flexDirection: 'column',
              gap: 2,
              width: '60%',
            }}
          >
            <FormTextField
              name="name"
              label={t('products_form.product_name')}
              helperText={t('products_form.product_name_helper_text')}
              rules={{ validate: validateRequiredStringRule }}
              inputProps={{ maxLength: 255 }}
              margin="normal"
            />
            <div>
              <FormFileDropZone
                name="coverPicture"
                fileDescription={t('products_form.product_photo')}
                maxFiles={1}
                maxSize={3 * 1024 * 1024}
                accept={{ 'image/png': [], 'image/jpeg': [], 'image/gif': [] }}
              />
              {hasCoverPicture && (
                <Button
                  size="small"
                  fullWidth
                  onClick={() => form.setValue('coverPicture', null)}
                >
                  {tLokalise('general:delete')}
                </Button>
              )}
            </div>
            <FormTextField
              name="cost"
              label={t('products_form.cost')}
              helperText={t('products_form.cost_helper_text')}
              rules={{ validate: validateMinRule(1) }}
              inputProps={{ maxLength: 255 }}
              type="number"
              margin="normal"
            />
            <Typography sx={{ fontWeight: 500 }}>
              {t('products_form.product_description')}
            </Typography>
            <FormTextField
              name="description"
              label={t('products_form.enter_description')}
              inputProps={{ maxLength: 255 }}
              multiline
              rows={5}
            />
          </CardContent>
          <CardActions sx={{ justifyContent: 'flex-end' }}>
            <Button
              variant="contained"
              onClick={form.handleSubmit(() => mutation.mutate())}
              loading={mutation.isLoading}
              disabled={!isDirty || !isValid || !hasCoverPicture}
            >
              {tLokalise('general:save')}
            </Button>
          </CardActions>
        </Card>
      </Container>
    </FormProvider>
  );
};

export default Product;
