import { useMutation } from '@apollo/client';
import { yupResolver } from '@hookform/resolvers/yup';
import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle';
import Button from '@mui/material/Button';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { styled } from '@mui/material/styles';
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
import * as React from 'react';
import * as yup from 'yup';

import Container from 'components/Container';
import DeleteAccountDialog from 'components/DeleteAccountDialog/index.ee';
import Form from 'components/Form';
import PageTitle from 'components/PageTitle';
import TextField from 'components/TextField';
import { UPDATE_CURRENT_USER } from 'graphql/mutations/update-current-user';
import useCurrentUser from 'hooks/useCurrentUser';
import useFormatMessage from 'hooks/useFormatMessage';
import { useQueryClient } from '@tanstack/react-query';

const validationSchema = yup
  .object({
    fullName: yup.string().required(),
    email: yup.string().email().required(),
    password: yup.string(),
    confirmPassword: yup
      .string()
      .oneOf([yup.ref('password')], 'Passwords must match'),
  })
  .required();

const StyledForm = styled(Form)`
  display: flex;
  align-items: end;
  flex-direction: column;
`;

function ProfileSettings() {
  const [showDeleteAccountConfirmation, setShowDeleteAccountConfirmation] =
    React.useState(false);
  const enqueueSnackbar = useEnqueueSnackbar();
  const { data } = useCurrentUser();
  const currentUser = data?.data;
  const formatMessage = useFormatMessage();
  const [updateCurrentUser] = useMutation(UPDATE_CURRENT_USER);
  const queryClient = useQueryClient();

  const handleProfileSettingsUpdate = async (data) => {
    const { fullName, password, email } = data;
    const mutationInput = {
      fullName,
      email,
    };

    if (password) {
      mutationInput.password = password;
    }

    await updateCurrentUser({
      variables: {
        input: mutationInput,
      },
      optimisticResponse: {
        updateCurrentUser: {
          __typename: 'User',
          id: currentUser.id,
          fullName,
          email,
        },
      },
    });

    await queryClient.invalidateQueries({ queryKey: ['users', 'me'] });

    enqueueSnackbar(formatMessage('profileSettings.updatedProfile'), {
      variant: 'success',
      SnackbarProps: {
        'data-test': 'snackbar-update-profile-settings-success',
      },
    });
  };

  return (
    <Container sx={{ py: 3, display: 'flex', justifyContent: 'center' }}>
      <Grid container item xs={12} sm={9} md={8} lg={6}>
        <Grid item xs={12} sx={{ mb: [2, 5] }}>
          <PageTitle>{formatMessage('profileSettings.title')}</PageTitle>
        </Grid>

        <Grid item xs={12} justifyContent="flex-end">
          <StyledForm
            defaultValues={{
              ...currentUser,
              password: '',
              confirmPassword: '',
            }}
            onSubmit={handleProfileSettingsUpdate}
            resolver={yupResolver(validationSchema)}
            mode="onChange"
            sx={{ mb: 2 }}
            render={({
              formState: {
                errors,
                touchedFields,
                isDirty,
                isValid,
                isSubmitting,
              },
            }) => (
              <>
                <TextField
                  fullWidth
                  name="fullName"
                  label={formatMessage('profileSettings.fullName')}
                  margin="dense"
                  error={touchedFields.fullName && !!errors?.fullName}
                  helperText={errors?.fullName?.message || ' '}
                />

                <TextField
                  fullWidth
                  name="email"
                  label={formatMessage('profileSettings.email')}
                  margin="dense"
                  error={touchedFields.email && !!errors?.email}
                  helperText={errors?.email?.message || ' '}
                />

                <TextField
                  fullWidth
                  name="password"
                  label={formatMessage('profileSettings.newPassword')}
                  margin="dense"
                  type="password"
                  error={touchedFields.password && !!errors?.password}
                  helperText={
                    (touchedFields.password && errors?.password?.message) || ' '
                  }
                />

                <TextField
                  fullWidth
                  name="confirmPassword"
                  label={formatMessage('profileSettings.confirmNewPassword')}
                  margin="dense"
                  type="password"
                  error={
                    touchedFields.confirmPassword && !!errors?.confirmPassword
                  }
                  helperText={
                    (touchedFields.confirmPassword &&
                      errors?.confirmPassword?.message) ||
                    ' '
                  }
                />

                <Button
                  variant="contained"
                  type="submit"
                  disabled={!isDirty || !isValid || isSubmitting}
                >
                  {formatMessage('profileSettings.updateProfile')}
                </Button>
              </>
            )}
          />
        </Grid>

        <Grid item xs={12} justifyContent="flex-end" sx={{ pt: 5 }}>
          <Alert variant="outlined" severity="error" sx={{ fontWeight: 500 }}>
            <AlertTitle sx={{ fontWeight: 700 }}>
              {formatMessage('profileSettings.deleteMyAccount')}
            </AlertTitle>

            <Typography variant="body1" gutterBottom>
              {formatMessage('profileSettings.deleteAccountSubtitle')}
            </Typography>

            <ol>
              <li>{formatMessage('profileSettings.deleteAccountResult1')}</li>
              <li>{formatMessage('profileSettings.deleteAccountResult2')}</li>
              <li>{formatMessage('profileSettings.deleteAccountResult3')}</li>
              <li>{formatMessage('profileSettings.deleteAccountResult4')}</li>
            </ol>

            <Button
              variant="contained"
              type="submit"
              color="error"
              size="small"
              sx={{ justifyContent: 'end' }}
              onClick={() => setShowDeleteAccountConfirmation(true)}
            >
              {formatMessage('profileSettings.deleteAccount')}
            </Button>

            {showDeleteAccountConfirmation && (
              <DeleteAccountDialog
                onClose={() => setShowDeleteAccountConfirmation(false)}
              />
            )}
          </Alert>
        </Grid>
      </Grid>
    </Container>
  );
}
export default ProfileSettings;
