'use client'

// React Imports
import { useMemo, useState } from 'react'

// Next Imports
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation'
import { useTranslations } from 'next-intl'

// MUI Imports
import useMediaQuery from '@mui/material/useMediaQuery'
import { styled, useTheme } from '@mui/material/styles'
import Typography from '@mui/material/Typography'
import Button from '@mui/material/Button'
import Alert from '@mui/material/Alert'
import CircularProgress from '@mui/material/CircularProgress'

// Third-party Imports
import { Controller, useForm } from 'react-hook-form'
import { valibotResolver } from '@hookform/resolvers/valibot'
import { object, minLength, maxLength, string, pipe, nonEmpty, custom } from 'valibot'
import type { SubmitHandler } from 'react-hook-form'
import classnames from 'classnames'
import { OTPInput } from 'input-otp'

// Type Imports
import type { SystemMode } from '@core/types'

// Component Imports
import Logo from '@components/layout/shared/Logo'
import CustomTextField from '@core/components/mui/TextField'

// Context Imports
import { useAuth } from '@/contexts/authContext'

// Config Imports
import themeConfig from '@configs/themeConfig'

// Hook Imports
import { useImageVariant } from '@core/hooks/useImageVariant'
import { useSettings } from '@core/hooks/useSettings'

// Styled Custom Components
const LoginIllustration = styled('img')(({ theme }) => ({
  zIndex: 2,
  blockSize: 'auto',
  maxBlockSize: 680,
  maxInlineSize: '100%',
  margin: theme.spacing(12),
  [theme.breakpoints.down(1536)]: {
    maxBlockSize: 550
  },
  [theme.breakpoints.down('lg')]: {
    maxBlockSize: 450
  }
}))

const MaskImg = styled('img')({
  blockSize: 'auto',
  maxBlockSize: 355,
  inlineSize: '100%',
  position: 'absolute',
  insetBlockEnd: 0,
  zIndex: -1
})

const OtpContainer = styled('div')({
  display: 'flex',
  justifyContent: 'center',
  gap: '8px',
  marginTop: '16px'
})

type ErrorType = {
  message: string
}

type PhoneFormData = {
  phone_number: string
}

