import { useState } from 'react'
import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { AlertCircle, Eye, EyeOff, Lock, Mail, ShieldCheck, Sparkles } from 'lucide-react'
import { useAuth } from '#/context/auth-context'
import { AppError } from '#/types'
import { Button, Input } from '#/components/ui/primitives'
import { MOCK_CREDENTIALS } from '#/lib/mock-data/users'
import { isUsingMockData } from '#/lib/services/service-factory'

export const Route = createFileRoute('/login')({ component: LoginPage })

type LoginState = 'idle' | 'loading' | 'invalid' | 'network-error' | 'rate-limited'

function LoginPage() {
  const { login } = useAuth()
  const navigate = useNavigate()

  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [showPassword, setShowPassword] = useState(false)
  const [rememberMe, setRememberMe] = useState(true)
  const [state, setState] = useState<LoginState>('idle')
  const [forgotOpen, setForgotOpen] = useState(false)

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setState('loading')
    try {
      await login({ email, password, rememberMe })
      navigate({ to: '/mail/$folder', params: { folder: 'inbox' } })
    } catch (err) {
      if (err instanceof AppError && err.kind === 'unauthorized') {
        setState('invalid')
      } else if (err instanceof AppError && err.kind === 'rate-limited') {
        setState('rate-limited')
      } else {
        setState('network-error')
      }
    }
  }

  const fillDemoCredentials = () => {
    setEmail(MOCK_CREDENTIALS.email)
    setPassword(MOCK_CREDENTIALS.password)
  }

  return (
    <div className="flex min-h-screen items-center justify-center bg-surface-2 px-4">
      <div className="w-full max-w-md">
        <div className="mb-8 flex flex-col items-center gap-3 text-center">
          <div className="flex size-12 items-center justify-center rounded-2xl bg-accent text-white shadow-lg">
            <Mail className="size-6" />
          </div>
          <div>
            <h1 className="text-xl font-semibold text-primary">Enterprise Mail</h1>
            <p className="mt-1 text-sm text-tertiary">Sign in to your workspace</p>
          </div>
        </div>

        <div className="rounded-2xl border border-subtle bg-surface p-6 shadow-xl">
          {!forgotOpen ? (
            <form onSubmit={handleSubmit} className="flex flex-col gap-4" noValidate>
              {state === 'invalid' && (
                <div className="flex items-start gap-2 rounded-lg bg-red-500/10 px-3 py-2.5 text-sm text-red-600 dark:text-red-400">
                  <AlertCircle className="mt-0.5 size-4 shrink-0" />
                  <span>The email or password you entered is incorrect. Please try again.</span>
                </div>
              )}
              {state === 'rate-limited' && (
                <div className="flex items-start gap-2 rounded-lg bg-amber-500/10 px-3 py-2.5 text-sm text-amber-600 dark:text-amber-400">
                  <AlertCircle className="mt-0.5 size-4 shrink-0" />
                  <span>Too many sign-in attempts. Please wait a minute and try again.</span>
                </div>
              )}
              {state === 'network-error' && (
                <div className="flex items-start gap-2 rounded-lg bg-amber-500/10 px-3 py-2.5 text-sm text-amber-600 dark:text-amber-400">
                  <AlertCircle className="mt-0.5 size-4 shrink-0" />
                  <span>We couldn&apos;t reach the server. Check your connection and try again.</span>
                </div>
              )}

              <Input
                label="Email or username"
                type="email"
                autoComplete="username"
                required
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                placeholder="you@company.com"
              />

              <div className="relative">
                <Input
                  label="Password"
                  type={showPassword ? 'text' : 'password'}
                  autoComplete="current-password"
                  required
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  placeholder="••••••••"
                  className="pr-10"
                />
                <button
                  type="button"
                  onClick={() => setShowPassword((v) => !v)}
                  aria-label={showPassword ? 'Hide password' : 'Show password'}
                  className="absolute right-3 top-[34px] text-tertiary hover:text-primary"
                >
                  {showPassword ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
                </button>
              </div>

              <div className="flex items-center justify-between text-sm">
                <label className="inline-flex items-center gap-2 text-secondary">
                  <input
                    type="checkbox"
                    checked={rememberMe}
                    onChange={(e) => setRememberMe(e.target.checked)}
                    className="size-4 rounded border-subtle accent-[var(--color-accent)]"
                  />
                  Remember me
                </label>
                <button type="button" onClick={() => setForgotOpen(true)} className="font-medium text-accent hover:underline">
                  Forgot password?
                </button>
              </div>

              <Button type="submit" size="lg" loading={state === 'loading'} className="w-full">
                {state === 'loading' ? 'Signing in…' : 'Sign in'}
              </Button>

              {isUsingMockData && (
                <button
                  type="button"
                  onClick={fillDemoCredentials}
                  className="flex items-center justify-center gap-1.5 text-xs font-medium text-tertiary hover:text-accent"
                >
                  <Sparkles className="size-3.5" /> Use demo credentials
                </button>
              )}

              <div className="relative my-1 flex items-center gap-3">
                <span className="h-px flex-1 bg-subtle" />
                <span className="text-xs text-tertiary">or</span>
                <span className="h-px flex-1 bg-subtle" />
              </div>

              <button
                type="button"
                disabled
                title="Coming with backend integration"
                className="flex h-10 items-center justify-center gap-2 rounded-lg border border-subtle text-sm font-medium text-tertiary opacity-60"
              >
                <ShieldCheck className="size-4" /> Continue with SSO
              </button>
              <p className="text-center text-[11px] text-tertiary">Two-factor authentication and SSO arrive with backend integration.</p>
            </form>
          ) : (
            <ForgotPasswordForm onBack={() => setForgotOpen(false)} />
          )}
        </div>

        <p className="mt-6 text-center text-xs text-tertiary">
          Frontend preview build — authentication is simulated with mock data.
        </p>
      </div>
    </div>
  )
}

function ForgotPasswordForm({ onBack }: { onBack: () => void }) {
  const [email, setEmail] = useState('')
  const [sent, setSent] = useState(false)
  const [loading, setLoading] = useState(false)

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true)
    await new Promise((r) => setTimeout(r, 600))
    setLoading(false)
    setSent(true)
  }

  if (sent) {
    return (
      <div className="flex flex-col items-center gap-3 py-4 text-center">
        <div className="flex size-12 items-center justify-center rounded-full bg-accent/10 text-accent">
          <Lock className="size-5" />
        </div>
        <p className="text-sm font-medium text-primary">Check your inbox</p>
        <p className="text-sm text-tertiary">If an account exists for {email}, we&apos;ve sent password reset instructions.</p>
        <Button variant="secondary" size="sm" onClick={onBack}>
          Back to sign in
        </Button>
      </div>
    )
  }

  return (
    <form onSubmit={handleSubmit} className="flex flex-col gap-4">
      <div>
        <p className="text-sm font-semibold text-primary">Reset your password</p>
        <p className="mt-1 text-sm text-tertiary">Enter your email and we&apos;ll send you reset instructions.</p>
      </div>
      <Input label="Email" type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" />
      <Button type="submit" loading={loading} className="w-full">
        Send reset link
      </Button>
      <button type="button" onClick={onBack} className="text-sm font-medium text-tertiary hover:text-primary">
        Back to sign in
      </button>
    </form>
  )
}
