import axios, { AxiosError } from 'axios'
import { Field, Form, Formik } from 'formik'
import _get from 'lodash/get'
import _identity from 'lodash/identity'
import React, { FC, useState } from 'react'

import { authorize, getProfileData } from '../../api'
import { combineValidators, emailValidator, requiredValidator } from '../../validators'
import { CustomField } from '../common'
import { PoweredBy } from '../common/PoweredBy'

export interface ILoginFormProps {
  alreadyHasUser?: boolean;
  userExpired?: boolean;

  onLoginSuccess?: (res: IProfileData) => void;
  onLoginError?: (e: AxiosError) => void;

  onGetProfileDataSuccess?: (res: IProfileData) => void;
  onGetProfileDataError?: (e: AxiosError) => void;

  onForgotPasswordButtonClick?: () => void;
  onSignupButtonClick?: () => void;

  logo?: string;
  showForgotPasswordButton?: boolean;
  showSignUpButton?: boolean;
  showPoweredByImage?: boolean;
  registerUrl?: string;
}

// interface IUserData {
//   id: string;
//   firstName: string;
//   lastName: string;
//   email: string;
//   city?: string;
//   country?: string;
//   countryId?: string;
//   phone?: string;
//   streetAddress?: string;
//   state?: string;
//   zip?: string;
//   zipCode?: string;
//   stateId?: string;
// }

export const setLoggedUserData = (data: IProfileData) => ({
  id: data.id,
  first_name: data.firstName,
  last_name: data.lastName,
  email: data.email,
  confirmEmail: data.email,
  city: data?.city || '',
  country: data?.countryId || '',
  phone: data?.phone || '',
  street_address: data?.streetAddress || '',
  state: data?.stateId || '',
  zip: data?.zipCode || '',
})

export const LoginForm: FC<ILoginFormProps> = ({
  alreadyHasUser = false,
  userExpired = false,

  onLoginSuccess = _identity,
  onLoginError = _identity,

  onGetProfileDataSuccess = _identity,
  onGetProfileDataError = _identity,

  onForgotPasswordButtonClick = _identity,
  onSignupButtonClick = _identity,

  logo,
  showForgotPasswordButton = false,
  showSignUpButton = false,
  showPoweredByImage = false,
  registerUrl = 'https://www.ticketfairy.com/register',
}) => {
  const [error, setError] = useState('')
  return (
    <div className="login-modal">
      <Formik
        initialValues={{ email: '', password: '' }}
        onSubmit={async ({ email, password }) => {
          try {
            const body = { email, password }
            const authRes = await authorize(body)
            let profileResponse = null
            try {
              profileResponse = await getProfileData()
              onGetProfileDataSuccess(_get(profileResponse, 'data'))
            } catch (e) {
              if (axios.isAxiosError(e)) {
                onGetProfileDataError(e)
              }
              return
            }

            const profileSpecifiedData = _get(profileResponse, 'data')
            const profileDataObj = setLoggedUserData(profileSpecifiedData)
            if (typeof window !== 'undefined') {
              window.localStorage.setItem('user_data', JSON.stringify(profileDataObj))
              const event = new window.CustomEvent('tf-login')
              window.document.dispatchEvent(event)
            }
            onLoginSuccess(_get(authRes, 'data'))
          } catch (e) {
            if (axios.isAxiosError(e)) {
              const error = _get(e, 'response.data.message') || 'Error'
              setError(error)
              onLoginError(e)
            } else if (e instanceof Error) {
              setError(e?.message || 'Error')
            }
          }
        }}
      >
        {props => (
          <Form onSubmit={props.handleSubmit}>
            <div className="modal-title">Login</div>
            <div className="login-logo-container">
              <img
                className="login-logo-tff"
                src={
                  logo ||
                  'https://www.ticketfairy.com/resources/images/logo-ttf-black.svg'
                }
                alt="logo"
              />
            </div>
            <div className="server_auth__error">{error}</div>
            {alreadyHasUser && (
              <p className="info-text-for-login">
                It appears this email is already attached to an account. Please log in
                here to complete your registration.
              </p>
            )}
            {userExpired && (
              <p className="info-text-for-login">
                Your session has expired, please log in again.
              </p>
            )}
            <div className="login-modal-body">
              <div className="login-modal-body__email">
                <Field
                  name="email"
                  label="Email"
                  type="email"
                  component={CustomField}
                  validate={combineValidators(requiredValidator, emailValidator)}
                />
              </div>
              <div className="login-modal-body__password">
                <Field
                  name="password"
                  label="Password"
                  type="password"
                  component={CustomField}
                  validate={requiredValidator}
                />
              </div>
              <div className="login-action-button">
                <button type="submit">Login</button>
              </div>
              {showForgotPasswordButton && (
                <div className="forgot-password">
                  <span aria-hidden="true" onClick={onForgotPasswordButtonClick}>
                    Forgot password?
                  </span>
                </div>
              )}
              {showSignUpButton && (
                <div className="forgot-password">
                  {onSignupButtonClick !== _identity ? (
                    <span
                      aria-hidden="true"
                      onClick={onSignupButtonClick}
                      style={{ cursor: 'pointer' }}
                    >
                      Sign up
                    </span>
                  ) : (
                    <a
                      href={registerUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                    >
                      Sign up
                    </a>
                  )}
                </div>
              )}
              {showPoweredByImage ? <PoweredBy /> : null}
            </div>
          </Form>
        )}
      </Formik>
    </div>
  )
}
