import { observer } from 'mobx-react';
import { FormV2 as FormModel } from '../../models/Form/FormV2';
import { useApphouse } from '../../context/useApphouse';
import { Text } from '../Text';
import { Input } from '../input/Input';
import React, { useEffect } from 'react';
import { Button } from '../Button';
import { Form } from './Form';
import { isValidEmail } from '../../utils/string/isValidEmail';
import { ErrorMessage } from './ErrorMessage';

export interface ISignInFields {
  // declare the fields here
  // and their types
  email: string;
  password: string;
}
export type SignInFormType = FormModel;

export interface SignInFormProps {
  /**
   * A function that is called when the form is submitted
   * @param formData
   * @returns void
   */
  onSubmit: (formData: ISignInFields) => void;
  /**
   * An error message to be displayed if the form has an error
   * on submission
   */
  errorMessage?: React.ReactNode;
  /**
   * A reason to be prompted the sign in form
   */
  reason?: string;
  /**
   * content to be displayed below the form and above the submit button
   */
  children?: React.ReactNode;
}
export const SignInForm: React.FC<SignInFormProps> = observer(
  ({ onSubmit, children, errorMessage }) => {
    const firstInputRef = React.useRef<HTMLInputElement>(null);
    const isEmailValid = (email?: string) => {
      if (email !== undefined) {
        return isValidEmail(email);
      }
      return true;
    };
    const SignInForm: SignInFormType = new FormModel({
      id: 'SignIn',
      title: 'Sign In',
      fields: [
        {
          id: 'email',
          value: '',
          type: 'text',
          input: {
            required: true,
            label: 'Email'
          }
        },
        {
          id: 'password',
          value: '',
          type: 'password',
          input: {
            required: true,
            label: 'Password'
          }
        }
      ]
    });
    // Note: we use the observer from mobx-react to make sure the component
    // is re-rendered when the form is updated.
    // Ensure to use the observer on the component that uses the form.
    const FormComponent = observer(() => {
      const { theme } = useApphouse();

      const emailField = SignInForm.getValue('email');

      const inputErrorStyle = {
        input: {
          borderColor: theme.colors.error
        }
      };
      const hasEmailFieldError =
        isEmailValid(emailField) === false && emailField !== '';

      useEffect(() => {
        if (firstInputRef.current) {
          firstInputRef.current.focus();
        }
      });

      const emailErrorMessage = hasEmailFieldError
        ? 'Email address not valid'
        : undefined;
      return (
        <Form
          title={SignInForm.title}
          onSubmit={(e) => {
            e.preventDefault();
            e.stopPropagation();
          }}
        >
          <Input
            id="email"
            label="Email"
            onChange={(value) => {
              SignInForm.setValue('email', value);
            }}
            placeholder="email"
            required
            styleOverwrites={hasEmailFieldError ? inputErrorStyle : {}}
            error={emailErrorMessage}
          />

          <Input
            id="password"
            label="Password"
            password
            onChange={(value) => {
              SignInForm.setValue('password', value);
            }}
            required
          />
          {errorMessage && <ErrorMessage errorMessage={errorMessage} />}
          <Button
            onClick={() => {
              onSubmit({
                email: SignInForm.getValue('email') || '',
                password: SignInForm.getValue('password') || ''
              });
            }}
            disabled={!SignInForm.valid}
            styleOverwrites={{
              display: 'flex',
              justifyContent: 'center'
            }}
          >
            <Text
              styleOverwrites={{
                textAlign: 'center',
                color: theme.styles.button.primary.color,
                fontWeight: 'bold'
              }}
            >
              Sign in
            </Text>
          </Button>
          {children && children}
        </Form>
      );
    });

    return <FormComponent />;
  }
);
