import './style.css'

import Box from '@mui/material/Box'
import Modal from '@mui/material/Modal'
import Tab from '@mui/material/Tab'
import Tabs from '@mui/material/Tabs'
import useMediaQuery from '@mui/material/useMediaQuery'
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 { isBrowser, setLoggedUserData } from '../../utils'
import { requiredValidator } from '../../validators'
import { CustomField } from '../common/CustomField'
import { PoweredBy } from '../common/PoweredBy'
import { COLORS, MODAL_DIMENSIONS, TAB_STYLES } from './constants'
import { SignUpForm } from './SignUpForm'

export interface Props {
  onClose: () => void;
  onLogin: (res: IProfileData) => void;
  alreadyHasUser?: boolean;
  userExpired?: boolean;
  onAuthorizeSuccess?: (res: any) => void;
  onAuthorizeError?: (e: AxiosError) => void;
  onGetProfileDataSuccess?: (res: any) => void;
  onGetProfileDataError?: (e: AxiosError) => void;
  onForgotPassword?: () => void;
  onSignup?: () => void;
  modalClassname?: string;
  logo?: string;
  showForgotPasswordButton?: boolean;
  showSignUpButton?: boolean;
  showPoweredByImage?: boolean;
  registerUrl?: string;
}

const style: React.CSSProperties = {
  position: 'absolute',
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  width: MODAL_DIMENSIONS.WIDTH.DESKTOP,
  backgroundColor: '#e3e3e3',
  border: `1px solid ${COLORS.BORDER}`,
  outline: 'none',
}

const mobileStyle: React.CSSProperties = {
  ...style,
  width: MODAL_DIMENSIONS.WIDTH.MOBILE,
}

export const LoginModal: FC<Props> = ({
  onClose,
  onLogin,
  alreadyHasUser = false,
  userExpired = false,
  onGetProfileDataSuccess = _identity,
  onGetProfileDataError = _identity,
  onForgotPassword = _identity,
  onSignup = _identity,
  modalClassname = '',
  logo,
  showForgotPasswordButton = false,
  showSignUpButton = false,
  showPoweredByImage = false,
}) => {
  const [error, setError] = useState('')
  const [activeTab, setActiveTab] = useState<'login' | 'signup'>('login')
  const isMobile = useMediaQuery('(max-width:600px)')

  // If onSignup is provided (custom callback), use old behavior
  const useCustomSignup = onSignup !== _identity

  const handleTabChange = (_event: React.SyntheticEvent, newValue: 'login' | 'signup') => {
    setActiveTab(newValue)
  }

  return (
    <Modal
      open={true}
      onClose={onClose}
      aria-labelledby="modal-modal-title"
      aria-describedby="modal-modal-description"
      className={`login-modal ${modalClassname}`}
    >
      <Box style={isMobile ? mobileStyle : style}
        sx={{
          '@media screen and (orientation:landscape)': {
            maxHeight: '80vh',
            overflowY: 'auto'
          }
        }}
      >
        <div>
          {showSignUpButton && !useCustomSignup && (
            <Tabs
              value={activeTab}
              onChange={handleTabChange}
              variant="fullWidth"
              sx={{
                backgroundColor: TAB_STYLES.BACKGROUND_COLOR,
                marginBottom: TAB_STYLES.MARGIN_BOTTOM,
                '& .MuiTabs-indicator': {
                  backgroundColor: TAB_STYLES.INDICATOR.BACKGROUND_COLOR,
                },
              }}
            >
              <Tab
                label="Login"
                value="login"
                sx={{
                  fontFamily: TAB_STYLES.LABEL.FONT_FAMILY,
                  fontWeight: TAB_STYLES.LABEL.FONT_WEIGHT,
                  fontSize: TAB_STYLES.LABEL.FONT_SIZE,
                  textTransform: TAB_STYLES.LABEL.TEXT_TRANSFORM,
                  color: TAB_STYLES.LABEL.COLOR,
                  '&.Mui-selected': {
                    color: TAB_STYLES.LABEL.SELECTED_COLOR,
                  },
                }}
              />
              <Tab
                label="Sign Up"
                value="signup"
                sx={{
                  fontFamily: TAB_STYLES.LABEL.FONT_FAMILY,
                  fontWeight: TAB_STYLES.LABEL.FONT_WEIGHT,
                  fontSize: TAB_STYLES.LABEL.FONT_SIZE,
                  textTransform: TAB_STYLES.LABEL.TEXT_TRANSFORM,
                  color: TAB_STYLES.LABEL.COLOR,
                  '&.Mui-selected': {
                    color: TAB_STYLES.LABEL.SELECTED_COLOR,
                  },
                }}
              />
            </Tabs>
          )}

          {activeTab === 'login' ? (
            <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(profileResponse.data)
                } catch (e) {
                  if (axios.isAxiosError(e)) {
                    onGetProfileDataError(e)
                  }
                  return
                }

                const profileSpecifiedData = profileResponse.data
                const profileDataObj = setLoggedUserData(profileSpecifiedData)
                if (isBrowser) {
                  window.localStorage.setItem('user_data', JSON.stringify(profileDataObj))
                  const event = new window.CustomEvent('tf-login')
                  window.document.dispatchEvent(event)
                }
                onLogin(_get(authRes, 'data.data', {}) as IProfileData)
              } catch (e) {
                if (axios.isAxiosError(e)) {
                  const error = _get(e, 'response.data.message', 'Error')
                  setError(error)
                } else if (e instanceof Error) {
                  setError(e?.message || 'Error')
                }
              }
            }}
          >
            {props => (
              <Form onSubmit={props.handleSubmit}>
                <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}
                      theme="light"
                      validate={requiredValidator}
                    />
                  </div>
                  <div className="login-modal-body__password">
                    <Field
                      name="password"
                      label="Password"
                      type="password"
                      component={CustomField}
                      theme="light"
                      validate={requiredValidator}
                    />
                  </div>
                  <div className="login-action-button">
                    <button type="submit">Login</button>
                  </div>
                  {showForgotPasswordButton && (
                    <div className="forgot-password">
                      <span aria-hidden="true" onClick={onForgotPassword}>
                        Forgot password?
                      </span>
                    </div>
                  )}
                  {showSignUpButton && useCustomSignup && (
                    <div className="forgot-password">
                      <span
                        aria-hidden="true"
                        onClick={onSignup}
                        style={{ cursor: 'pointer' }}
                      >
                        Sign up
                      </span>
                    </div>
                  )}
                  {showPoweredByImage ? <PoweredBy /> : null}
                </div>
              </Form>
            )}
          </Formik>
          ) : (
            <SignUpForm
              onSignUpSuccess={onLogin}
              onGetProfileDataSuccess={onGetProfileDataSuccess}
              onGetProfileDataError={onGetProfileDataError}
              logo={logo}
            />
          )}
        </div>
      </Box>
    </Modal>
  )
}
