import { LoadingButton } from '@mui/lab';
import {
  Box,
  IconButton,
  InputLabel,
  TextField,
  Typography,
} from '@mui/material';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { useStyles } from './resetPasswordStyles';
import { useRef, useState } from 'react';
import PasswordValidation from '../Login/component/PasswordValidation';
import { VisibilityOffOutlined, VisibilityOutlined } from '@mui/icons-material';
import useQuery from '../../hooks/useQuery';
import {
  passwordLengthRegex,
  passwordLetterRegex,
  passwordNumberRegex,
  passwordSpacesRegex,
} from '../../utils/regex';
import { pushNotification } from '../../utils/notification';
import { NOTIFICATION } from '../../constants';
import { resetPassword } from '../../services/auth.services';

const validationSchema = Yup.object().shape({
  password: Yup.string()
    .matches(passwordLengthRegex, 'Password must be at least 8 characters')
    .matches(passwordLetterRegex, 'Password must contain at least one letter')
    .matches(passwordNumberRegex, 'Password must contain at least one number')
    .matches(passwordSpacesRegex, 'Password must not start or end with a space')
    .required('Password is required'),
  confirmPassword: Yup.string()
    .oneOf([Yup.ref('password'), null], 'Passwords must match')
    .required('Passwords must match'),
});

function ResetPasswordForm({ onSubmit }) {
  const query = useQuery();
  const classes = useStyles();
  const [showPassword, setShowPassword] = useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);

  const fieldRefs = {
    password: useRef(null),
    confirmPassword: useRef(null),
  };

  const formik = useFormik({
    initialValues: { password: '', confirmPassword: '' },
    validationSchema,
    onSubmit: (values) => handleSubmit(values, formik),
  });

  const handleSubmit = async (values, formik) => {
    try {
      values.token = query.get('token');

      const requestBody = {
        token: values.token,
        password: values.password,
      };

      const response = await resetPassword(requestBody);
      if (response.status === 200) {
        pushNotification(response?.data?.message, NOTIFICATION.SUCCESS);
      }
      onSubmit();
    } catch (error) {
      return;
    } finally {
      formik.setSubmitting(false);
      formik.resetForm();
    }
  };
  const handleTogglePasswordVisibility = (field) => {
    if (field === 'password') {
      setShowPassword((prevShowPassword) => !prevShowPassword);
    } else if (field === 'confirmPassword') {
      setShowConfirmPassword(
        (prevShowConfirmPassword) => !prevShowConfirmPassword
      );
    }
  };

  const handleSubmitClick = async (e) => {
    e.preventDefault();
    const formikErrors = await formik.validateForm();
    const errors = Object.keys(formikErrors);

    if (errors.length) {
      // Find the first invalid field and focus it
      const firstErrorField = errors[0];
      const firstErrorRef = fieldRefs[firstErrorField]?.current;

      if (firstErrorRef) {
        // Scroll to the first invalid field smoothly
        if (typeof firstErrorRef?.scrollIntoView === 'function') {
          firstErrorRef?.scrollIntoView({
            behavior: 'smooth',
            block: 'center',
          });
        }

        // Focus the field after a slight delay (to ensure scrolling completes first)
        setTimeout(() => firstErrorRef.focus(), 300);
      }

      // Show error notification
      if (formik?.touched[firstErrorField])
        pushNotification(formikErrors[firstErrorField], NOTIFICATION.ERROR);
    }

    formik.handleSubmit();
  };

  return (
    <Box className={classes.right}>
      <form onSubmit={handleSubmitClick} className={classes.form}>
        <Box className={classes.formBody}>
          <Box className={classes.formHeader}>
            <Typography className={classes.subHeading}>
              Note: Password must be at least 8 characters, contain 1 letter and
              1 number, with no spaces at the beginning/end.
            </Typography>
          </Box>
          <InputLabel
            shrink={false}
            htmlFor={'password'}
            className={classes.labelStyle}
          >
            <Typography className={classes.inputTitle}>
              Enter New Password
            </Typography>
          </InputLabel>
          <TextField
            color="secondary"
            placeholder="Enter Password"
            variant="outlined"
            margin="normal"
            fullWidth
            type={showPassword ? 'text' : 'password'}
            name="password"
            value={formik.values.password}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            inputRef={fieldRefs.password}
            error={Boolean(formik.errors.password && formik.touched.password)}
            helperText={
              formik.errors.password && formik.touched.password
                ? formik.errors.password
                : ''
            }
            InputProps={{
              endAdornment: (
                <IconButton
                  onClick={() => handleTogglePasswordVisibility('password')}
                  edge="end"
                >
                  {!showPassword ? (
                    <VisibilityOffOutlined />
                  ) : (
                    <VisibilityOutlined />
                  )}
                </IconButton>
              ),
            }}
          />
          {/* Password validation display */}
          {!formik.isValid && (
            <>
              <Typography className={classes.passwordCheckListTitle}>
                Note: Password must be
              </Typography>
              <Box className={classes.passwordCheckList}>
                <PasswordValidation
                  isValid={passwordLengthRegex.test(formik.values.password)}
                  text="at least 6 characters"
                />
                <PasswordValidation
                  isValid={passwordLetterRegex.test(formik.values.password)}
                  text="at least 1 letter"
                />
                <PasswordValidation
                  isValid={passwordNumberRegex.test(formik.values.password)}
                  text="at least 1 number"
                />
                <PasswordValidation
                  isValid={passwordSpacesRegex.test(formik.values.password)}
                  text="with no spaces at the beginning/end"
                />
              </Box>
            </>
          )}
        </Box>
        <Box className={classes.confirmResetBox}>
          <InputLabel
            shrink={false}
            htmlFor={'confirmPassword'}
            className={classes.labelStyle}
          >
            <Typography className={classes.inputTitle}>
              Confirm New Password
            </Typography>
          </InputLabel>
          <TextField
            className={classes.resetPasswordTextField}
            color="secondary"
            placeholder="Confirm Password"
            variant="outlined"
            margin="normal"
            fullWidth
            type={showConfirmPassword ? 'text' : 'password'}
            name="confirmPassword"
            value={formik.values.confirmPassword}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            inputRef={fieldRefs.confirmPassword}
            error={Boolean(
              formik.errors.confirmPassword && formik.touched.confirmPassword
            )}
            helperText={
              formik.errors.confirmPassword && formik.touched.confirmPassword
                ? formik.errors.confirmPassword
                : ''
            }
            InputProps={{
              endAdornment: (
                <IconButton
                  onClick={() =>
                    handleTogglePasswordVisibility('confirmPassword')
                  }
                  edge="end"
                >
                  {!showConfirmPassword ? (
                    <VisibilityOffOutlined />
                  ) : (
                    <VisibilityOutlined />
                  )}
                </IconButton>
              ),
            }}
          />
        </Box>
        <LoadingButton
          size="large"
          type="submit"
          variant="contained"
          className={classes.submitButton}
          loading={formik.isSubmitting}
        >
          Save New Password
        </LoadingButton>
      </form>
    </Box>
  );
}

export default ResetPasswordForm;
