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

/**
 * The fields that are used in the sign up form
 */
export interface ISignUpFields {
  email: string;
  password: string;
  confirmPassword: string;
}
export type SignUpFormType = FormModel;

export interface SignUpFormProps {
  /**
   * A function that is called when the form is submitted
   * @param formData
   * @returns void
   */
  onSubmit: (formData: ISignUpFields) => 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 up form
   */
  reason?: string;
  /**
   * content to be displayed below the form and above the submit button
   */
  children?: React.ReactNode;
}
export const SignUpForm: React.FC<SignUpFormProps> = observer(
  ({ onSubmit, errorMessage }) => {
    const isConfirmedPasswordValid = (value?: string) => {
      // here we do the validation for the 'confirmPassword' field
      // if the confirm password is the same as the password
      // we return true, otherwise false
      // true means the field is valid and the passwords match
      return value === signUpForm.getValue('password');
    };

    const isEmailValid = (email?: string) => {
      if (email !== undefined) {
        return isValidEmail(email);
      }
      return true;
    };
    const signUpForm: SignUpFormType = new FormModel({
      id: 'SignUp',
      title: 'Sign Up',
      fields: [
        {
          id: 'email',
          value: '',
          type: 'text',
          input: {
            required: true,
            label: 'Email'
          }
        },
        {
          id: 'password',
          value: '',
          type: 'password',
          input: {
            required: true,
            label: 'Password'
          }
        },
        {
          id: 'confirmPassword',
          value: '',
          type: 'password',
          validation: isConfirmedPasswordValid,
          input: {
            required: true,
            label: 'Confirm 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 confirmPasswordErrorField = signUpForm.getValue('confirmPassword');
      const emailField = signUpForm.getValue('email');
      const isConfirmPasswordError =
        isConfirmedPasswordValid(confirmPasswordErrorField) === false;
      const showConfirmPasswordError =
        isConfirmPasswordError && confirmPasswordErrorField !== '';
      const inputErrorStyle = {
        input: {
          borderColor: theme.colors.error
        }
      };
      const hasEmailFieldError =
        isEmailValid(emailField) === false && emailField !== '';

      return (
        <Form
          title={signUpForm.title}
          onSubmit={(formData) => console.log(formData)}
        >
          <Input
            id="email"
            label="Email"
            onChange={(value) => {
              signUpForm.setValue('email', value);
            }}
            placeholder="email"
            required
            styleOverwrites={hasEmailFieldError ? inputErrorStyle : {}}
          />
          {hasEmailFieldError && (
            <Text styleOverwrites={{ color: theme.colors.error }}>
              Email address not valid
            </Text>
          )}

          <Input
            id="password"
            label="Password"
            password
            onChange={(value) => {
              signUpForm.setValue('password', value);
            }}
            required
            styleOverwrites={showConfirmPasswordError ? inputErrorStyle : {}}
          />

          <Input
            id="confirmPassword"
            label="Confirm Password"
            password
            onChange={(value) => {
              signUpForm.setValue('confirmPassword', value);
            }}
            required
            styleOverwrites={showConfirmPasswordError ? inputErrorStyle : {}}
          />
          {showConfirmPasswordError && (
            <Text styleOverwrites={{ color: theme.colors.error }}>
              Passwords do not match
            </Text>
          )}

          {errorMessage && <ErrorMessage errorMessage={errorMessage} />}
          <Button
            onClick={() => {
              onSubmit({
                email: signUpForm.getValue('email') || '',
                password: signUpForm.getValue('password') || '',
                confirmPassword: signUpForm.getValue('confirmPassword') || ''
              });
            }}
            disabled={!signUpForm.valid}
            styleOverwrites={{
              display: 'flex',
              justifyContent: 'center'
            }}
          >
            <Text
              styleOverwrites={{
                textAlign: 'center',
                color: theme.styles.button.primary.color,
                fontWeight: 'bold'
              }}
            >
              Sign Up!
            </Text>
          </Button>
        </Form>
      );
    });

    return <FormComponent />;
  }
);
