/* eslint-disable @typescript-eslint/no-explicit-any */
import { Button, CircularProgress, ThemeOptions } from '@mui/material'
import { createTheme, ThemeProvider } from '@mui/material/styles'
import { CSSProperties } from '@mui/styles'
import axios, { AxiosError } from 'axios'
import { Form, Formik, FormikValues } from 'formik'
import _get from 'lodash/get'
import _identity from 'lodash/identity'
import _map from 'lodash/map'
import React, { FC, useEffect, useState } from 'react'

import { confirmPreRegistration, getCountries, getProfileData, register } from '../../api'
import { useCookieListener } from '../../hooks/useCookieListener'
import { CONFIGS, getCookieByName, getQueryVariable } from '../../utils'
import SnackbarAlert from '../common/SnackbarAlert'
import ConfirmModal from '../confirmModal'
import { ForgotPasswordModal, IForgotPasswordProps } from '../forgotPasswordModal'
import { LoginModal, Props } from '../loginModal'
import { getFormFieldsLoggedIn, getFormFieldsNotLoggedIn } from './constants'
import { FieldsSection } from './FieldsSection'
import { PreRegistrationComplete } from './PreRegistrationComplete'
import { getFormInitialValues, updateFormFieldsAttributes } from './utils'

const X_TF_ECOMMERCE = 'X-TF-ECOMMERCE'
const isWindowDefined = typeof window !== 'undefined'

interface IPreRegistrationProps extends Props, IForgotPasswordProps {
  eventId: string | number;
  formFields?: IFormFieldsSection[];
  additionalFieldAttribute?: IFieldAttribute;
  isPreregistrationStarted: boolean;
  onGetCountriesSuccess?: (res: any) => void;
  onGetCountriesError?: (e: AxiosError) => void;
  onConfirmationSuccess?: (res: any) => void;
  onConfirmationError?: (e: AxiosError) => void;
  onLoginSuccess?: (res: any) => void;

  themeOptions?: ThemeOptions & {
    input?: CSSProperties;
    checkbox?: CSSProperties;
  };
}

