import {
  Button,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  TextField,
  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, useState } from 'react';
import Api from '../../../api/Api';
import { User, UserUpdate } from '../../../types/User';
import ErrorComponent from '../../Error/ErrorComponent';

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

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

  const updateMutation = useMutation({
    mutationFn: ({ data, id }: { data: UserUpdate; id?: number }) => {
      return Api.updateUser(data, id);
    },
  });

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

              const queryKey = Api.getAuthenticatedUser()?.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 theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.only('xs'), { noSsr: true });
  const queryClient = useQueryClient();

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

  return (
    <Dialog
      open={open}
      onClose={handleClose}
      fullWidth
      fullScreen={fullScreen}
      PaperProps={{
        component: 'form',
        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 data')}</DialogTitle>
      <DialogContent>
        <form.Field
          name="username"
          validators={{
            onChange: ({ value }) => (!value ? t('Username required') : undefined),
            onChangeAsyncDebounceMs: 250,
            onChangeAsync: async ({ value }) => {
              return !value && t('Username required');
            },
          }}
          children={(field) => {
            return (
              <>
                <TextField
                  name={field.name}
                  value={field.state.value}
                  onBlur={field.handleBlur}
                  onChange={(e) => field.handleChange(e.target.value)}
                  size="small"
                  label={t('Username')}
                  required
                  margin="dense"
                  autoComplete="new-username"
                  fullWidth
                  error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
                  helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
                />
              </>
            );
          }}
        />
        <form.Field
          name="email"
          validators={{
            onChange: ({ value }) => (!value ? t('Email required') : undefined),
            onChangeAsyncDebounceMs: 250,
            onChangeAsync: async ({ value }) => {
              return !value && t('Email required');
            },
          }}
          children={(field) => {
            return (
              <>
                <TextField
                  name={field.name}
                  value={field.state.value}
                  onBlur={field.handleBlur}
                  onChange={(e) => field.handleChange(e.target.value)}
                  size="small"
                  label={t('Email')}
                  required
                  margin="dense"
                  autoComplete="new-username"
                  fullWidth
                  error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
                  helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
                />
              </>
            );
          }}
        />
      </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 UserEditDialog;
