import './style.css'

import { Box, CircularProgress, Modal } from '@mui/material'
import axios, { AxiosError } from 'axios'
import { Field, Form, Formik } from 'formik'
import _identity from 'lodash/identity'
import React, { FC, useState } from 'react'
import * as Yup from 'yup'

import { register } from '../../api'
import { CONFIGS } from '../../utils'
import { CustomField } from '../common/CustomField'
import { PoweredBy } from '../common/PoweredBy'

interface ISignupProps {
  onClose: () => void;
  onLogin: () => void;
  onRegisterSuccess: (res: any) => void;
  onRegisterError: (e: AxiosError, email: string) => void;
  showPoweredByImage?: boolean;
}

interface ValuesTypes {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  confirmPassword: string;
}

const style: React.CSSProperties = {
  position: 'absolute',
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  minWidth: 480,
  backgroundColor: '#fff',
  border: '1px solid white',
  outline: 'none',
  padding: '14px',
}

const SignupSchema = Yup.object().shape({
  firstName: Yup.string().required('Required'),
  lastName: Yup.string().required('Required'),
  email: Yup.string().email('Invalid email').required('Required'),
  password: Yup.string()
    .min(8, 'Password must have 8+ characters')
    .required('Required')
    .matches(
      new RegExp('^(?=.*[@$!%*#?&])'),
      'Password must contain at least one special character'
    ),
  confirmPassword: Yup.string()
    .required('Required')
    .oneOf([Yup.ref('password'), null], 'Passwords must match'),
})

export const SignupModal: FC<ISignupProps> = ({
  onClose = _identity,
  onLogin = _identity,
  onRegisterSuccess = _identity,
  onRegisterError = _identity,
  showPoweredByImage = false,
}) => {
  const [loading, setLoading] = useState(false)

  const onSignup = async (values: ValuesTypes) => {
    try {
      setLoading(true)
      const formData = new FormData()
      formData.set('first_name', values.firstName)
      formData.set('last_name', values.lastName)
      formData.set('email', values.email)
      formData.set('password', values.password)
      formData.set('password_confirmation', values.confirmPassword)
      formData.append(
        'client_id',
        CONFIGS.CLIENT_ID || 'e9d8f8922797b4621e562255afe90dbf'
      )
      formData.append(
        'client_secret',
        CONFIGS.CLIENT_SECRET || 'b89c191eff22fdcf84ac9bfd88d005355a151ec2c83b26b9'
      )

      const res = await register(formData)

      onRegisterSuccess(res)
      onClose()
    } catch (e) {
      if (axios.isAxiosError(e)) {
        onRegisterError(e, values.email)
      }
    } finally {
      setLoading(false)
    }
  }

  const _onClose = loading ? _identity : onClose

  return (
    <Modal
      open={true}
      onClose={_onClose}
      aria-labelledby="modal-modal-title"
      aria-describedby="modal-modal-description"
      className="signup-modal"
    >
      <Box style={style}>
        <div>
          <Formik
            initialValues={{
              firstName: '',
              lastName: '',
              email: '',
              password: '',
              confirmPassword: '',
            }}
            validationSchema={SignupSchema}
            onSubmit={onSignup}
          >
            {({ isValid, dirty, handleSubmit }) => (
              <Form onSubmit={handleSubmit}>
                <div className="signup-container">
                  <div className="title">Create an Account</div>
                  <div className="signup-container__twoFields">
                    <div className="is-half">
                      <Field
                        name="firstName"
                        label="First Name"
                        component={CustomField}
                      />
                    </div>
                    <div className="is-half">
                      <Field name="lastName" label="Last Name" component={CustomField} />
                    </div>
                  </div>
                  <div className="signup-container__singleField">
                    <div className="">
                      <Field name="email" label="Email" component={CustomField} />
                    </div>
                  </div>
                  <div className="signup-container__twoFields">
                    <div className="is-half">
                      <Field
                        name="password"
                        label="Password"
                        type="password"
                        component={CustomField}
                      />
                    </div>
                    <div className="is-half">
                      <Field
                        name="confirmPassword"
                        label="Confirm Password"
                        type="password"
                        component={CustomField}
                      />
                    </div>
                  </div>
                </div>
                <div className="signup-action-button">
                  <button type="submit" disabled={!(isValid && dirty)}>
                    {loading ? <CircularProgress size="22px" /> : 'Submit'}
                  </button>
                </div>
                <div className="login">
                  <span onClick={onLogin}>Login</span>
                </div>
                {showPoweredByImage ? <PoweredBy /> : null}
              </Form>
            )}
          </Formik>
        </div>
      </Box>
    </Modal>
  )
}
