import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Eye, EyeOff, Smartphone, Lock, KeyRound, ArrowLeft } from 'lucide-react'
import { LanguageSelect, PasswordStrengthMeter, isPasswordStrong } from '@meshkee/dashboard-ui'
import { useAuth, BUSINESS_ACCESS_MESSAGE } from '../context/AuthContext'
import { useTenantBranding } from '../context/TenantBrandingContext'
import { ApiError } from '../lib/api'
import { toE164CellNumber } from '../lib/cellNumber'
import { getBusinessDomain } from '../lib/config'
import { resetPassword, sendOtp } from '../services/authService'
import { useT } from '../i18n/useT'
import styles from './LoginPage.module.css'

type AuthView = 'login' | 'forgot' | 'otp'
type SmsStep = 'phone' | 'code'

export function LoginPage() {
  const navigate = useNavigate()
  const { login, loginWithOtp } = useAuth()
  const { businessName, businessNameEn, logoUrl } = useTenantBranding()
  const businessDomain = getBusinessDomain()
  const t = useT()

  const [view, setView] = useState<AuthView>('login')
  const [smsStep, setSmsStep] = useState<SmsStep>('phone')
  const [showPassword, setShowPassword] = useState(false)
  const [phone, setPhone] = useState('')
  const [password, setPassword] = useState('')
  const [smsCode, setSmsCode] = useState('')
  const [newPassword, setNewPassword] = useState('')
  const [confirmNewPassword, setConfirmNewPassword] = useState('')
  const [codeSent, setCodeSent] = useState(false)
  const [countdown, setCountdown] = useState(0)
  const [error, setError] = useState('')
  const [info, setInfo] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)

  function clearMessages() {
    setError('')
    setInfo('')
  }

  function resetForm() {
    setPhone('')
    setPassword('')
    setSmsCode('')
    setNewPassword('')
    setConfirmNewPassword('')
    setSmsStep('phone')
    setCodeSent(false)
    setShowPassword(false)
    clearMessages()
  }

  function switchView(next: AuthView) {
    resetForm()
    setView(next)
  }

  function startCountdown() {
    setCountdown(60)
    const timer = setInterval(() => {
      setCountdown((prev) => {
        if (prev <= 1) {
          clearInterval(timer)
          return 0
        }
        return prev - 1
      })
    }, 1000)
  }

  function handleApiError(err: unknown, fallback: string) {
    if (err instanceof ApiError) {
      if (err.message === BUSINESS_ACCESS_MESSAGE) {
        setError(t('login.error.access'))
      } else if (
        err.message.includes('E.164') ||
        err.message.includes('cellNumber must be')
      ) {
        setError(t('login.error.cellEnglishDigits'))
      } else if (
        err.message.includes('SMS provider is not configured') ||
        err.message.includes('SMS provider is unreachable') ||
        err.message.includes('SMS provider returned') ||
        err.message.includes('Unable to send SMS')
      ) {
        setError(t('login.error.smsProvider'))
      } else {
        setError(err.message)
      }
    } else {
      setError(fallback)
    }
  }

  function resolveCellNumber(): string | null {
    if (/[۰-۹٠-٩]/.test(phone)) {
      setError(t('login.error.cellEnglishDigits'))
      return null
    }
    const cellNumber = toE164CellNumber(phone)
    if (!/^\+[1-9]\d{6,14}$/.test(cellNumber)) {
      setError(t('login.error.cellEnglishDigits'))
      return null
    }
    return cellNumber
  }

  async function handleSendCode() {
    clearMessages()
    const cellNumber = resolveCellNumber()
    if (!cellNumber) return

    setIsSubmitting(true)

    try {
      const result = await sendOtp(cellNumber, businessDomain)

      if (!result.enabled) {
        setInfo(result.message)
      }

      setCodeSent(true)
      setSmsStep('code')
      startCountdown()
    } catch (err) {
      handleApiError(err, t('login.error.sendCode'))
    } finally {
      setIsSubmitting(false)
    }
  }

  async function handleLogin(e: React.FormEvent) {
    e.preventDefault()
    clearMessages()
    const cellNumber = resolveCellNumber()
    if (!cellNumber) return

    setIsSubmitting(true)

    try {
      await login(cellNumber, password)
      navigate('/')
    } catch (err) {
      handleApiError(err, t('login.error.signIn'))
    } finally {
      setIsSubmitting(false)
    }
  }

  async function handleResetPassword(e: React.FormEvent) {
    e.preventDefault()
    clearMessages()

    if (!isPasswordStrong(newPassword)) {
      setError(t('forgot.error.strength'))
      return
    }

    if (newPassword !== confirmNewPassword) {
      setError(t('forgot.error.match'))
      return
    }

    const cellNumber = resolveCellNumber()
    if (!cellNumber) return

    setIsSubmitting(true)

    try {
      await resetPassword(cellNumber, smsCode, newPassword)
      setInfo(t('forgot.info.success'))
      setTimeout(() => switchView('login'), 2000)
    } catch (err) {
      handleApiError(err, t('forgot.error.verify'))
    } finally {
      setIsSubmitting(false)
    }
  }

  async function handleOtpLogin(e: React.FormEvent) {
    e.preventDefault()
    clearMessages()
    const cellNumber = resolveCellNumber()
    if (!cellNumber) return

    setIsSubmitting(true)

    try {
      await loginWithOtp(cellNumber, smsCode)
      navigate('/')
    } catch (err) {
      handleApiError(err, t('otp.error.signIn'))
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <div className={styles.page}>
      <div className={styles.card}>
        <div className={styles.brand}>
          {logoUrl ? <img src={logoUrl} alt="" className={styles.logo} /> : null}
          <div className={styles.brandText}>
            <span className={styles.businessName}>{businessName || businessDomain}</span>
            <span className={styles.appName}>{businessNameEn || businessDomain}</span>
          </div>
          <div className={styles.langSelect}>
            <LanguageSelect />
          </div>
        </div>

        {view === 'login' && (
          <>
            <h1 className={styles.title}>{t('login.welcome')}</h1>
            <p className={styles.subtitle}>{t('login.subtitle')}</p>

            <form className={styles.form} onSubmit={handleLogin}>
              {error && (
                <div className={styles.error} role="alert">
                  {error}
                </div>
              )}
              {info && <div className={styles.info}>{info}</div>}

              <div className={styles.field}>
                <label htmlFor="login-phone">{t('login.mobile')}</label>
                <div className={styles.inputWrap}>
                  <Smartphone size={18} className={styles.inputIcon} />
                  <input
                    id="login-phone"
                    type="tel"
                    inputMode="tel"
                    placeholder="09122222222"
                    value={phone}
                    onChange={(e) => setPhone(e.target.value)}
                    required
                    disabled={isSubmitting}
                  />
                </div>
              </div>

              <div className={styles.field}>
                <label htmlFor="login-password">{t('login.password')}</label>
                <div className={styles.inputWrap}>
                  <Lock size={18} className={styles.inputIcon} />
                  <input
                    id="login-password"
                    type={showPassword ? 'text' : 'password'}
                    dir="ltr"
                    lang="en"
                    placeholder={t('login.passwordPlaceholder')}
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                    required
                    minLength={8}
                    disabled={isSubmitting}
                  />
                  <button
                    type="button"
                    className={styles.togglePassword}
                    onClick={() => setShowPassword((v) => !v)}
                    aria-label={showPassword ? t('login.hidePassword') : t('login.showPassword')}
                    disabled={isSubmitting}
                  >
                    {showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
                  </button>
                </div>
              </div>

              <div className={styles.formActions}>
                <button
                  type="button"
                  className={styles.linkBtn}
                  onClick={() => switchView('forgot')}
                  disabled={isSubmitting}
                >
                  {t('login.forgot')}
                </button>
              </div>

              <button type="submit" className={styles.submitBtn} disabled={isSubmitting}>
                {isSubmitting ? t('login.signingIn') : t('login.signIn')}
              </button>
            </form>

            <div className={styles.divider}>
              <span>{t('login.or')}</span>
            </div>

            <button
              type="button"
              className={styles.secondaryBtn}
              onClick={() => switchView('otp')}
              disabled={isSubmitting}
            >
              <KeyRound size={18} />
              {t('login.otp')}
            </button>
          </>
        )}

        {view === 'forgot' && (
          <>
            <button
              type="button"
              className={styles.backBtn}
              onClick={() => switchView('login')}
              disabled={isSubmitting}
            >
              <ArrowLeft size={18} />
              {t('forgot.back')}
            </button>

            <h1 className={styles.title}>{t('forgot.title')}</h1>
            <p className={styles.subtitle}>
              {smsStep === 'phone' ? t('forgot.subtitlePhone') : t('forgot.subtitleCode')}
            </p>

            <form className={styles.form} onSubmit={handleResetPassword}>
              {error && (
                <div className={styles.error} role="alert">
                  {error}
                </div>
              )}
              {info && <div className={styles.info}>{info}</div>}

              {smsStep === 'phone' ? (
                <>
                  <div className={styles.field}>
                    <label htmlFor="forgot-phone">{t('login.mobile')}</label>
                    <div className={styles.inputWrap}>
                      <Smartphone size={18} className={styles.inputIcon} />
                      <input
                        id="forgot-phone"
                        type="tel"
                        inputMode="tel"
                        placeholder="09122222222"
                        value={phone}
                        onChange={(e) => setPhone(e.target.value)}
                        required
                        disabled={isSubmitting}
                      />
                    </div>
                  </div>

                  <button
                    type="button"
                    className={styles.submitBtn}
                    onClick={() => void handleSendCode()}
                    disabled={isSubmitting}
                  >
                    {isSubmitting ? t('forgot.sending') : t('forgot.sendCode')}
                  </button>
                </>
              ) : (
                <>
                  {codeSent && (
                    <p className={styles.codeHint}>{t('common.codeSent', { phone })}</p>
                  )}

                  <div className={styles.field}>
                    <label htmlFor="forgot-code">{t('forgot.code')}</label>
                    <div className={styles.inputWrap}>
                      <KeyRound size={18} className={styles.inputIcon} />
                      <input
                        id="forgot-code"
                        type="text"
                        inputMode="numeric"
                        placeholder="123456"
                        maxLength={6}
                        value={smsCode}
                        onChange={(e) => setSmsCode(e.target.value.replace(/\D/g, ''))}
                        required
                        disabled={isSubmitting}
                      />
                    </div>
                  </div>

                  <div className={styles.field}>
                    <label htmlFor="forgot-new-password">{t('forgot.newPassword')}</label>
                    <div className={styles.inputWrap}>
                      <Lock size={18} className={styles.inputIcon} />
                      <input
                        id="forgot-new-password"
                        type={showPassword ? 'text' : 'password'}
                        dir="ltr"
                        lang="en"
                        placeholder={t('forgot.newPasswordPlaceholder')}
                        value={newPassword}
                        onChange={(e) => setNewPassword(e.target.value)}
                        required
                        minLength={8}
                        disabled={isSubmitting}
                        aria-describedby="forgot-password-strength"
                      />
                      <button
                        type="button"
                        className={styles.togglePassword}
                        onClick={() => setShowPassword((v) => !v)}
                        aria-label={showPassword ? t('login.hidePassword') : t('login.showPassword')}
                        disabled={isSubmitting}
                      >
                        {showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
                      </button>
                    </div>
                    <PasswordStrengthMeter
                      password={newPassword}
                      id="forgot-password-strength"
                      labels={{
                        title: t('password.strength'),
                        empty: t('password.strength.empty'),
                        weak: t('password.strength.weak'),
                        fair: t('password.strength.fair'),
                        good: t('password.strength.good'),
                        strong: t('password.strength.strong'),
                        rules: {
                          length: t('password.rule.length'),
                          upper: t('password.rule.upper'),
                          number: t('password.rule.number'),
                          special: t('password.rule.special'),
                        },
                      }}
                    />
                  </div>

                  <div className={styles.field}>
                    <label htmlFor="forgot-confirm-password">{t('forgot.confirm')}</label>
                    <div className={styles.inputWrap}>
                      <Lock size={18} className={styles.inputIcon} />
                      <input
                        id="forgot-confirm-password"
                        type={showPassword ? 'text' : 'password'}
                        dir="ltr"
                        lang="en"
                        placeholder={t('forgot.confirmPlaceholder')}
                        value={confirmNewPassword}
                        onChange={(e) => setConfirmNewPassword(e.target.value)}
                        required
                        minLength={8}
                        disabled={isSubmitting}
                      />
                    </div>
                  </div>

                  <div className={styles.resendRow}>
                    {countdown > 0 ? (
                      <span className={styles.countdown}>
                        {t('common.resendIn', { seconds: countdown })}
                      </span>
                    ) : (
                      <button
                        type="button"
                        className={styles.linkBtn}
                        onClick={() => void handleSendCode()}
                        disabled={isSubmitting}
                      >
                        {t('common.resend')}
                      </button>
                    )}
                  </div>

                  <button
                    type="submit"
                    className={styles.submitBtn}
                    disabled={isSubmitting || !isPasswordStrong(newPassword)}
                  >
                    {isSubmitting ? t('forgot.verifying') : t('forgot.reset')}
                  </button>
                </>
              )}
            </form>
          </>
        )}

        {view === 'otp' && (
          <>
            <button
              type="button"
              className={styles.backBtn}
              onClick={() => switchView('login')}
              disabled={isSubmitting}
            >
              <ArrowLeft size={18} />
              {t('otp.back')}
            </button>

            <h1 className={styles.title}>{t('otp.title')}</h1>
            <p className={styles.subtitle}>
              {smsStep === 'phone' ? t('otp.subtitlePhone') : t('otp.subtitleCode')}
            </p>

            <form className={styles.form} onSubmit={handleOtpLogin}>
              {error && (
                <div className={styles.error} role="alert">
                  {error}
                </div>
              )}
              {info && <div className={styles.info}>{info}</div>}

              {smsStep === 'phone' ? (
                <>
                  <div className={styles.field}>
                    <label htmlFor="otp-phone">{t('login.mobile')}</label>
                    <div className={styles.inputWrap}>
                      <Smartphone size={18} className={styles.inputIcon} />
                      <input
                        id="otp-phone"
                        type="tel"
                        inputMode="tel"
                        placeholder="09122222222"
                        value={phone}
                        onChange={(e) => setPhone(e.target.value)}
                        required
                        disabled={isSubmitting}
                      />
                    </div>
                  </div>

                  <button
                    type="button"
                    className={styles.submitBtn}
                    onClick={() => void handleSendCode()}
                    disabled={isSubmitting}
                  >
                    {isSubmitting ? t('otp.sending') : t('otp.sendCode')}
                  </button>
                </>
              ) : (
                <>
                  {codeSent && (
                    <p className={styles.codeHint}>{t('common.codeSent', { phone })}</p>
                  )}

                  <div className={styles.field}>
                    <label htmlFor="otp-code">{t('otp.code')}</label>
                    <div className={styles.inputWrap}>
                      <KeyRound size={18} className={styles.inputIcon} />
                      <input
                        id="otp-code"
                        type="text"
                        inputMode="numeric"
                        placeholder="123456"
                        maxLength={6}
                        value={smsCode}
                        onChange={(e) => setSmsCode(e.target.value.replace(/\D/g, ''))}
                        required
                        disabled={isSubmitting}
                      />
                    </div>
                  </div>

                  <div className={styles.resendRow}>
                    {countdown > 0 ? (
                      <span className={styles.countdown}>
                        {t('common.resendIn', { seconds: countdown })}
                      </span>
                    ) : (
                      <button
                        type="button"
                        className={styles.linkBtn}
                        onClick={() => void handleSendCode()}
                        disabled={isSubmitting}
                      >
                        {t('common.resend')}
                      </button>
                    )}
                  </div>

                  <button type="submit" className={styles.submitBtn} disabled={isSubmitting}>
                    {isSubmitting ? t('otp.signingIn') : t('otp.signIn')}
                  </button>
                </>
              )}
            </form>
          </>
        )}
      </div>
      <a
        className={styles.poweredBy}
        href="https://meshkee.com"
        target="_blank"
        rel="noopener noreferrer"
      >
        Powered by Meshkee.app
      </a>
    </div>
  )
}
