import { Done } from '@mui/icons-material';
import {
  Button,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Grid,
  TextField,
  Typography,
  useMediaQuery,
  useTheme,
} from '@mui/material';
import { useForm } from '@tanstack/react-form';
import { useMutation } from '@tanstack/react-query';
import { FC, FormEvent, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useApi } from '../../../api/Api';
import { UserCreate } from '../../../types/User';
import ErrorComponent from '../../Error/ErrorComponent';

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

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

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

  const createMutation = useMutation({
    mutationFn: ({ data }: { data: UserCreate }) => {
      return Api.createUser(data);
    },
  });

  const form = useForm<UserCreate>({
    defaultValues: {
      username: '',
      email: '',
      password: '',
    },
    onSubmit: async ({ value }) => {
      try {
        createMutation.mutate(
          { data: value },
          {
            onSuccess: () => setError(undefined),
            onError: setError,
          }
        );
        //eslint-disable-next-line @typescript-eslint/no-explicit-any
      } catch (_error: any) {
        setError(_error);
      }
    },
  });

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

  if (createMutation.isSuccess)
    return (
      <Dialog open={open} onClose={handleClose} fullWidth fullScreen={fullScreen}>
        <DialogContent>
          <Grid container spacing={2}>
            <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'center' }}>
              <Done color="action" sx={{ fontSize: '200px' }} />
            </Grid>
            <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'center' }}>
              <Typography variant="h5">{t('Confirm header')}</Typography>
            </Grid>
            <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'center' }}>
              <Typography>{t('Confirm mail')}</Typography>
            </Grid>
          </Grid>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose}>{t('Close')}</Button>
        </DialogActions>
      </Dialog>
    );

  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('Register')}</DialogTitle>
      <DialogContent sx={{ gap: 2 }}>
        <Grid container spacing={2}>
          <Grid item xs={12}>
            <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
                      variant="outlined"
                      name={field.name}
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={(e) => field.handleChange(e.target.value)}
                      size="small"
                      label={t('Username')}
                      required
                      error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
                      helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
                      autoComplete="new-username"
                      fullWidth
                      margin="dense"
                    />
                  </>
                );
              }}
            />
          </Grid>
          <Grid item xs={12}>
            <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
                      variant="outlined"
                      name={field.name}
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={(e) => field.handleChange(e.target.value)}
                      size="small"
                      label={t('Email')}
                      required
                      error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
                      helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
                      type="email"
                      autoComplete="new-email"
                      inputMode="email"
                      fullWidth
                    />
                  </>
                );
              }}
            />
          </Grid>
          <Grid item xs={12}>
            <form.Field
              name="password"
              validators={{
                onChange: ({ value }) => (!value ? t('Password required') : undefined),
                onChangeAsyncDebounceMs: 250,
                onChangeAsync: async ({ value }) => {
                  return !value && t('Password required');
                },
              }}
              children={(field) => {
                return (
                  <>
                    <TextField
                      variant="outlined"
                      name={field.name}
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={(e) => field.handleChange(e.target.value)}
                      size="small"
                      label={t('Password')}
                      required
                      error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
                      helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
                      type="password"
                      autoComplete="new-password"
                      fullWidth
                    />
                  </>
                );
              }}
            />
          </Grid>
          <Grid item xs={12}>
            <form.Subscribe
              selector={(state) => [state.canSubmit, state.isSubmitting]}
              children={([canSubmit]) => (
                <>
                  <Button
                    type="submit"
                    disabled={!canSubmit || createMutation.isPending}
                    variant="contained"
                    endIcon={createMutation.isPending && <CircularProgress color="inherit" size="20px" />}
                  >
                    {t('Register')}
                  </Button>
                </>
              )}
            />
          </Grid>
          <Grid item xs={12}>
            {error && <ErrorComponent error={error} context="register" />}
          </Grid>
        </Grid>
      </DialogContent>
    </Dialog>
  );
};

export default RegisterDialog;
