import { Formik } from 'formik';
import { AuthModalState } from './AuthModal';
import { EMAIL_REGEX, getRecaptchaToken } from './helper';
import {
  FieldWrapper,
  FormField,
  FormFieldError,
  FormLabel,
  FormWrapper,
  InteractButton,
  Notice,
  ShowHidePasswordButton,
} from './styles';

import generateQueryString from '@/lib/generateQueryString';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import { useState } from 'react';

const SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL;

const LoginForm = ({
  directToStudio,
  setAuthModalState,
  setEmail,
  onCancel,
}: {
  directToStudio?: boolean;
  setAuthModalState: (state: AuthModalState) => void;
  setEmail: (state: string) => void;
  onCancel: () => void;
}) => {
  const router = useRouter();
  interface Values {
    email: string;
    password: string;
  }

  const [message, setMessage] = useState<string | null>(null);
  const [showPassword, setShowPassword] = useState(false);
  const { mutate, isLoading, isError, isSuccess } = useMutation(async (values: Values) => {
    const { email, password } = values;
    const token = await getRecaptchaToken('login');

    const loginResponse = await fetch(`${SERVER_URL}/auth/email/login${generateQueryString(router.query)}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ email, password, token }),
      credentials: 'include',
    });
    // Convert response to text
    const contents = await loginResponse.text();

    if (loginResponse.status === 200) {
      const body = JSON.parse(contents);
      const { redirected, url } = body;
      if (redirected && url) window.location.href = url;
    } else if (loginResponse.status === 403) {
      setAuthModalState('usernotverified');
      setEmail(email);
      setMessage('User not verified');
      throw new Error('');
    } else if (loginResponse.status === 500) {
      setMessage('Something went wrong');
      throw new Error('');
    } else {
      setMessage('Email or password incorrect');
      throw new Error('');
    }
  });

  const validate = (values: Values) => {
    const errors: Partial<Values> = {};
    if (!values.email) {
      errors.email = 'Required';
    } else if (!EMAIL_REGEX.test(values.email)) {
      errors.email = 'Invalid email address';
    }
    if (!values.password) {
      errors.password = 'Required';
    }
    return errors;
  };

  let buttonText = 'Log in';
  if (isLoading) buttonText = 'Loading...';
  if (isSuccess) buttonText = 'Success!';
  if (message === 'User not verified') buttonText = 'Error!';
  return (
    <Formik
      initialValues={{
        email: '',
        password: '',
      }}
      validateOnBlur={false}
      validate={validate}
      onSubmit={(values) => mutate(values)}
    >
      {({ errors, values }) => (
        <FormWrapper>
          <FieldWrapper>
            <div className="labelWrapper">
              <FormLabel htmlFor="email">Email</FormLabel>
              <FormFieldError name="email" component="div" />
            </div>
            <FormField disabled={isSuccess || isLoading} id="email" name="email" placeholder="email" type="text" />
          </FieldWrapper>
          <FieldWrapper>
            <div className="labelWrapper">
              <FormLabel htmlFor="password">Password</FormLabel>
              <FormFieldError name="password" component="div" />
            </div>
            <div style={{ position: 'relative' }}>
              <FormField
                disabled={isSuccess || isLoading}
                id="password"
                name="password"
                placeholder="password"
                type={showPassword ? 'text' : 'password'}
              />
              <ShowHidePasswordButton
                tabIndex={-1}
                type="button"
                onClick={() => {
                  setShowPassword(!showPassword);
                }}
              >
                {showPassword ? 'HIDE' : 'SHOW'}
              </ShowHidePasswordButton>
            </div>
          </FieldWrapper>
          <div
            style={{
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'center',
              marginTop: '1em',
              gap: '10px',
            }}
          >
            <InteractButton
              type="submit"
              disabled={isSuccess || isLoading}
              style={{
                marginTop: 0,
                marginBottom: '0.5rem',
                backgroundColor: !values.email || errors.email || errors.password ? 'white' : '',
                borderColor: !values.email || errors.email || errors.password ? 'black' : '',
              }}
            >
              {buttonText}
            </InteractButton>
            <InteractButton
              type="button"
              disabled={isSuccess || isLoading}
              style={{ marginTop: 0, marginBottom: '0.5rem' }}
              cancel={true}
              onClick={onCancel}
            >
              Cancel
            </InteractButton>
          </div>
          {message && !isLoading && <Notice className="flash">{message}</Notice>}
        </FormWrapper>
      )}
    </Formik>
  );
};

export default LoginForm;
