import { gray100 } from '@/styles/colors';
import { Formik } from 'formik'; // Import the Form component
import { useEffect, useState } from 'react';
import Modal, { ModalProps } from '../Modal';
import { EMAIL_REGEX, checkPassword, removeQueryParams } from './helper';
import {
  AuthButton,
  FieldWrapper,
  FormField,
  FormFieldError,
  FormLabel,
  FormWrapper,
  Header,
  ModalBodyParagraph,
  Notice,
} from './styles';

import { useMutation } from '@tanstack/react-query';
import { AuthModalState } from './AuthModal';

const SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL;

type PasswordResetModalProps = Omit<ModalProps, 'children'> & {
  changePasswordCode: string;
  setAuthModalState: (state: AuthModalState) => void;
};

const PasswordResetModal = (props: PasswordResetModalProps) => {
  const [changePasswordId, setChangePasswordId] = useState('');
  const [email, setEmail] = useState('');
  const [valid, setValid] = useState(false);

  const { changePasswordCode, setAuthModalState, onClose } = props;

  interface Values {
    newPassword: string;
  }

  const validate = (values: Values) => {
    const errors: Partial<Values> = {};
    if (!values.newPassword) {
      errors.newPassword = 'Required';
    }
    const error = checkPassword(values.newPassword);
    if (error) {
      errors.newPassword = error;
    }
    return errors;
  };

  useEffect(() => {
    if (!changePasswordCode) return;
    // Base64 decode the changePasswordCode
    try {
      // This would have been generated by the /auth/email/forgot endpoint
      const { c, e } = JSON.parse(atob(changePasswordCode as string));
      if (!c || !e) throw new Error('Invalid reset link');
      if (!EMAIL_REGEX.test(e)) throw new Error('Invalid email address');
      setChangePasswordId(c);
      setEmail(e);
      setValid(true);
    } catch (err) {
      setValid(false);
    }
  }, [changePasswordCode]);

  const { mutate, isLoading, isError, isSuccess } = useMutation(
    async (values: Values) => {
      const { newPassword } = values;
      const response = await fetch(`${SERVER_URL}/auth/email/reset-password`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email, password: newPassword, changePasswordId }),
      });
      if (response.status !== 200) {
        throw new Error();
      }
    },
    {
      onSuccess: () => {
        removeQueryParams();
      },
      onError: () => {
        removeQueryParams();
      },
    }
  );

  return (
    <Modal
      style={{
        borderRadius: 4,
        backgroundColor: 'white',
        color: gray100,
      }}
      hideCloseButton
      {...props}
    >
      <Header>Reset password</Header>

      {valid ? (
        <Formik
          initialValues={{
            newPassword: '',
          }}
          validateOnBlur={false}
          validate={validate}
          onSubmit={(values) => mutate(values)}
        >
          {({ isSubmitting }) => (
            <FormWrapper>
              <div style={{ display: 'flex', flexDirection: 'column' }}>
                <ModalBodyParagraph
                  style={{
                    lineHeight: '2.5rem',
                    marginBottom: '2rem',
                  }}
                >
                  Changing password for:
                  <br />
                  <strong>{email}</strong>
                </ModalBodyParagraph>
                <FieldWrapper>
                  <div className="labelWrapper">
                    <FormLabel htmlFor="newPassword">New Password</FormLabel>
                    <FormFieldError name="newPassword" component="div" />
                  </div>
                  <FormField id="newPassword" name="newPassword" placeholder="" type="password" />
                </FieldWrapper>
                {!isSuccess && !isError && (
                  <AuthButton type="submit" disabled={isSubmitting} style={{ marginTop: 0, marginBottom: '0.5rem' }}>
                    {isLoading ? (
                      <>Loading...</>
                    ) : isSuccess ? (
                      <>
                        Password Reset <span style={{ fontSize: '1.5rem' }}>✅</span>
                      </>
                    ) : (
                      <>Set New Password</>
                    )}
                  </AuthButton>
                )}
                {isSuccess && (
                  <>
                    <Notice className="flash">
                      Your password has been reset.
                      <br />
                      Please login with your new password.
                    </Notice>
                    <AuthButton
                      onClick={() => {
                        setAuthModalState('login');
                        onClose();
                      }}
                    >
                      Login
                    </AuthButton>
                  </>
                )}
                {isError && (
                  <>
                    <Notice className="flash">
                      Token invalid or expired
                      <br />
                      Please request a new password reset link
                    </Notice>
                    <AuthButton
                      onClick={() => {
                        setAuthModalState('forgot');
                        onClose();
                      }}
                    >
                      Request new password reset link
                    </AuthButton>
                  </>
                )}
              </div>
            </FormWrapper>
          )}
        </Formik>
      ) : (
        <p>Invalid reset link</p>
      )}
    </Modal>
  );
};

export default PasswordResetModal;
