import { CloudUpload, Delete, Person } from '@mui/icons-material';
import {
  Avatar,
  Box,
  Button,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  FormControl,
  Grid,
  IconButton,
  InputLabel,
  MenuItem,
  Select,
  TextField,
  Typography,
  useMediaQuery,
  useTheme,
} from '@mui/material';
import { useForm } from '@tanstack/react-form';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { t } from 'i18next';
import { FC, FormEvent, useEffect, useState } from 'react';
import { useApi } from '../../../api/Api';
import { User, UserImageUpdate } from '../../../types/User';
import ErrorComponent from '../../Error/ErrorComponent';

interface Props {
  user: User;
  open: boolean;
  onClose: () => void;
}

const UserImageDialog: FC<Props> = ({ user, open, onClose }) => {
  //eslint-disable-next-line @typescript-eslint/no-explicit-any
  const [error, setError] = useState<any>();

  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.only('xs'), { noSsr: true });
  const queryClient = useQueryClient();
  const Api = useApi();

  const updateMutation = useMutation({
    mutationFn: ({ data, id }: { data: UserImageUpdate; id?: number }) => Api.updateUserImage(data, id),
  });

  const form = useForm<UserImageUpdate>({
    onSubmit: async ({ value }) => {
      try {
        updateMutation.mutate(
          { data: value, id: Api.authenticatedUser?.id === user.id ? undefined : user.id },
          {
            onSuccess: () => {
              handleClose();

              const queryKey = Api.authenticatedUser?.id === user.id ? ['profile'] : ['profile', { id: user.id }];
              queryClient.invalidateQueries({ queryKey });
            },
            onError: setError,
          }
        );
        //eslint-disable-next-line @typescript-eslint/no-explicit-any
      } catch (_error: any) {
        setError(_error);
      }
    },
  });

  const formState = form.useStore((state) => ({ image: state.values.image, predefined: state.values.predefined }));

  const handleClose = () => {
    form.reset();
    setError(undefined);
    onClose();
  };

  useEffect(() => {
    if (!Api.hasAuth) handleClose();
  }, [Api.hasAuth]); //eslint-disable-line react-hooks/exhaustive-deps

  return (
    <Dialog
      open={open}
      onClose={handleClose}
      fullWidth
      fullScreen={fullScreen}
      PaperProps={{
        component: 'form',
        encType: 'multipart/form-data',
        onSubmit: (e: FormEvent<HTMLFormElement>) => {
          e.preventDefault();
          e.stopPropagation();
          form.handleSubmit();
        },
        onKeyDown: (event: React.KeyboardEvent<HTMLFormElement>) => {
          if (event.key === 'Tab') {
            event.stopPropagation();
          }
        },
        noValidate: true,
      }}
    >
      <DialogTitle>{t('Edit image')}</DialogTitle>
      <DialogContent sx={{ gap: 2 }}>
        <Grid container spacing={2}>
          <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'center' }}>
            <Avatar
              alt={user.username}
              src={
                formState.image
                  ? URL.createObjectURL(formState.image)
                  : formState.predefined
                    ? `storage/profilbilder/default/${formState.predefined}.svg`
                    : `${user.image}`
              }
              sx={{ width: '100px', height: '100px' }}
            >
              <Person sx={{ width: '60px', height: '60px' }} />
            </Avatar>
          </Grid>
          <Grid item xs={12}>
            <Box sx={{ display: 'flex', gap: 2 }}>
              <Button
                component="label"
                role={undefined}
                variant="contained"
                tabIndex={-1}
                startIcon={<CloudUpload />}
                fullWidth
              >
                <form.Field
                  name="image"
                  children={(field) => (
                    <>
                      <Box sx={{ textOverflow: 'ellipsis', textWrap: 'nowrap', overflow: 'hidden' }}>
                        {!field.state.value ? t('Upload image') : t('Upload named', { name: field.state.value?.name })}
                      </Box>
                      <TextField
                        name={field.name}
                        onBlur={field.handleBlur}
                        value={!field.state.value ? '' : undefined}
                        //eslint-disable-next-line @typescript-eslint/no-explicit-any
                        onChange={(e) => field.handleChange((e.target as any).files[0])}
                        size="small"
                        type="file"
                        required
                        sx={{ display: 'none' }}
                        autoComplete="off"
                      />
                    </>
                  )}
                />
              </Button>
              <IconButton color="error" onClick={() => form.setFieldValue('image', undefined)}>
                <Delete />
              </IconButton>
            </Box>
          </Grid>
          <Grid item xs={12}>
            <Divider variant="middle">
              <Typography sx={{ opacity: 0.36 }}>{t('or')}</Typography>
            </Divider>
          </Grid>
          <Grid item xs={12}>
            <form.Field
              name="predefined"
              children={(field) => (
                <FormControl fullWidth>
                  <InputLabel size="small">{t('Predefined')}</InputLabel>
                  <Select
                    name={field.name}
                    value={field.state.value ?? ''}
                    onBlur={field.handleBlur}
                    onChange={(e) => field.handleChange(e.target.value)}
                    size="small"
                    label={t('Predefined')}
                    autoComplete="off"
                    fullWidth
                    //renderValue={(selected) => selected ?? 'Keine Auswahl'}
                  >
                    <MenuItem value="" selected>
                      Keine Auswahl
                    </MenuItem>
                    {[...Array(10).keys()].map((i) => (
                      <MenuItem key={`avatar-${i + 1}`} value={`avatar-${i + 1}`}>
                        {t('Avatar', { name: i + 1 })}
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>
              )}
            />
          </Grid>
        </Grid>
      </DialogContent>
      <DialogActions>
        <form.Subscribe
          selector={(state) => [state.canSubmit, state.isSubmitting]}
          children={([canSubmit]) => (
            <>
              <Button
                variant="outlined"
                onClick={() => {
                  handleClose();
                }}
              >
                {t('Cancel')}
              </Button>
              <Button
                type="submit"
                disabled={!canSubmit || updateMutation.isPending}
                autoFocus
                variant="contained"
                endIcon={updateMutation.isPending && <CircularProgress color="inherit" size="20px" />}
              >
                {t('Save')}
              </Button>
            </>
          )}
        />
      </DialogActions>
      {error && (
        <DialogContent>
          <ErrorComponent error={error} context="userUpdate" />
        </DialogContent>
      )}
    </Dialog>
  );
};

export default UserImageDialog;