const Login = ({ mode }: { mode: SystemMode }) => {
  const t = useTranslations('login')

  const phoneSchema = useMemo(
    () =>
      object({
        phone_number: pipe(
          string(),
          nonEmpty(String(t('validation.phoneRequired'))),
          minLength(10, String(t('validation.phoneMinLength'))),
          maxLength(15, String(t('validation.phoneMaxLength'))),
          custom((input) => /^[0-9]+$/.test(String(input)), String(t('validation.phoneDigitsOnly')))
        )
      }),
    [t]
  )
  // States
  const [step, setStep] = useState<'phone' | 'otp'>('phone')
  const [otp, setOtp] = useState('')
  const [tempToken, setTempToken] = useState<string>('')
  const [errorState, setErrorState] = useState<ErrorType | null>(null)
  const [isLoading, setIsLoading] = useState(false)

  // Vars
  const darkImg = '/images/pages/auth-mask-dark.png'
  const lightImg = '/images/pages/auth-mask-light.png'
  const darkIllustration = '/images/illustrations/auth/v2-login-dark.png'
  const lightIllustration = '/images/illustrations/auth/v2-login-light.png'
  const borderedDarkIllustration = '/images/illustrations/auth/v2-login-dark-border.png'
  const borderedLightIllustration = '/images/illustrations/auth/v2-login-light-border.png'

  // Hooks
  const router = useRouter()
  const searchParams = useSearchParams()
  const { settings } = useSettings()
  const theme = useTheme()
  const hidden = useMediaQuery(theme.breakpoints.down('md'))
  const authBackground = useImageVariant(mode, lightImg, darkImg)
  const { requestOTP, login } = useAuth()

  const {
    control,
    handleSubmit,
    getValues,
    formState: { errors }
  } = useForm<PhoneFormData>({
    resolver: valibotResolver(phoneSchema) as any,
    defaultValues: {
      phone_number: ''
    }
  })

  const characterIllustration = useImageVariant(
    mode,
    lightIllustration,
    darkIllustration,
    borderedLightIllustration,
    borderedDarkIllustration
  )

  const onPhoneSubmit: SubmitHandler<PhoneFormData> = async (data: PhoneFormData) => {
    setIsLoading(true)
    setErrorState(null)

    try {
      const token = await requestOTP(data.phone_number)
      setTempToken(token)
      setStep('otp')
    } catch (error: any) {
      setErrorState({ message: error.message || t('errors.sendOtpFailed') })
    } finally {
      setIsLoading(false)
    }
  }

  const onOtpSubmit = async (otpValue?: string) => {
    const code = otpValue ?? otp
    if (code.length !== 6) {
      setErrorState({ message: t('errors.incompleteOtp') })
      return
    }

    setIsLoading(true)
    setErrorState(null)

    try {
      const phoneNumber = getValues('phone_number')
      await login(phoneNumber, code, tempToken)
      
      // Redirect on successful login
      const redirectURL = searchParams.get('redirectTo') ?? '/'
      router.replace(redirectURL)
    } catch (error: any) {
      setErrorState({ message: error.message || t('errors.otpVerificationFailed') })
    } finally {
      setIsLoading(false)
    }
  }

  const handleBackToPhone = () => {
    setStep('phone')
    setOtp('')
    setErrorState(null)
  }

  return (
    <div className='flex bs-full justify-center'>
      <div
        className={classnames(
          'flex bs-full items-center justify-center flex-1 min-bs-[100dvh] relative p-6 max-md:hidden',
          {
            'border-ie': settings.skin === 'bordered'
          }
        )}
      >
        <LoginIllustration src={characterIllustration} alt='character-illustration' />
        {!hidden && <MaskImg alt='mask' src={authBackground} />}
      </div>
      <div className='flex justify-center items-center bs-full bg-backgroundPaper !min-is-full p-6 md:!min-is-[unset] md:p-12 md:is-[480px]'>
        <div className='absolute block-start-5 sm:block-start-[33px] inline-start-6 sm:inline-start-[38px]'>
          <Logo />
        </div>
        <div className='flex flex-col gap-6 is-full sm:is-auto md:is-full sm:max-is-[400px] md:max-is-[unset] mbs-8 sm:mbs-11 md:mbs-0'>
          <div className='flex flex-col gap-1'>
            <Typography variant='h4'>{t('welcome', { templateName: themeConfig.templateName })}</Typography>
            <Typography>
              {step === 'phone' ? t('phoneStep') : t('otpStep')}
            </Typography>
          </div>

          {errorState && (
            <Alert severity='error' onClose={() => setErrorState(null)}>
              {errorState.message}
            </Alert>
          )}

          {step === 'phone' ? (
            <form
              noValidate
              autoComplete='off'
              action={() => {}}
              onSubmit={handleSubmit(onPhoneSubmit)}
              className='flex flex-col gap-6'
            >
              <Controller
                name='phone_number'
                control={control}
                rules={{ required: true }}
                render={({ field }) => (
                  <CustomTextField
                    {...field}
                    autoFocus
                    fullWidth
                    type='tel'
                    label={t('phoneNumber')}
                    placeholder={t('placeholderPhone')}
                    onChange={e => {
                      field.onChange(e.target.value.replace(/\D/g, '')) // Only allow digits
                      errorState !== null && setErrorState(null)
                    }}
                    {...(errors.phone_number && {
                      error: true,
                      helperText: errors.phone_number.message
                    })}
                  />
                )}
              />
              <Button fullWidth variant='contained' type='submit' disabled={isLoading}>
                {isLoading ? <CircularProgress size={24} /> : t('sendOtp')}
              </Button>
              <div className='flex justify-center items-center flex-wrap gap-2'>
                <Typography>{t('newUser')}</Typography>
                <Typography component={Link} href='/register' color='primary.main'>
                  {t('createAccount')}
                </Typography>
              </div>
            </form>
          ) : (
            <div className='flex flex-col gap-6'>
              <div className='flex flex-col gap-4'>
                <Typography variant='body2' color='text.secondary'>
                  {t('otpSent', { phone: getValues('phone_number') })}
                </Typography>
                <OtpContainer>
                  <OTPInput
                    value={otp}
                    onChange={(value) => {
                      setOtp(value)
                      if (value.length === 6) onOtpSubmit(value)
                    }}
                    maxLength={6}
                    containerClassName='flex gap-2 ltr:flex-row rtl:flex-row-reverse'
                    render={({ slots }) => (
                      <>
                        {slots.map((slot, idx) => (
                          <div
                            key={idx}
                            className={classnames(
                              'flex items-center justify-center w-12 h-12 text-2xl font-semibold border rounded',
                              {
                                'border-primary': slot.isActive,
                                'border-defaultBorder': !slot.isActive && slot.char !== null,
                                'border-error': errorState !== null
                              }
                            )}
                          >
                            {slot.char}
                          </div>
                        ))}
                      </>
                    )}
                  />
                </OtpContainer>
              </div>
              <Button fullWidth variant='contained' onClick={() => onOtpSubmit()} disabled={isLoading || otp.length !== 6}>
                {isLoading ? <CircularProgress size={24} /> : t('verifyOtp')}
              </Button>
              <Button fullWidth variant='text' onClick={handleBackToPhone} disabled={isLoading}>
                {t('backToPhone')}
              </Button>
            </div>
          )}
        </div>
      </div>
    </div>
  )
}

export default Login