export const PreRegistration: FC<IPreRegistrationProps> = ({
  eventId,
  formFields: pFormFields,
  additionalFieldAttribute,
  isPreregistrationStarted,
  logo,
  showForgotPasswordButton,
  onLoginSuccess = _identity,
  onForgotPasswordSuccess = _identity,
  onForgotPasswordError = _identity,
  onGetCountriesSuccess = _identity,
  onGetCountriesError = _identity,
  onConfirmationSuccess = _identity,
  onConfirmationError = _identity,
  themeOptions,
}) => {
  const [error, setError] = useState('')
  const [showModalLogin, setShowModalLogin] = useState(false)
  const [alreadyHasUser, setAlreadyHasUser] = useState(false)
  const [showModalForgotPassword, setShowModalForgotPassword] = useState(false)
  const [countries, setCountries] = useState<{ [key: string]: string | number }[]>([])
  const [isLoggedIn, setIsLoggedIn] = useState(Boolean(getCookieByName(X_TF_ECOMMERCE)))
  const [confirmModalState, setConfirmModalState] = useState({ show: false, message: '' })
  const [, setUserData] = useState({} as IProfileData)
  const [isPreRegistrationComplete, setIsPreRegistrationComplete] = useState(false)
  useCookieListener(X_TF_ECOMMERCE, value => setIsLoggedIn(Boolean(value)))

  // Check if user already has a pre-registration when logged in
  useEffect(() => {
    if (!isLoggedIn || !isWindowDefined) return

    const savedHash = window.localStorage.getItem(`pre-registration-hash-${eventId}`)
    if (savedHash) {
      setIsPreRegistrationComplete(true)
    }
  }, [isLoggedIn, eventId])

  const themeMui = createTheme(themeOptions)

  const formFieldsLoggedIn = getFormFieldsLoggedIn(CONFIGS.CLIENT_NAME)
  const formFieldsNotLoggedIn = getFormFieldsNotLoggedIn(CONFIGS.CLIENT_NAME)

  const formFields = updateFormFieldsAttributes(
    pFormFields || isLoggedIn ? formFieldsLoggedIn : formFieldsNotLoggedIn,
    additionalFieldAttribute
  )

  useEffect(() => {
    // fetch countries data
    const fetchCountries = async () => {
      try {
        const res = await getCountries()
        setCountries(
          _map(_get(res, 'data'), item => ({
            label: item.name,
            value: Number(item.id),
          }))
        )
        onGetCountriesSuccess(res.data)
      } catch (e) {
        if (axios.isAxiosError(e)) {
          const error = 'Error'
          setError(error)
          onGetCountriesError(e)
        }
      }
    }
    fetchCountries()
  }, [])

  const localStorageHash = isWindowDefined
    ? window.localStorage.getItem('pre-registration-hash') || ''
    : ''
  const hash = getQueryVariable('hash') || localStorageHash
  const referrerId = getQueryVariable('referrer_id') || ''
  return (
    <ThemeProvider theme={themeMui}>
      <div className="pre-registration-container">
        <SnackbarAlert
          type="error"
          isOpen={!!error}
          message={error || ''}
          onClose={() => {
            setError('')
          }}
        />
        {confirmModalState.show && (
          <ConfirmModal
            hideCancelBtn
            onConfirm={() => setConfirmModalState({ show: false, message: '' })}
            message={confirmModalState.message}
          />
        )}
        {!isLoggedIn && (
          <div className="account-actions-block">
            <div className="action-item">
              <div>
                <span>
                  Create (or log in to) your account, then click on Confirm Registration.
                </span>
                <span> If you have a</span>
                <b> {CONFIGS.CLIENT_NAME || 'Mana Common'} </b>
                <span>account and password already</span>
              </div>
            </div>
            <div className="action-item login-block">
              <button
                className="login-register-button"
                type="button"
                onClick={() => {
                  setShowModalLogin(true)
                }}
              >
                Login
              </button>
            </div>
          </div>
        )}
        {showModalLogin && (
          <LoginModal
            logo={logo}
            onClose={() => {
              setShowModalLogin(false)
            }}
            onLogin={res => {
              setShowModalLogin(false)
              onLoginSuccess(res)
            }}
            showForgotPasswordButton={showForgotPasswordButton}
            onForgotPassword={() => {
              setShowModalLogin(false)
              setShowModalForgotPassword(true)
            }}
            alreadyHasUser={alreadyHasUser}
          />
        )}
        {showModalForgotPassword && (
          <ForgotPasswordModal
            onClose={() => {
              setShowModalForgotPassword(false)
            }}
            onLoginButtonClick={() => {
              setShowModalForgotPassword(false)
              setShowModalLogin(true)
            }}
            onForgotPasswordSuccess={onForgotPasswordSuccess}
            onForgotPasswordError={onForgotPasswordError}
            displaySuccessMessage
          />
        )}
        {isPreRegistrationComplete ? (
          <PreRegistrationComplete
            eventId={eventId}
            logo={logo}
            themeOptions={themeOptions}
            onLoginSuccess={onLoginSuccess}
            data={{} as IShareOptionsData}
            classNamePrefix=""
            onLinkCopied={_identity}
            updateShareActionData={_identity}
            hash={hash}
            shareActionData={{} as ISubmitShareActionAttributes}
            skipInitialValidation={true}
          />
        ) : (
          <>
            <h2>Pre-Registration</h2>
            <Formik
              initialValues={getFormInitialValues(formFields)}
              enableReinitialize={true}
              onSubmit={async (values: FormikValues) => {
                try {
                  if (isLoggedIn) {
                    if (isPreregistrationStarted) {
                      const updatedValues = { ...values }
                      const holderAgeDate = new Date(values.holderAge)
                      updatedValues.dobDay = holderAgeDate.getDate()
                      updatedValues.dobMonth = holderAgeDate.getMonth() + 1
                      updatedValues.dobYear = holderAgeDate.getFullYear()
                      updatedValues.referrerId = referrerId
                      updatedValues.shareHash = hash
                      // remove date picker string value
                      delete updatedValues.holderAge

                      const confirmationData = await confirmPreRegistration(
                        eventId,
                        updatedValues as IConfirmPreRegistrationRequestData
                      )
                      if (isWindowDefined) {
                        window.localStorage.setItem(
                          `pre-registration-hash-${eventId}`,
                          _get(confirmationData, 'attributes.hash')
                        )
                      }

                      setIsPreRegistrationComplete(true)
                      onConfirmationSuccess(confirmationData)
                    } else {
                      setConfirmModalState({
                        show: true,
                        message: 'The preregistration has not started',
                      })
                    }
                  } else {
                    const bodyFormData = new FormData()
                    bodyFormData.append('first_name', values.firstName)
                    bodyFormData.append('last_name', values.lastName)
                    bodyFormData.append('email', values.email)
                    bodyFormData.append('confirm_email', values.confirmEmail)
                    bodyFormData.append('zip', values.zip)
                    bodyFormData.append('country', values.country)
                    bodyFormData.append('password', values.password)
                    bodyFormData.append('password_confirmation', values.confirmPassword)
                    bodyFormData.append('client_id', CONFIGS.CLIENT_ID)
                    bodyFormData.append('client_secret', CONFIGS.CLIENT_SECRET)
                    bodyFormData.append('register_for', 'prereg')

                    const res = await register(bodyFormData)
                    const profileRes = await getProfileData()
                    onLoginSuccess(res.data)
                    if (isWindowDefined) {
                      window.localStorage.setItem(
                        'user_data',
                        JSON.stringify(_get(profileRes, 'data'))
                      )
                      setUserData(_get(profileRes, 'data'))
                    }
                  }
                } catch (e) {
                  const error = e as AxiosError
                  let errorMessage = error?.message || 'Error'
                  const emailErrors = _get(error, 'response.data.message.email') || ''
                  const errorDataMessage = _get(error, 'response.data.message')

                  if (typeof errorDataMessage === 'string') {
                    errorMessage = errorDataMessage
                  }
                  if (emailErrors?.length > 0) {
                    if (emailErrors[0] === 'The email is already used') {
                      setShowModalLogin(true)
                      setAlreadyHasUser(true)
                    }
                  } else {
                    setError(errorMessage)
                  }

                  onConfirmationError(error)
                }
              }}
            >
              {props => (
                <Form>
                  <div className="login-modal-body">
                    <FieldsSection
                      formFields={formFields}
                      values={props.values}
                      setFieldValue={props.setFieldValue}
                      containerClass="pre-registration"
                      countries={countries}
                      themeOptions={themeOptions}
                    />
                  </div>
                  <div className="button-container">
                    <Button
                      type="submit"
                      variant="contained"
                      className="login-register-button"
                      disabled={props.isSubmitting}
                    >
                      {props.isSubmitting ? (
                        <CircularProgress size={26} />
                      ) : isLoggedIn ? (
                        'Confirm Pre-Registration'
                      ) : (
                        'Create Account'
                      )}
                    </Button>
                  </div>
                </Form>
              )}
            </Formik>
          </>
        )}
      </div>
    </ThemeProvider>
  )
}
