import { useState, useRef, useEffect, type KeyboardEvent } from 'react';
import { Lock, LoaderCircle, ArrowRight, ArrowLeft, Shield, Check } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';

const LOGIN_STORAGE_KEY = 'bloby_login_totp';

interface Props {
  onLogin: (token: string) => void;
  totpEnabled?: boolean;
}

export default function LoginScreen({ onLogin, totpEnabled }: Props) {
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);

  // TOTP state
  const [phase, setPhase] = useState<'password' | 'totp'>('password');
  const [totpCode, setTotpCode] = useState('');
  const [pendingToken, setPendingToken] = useState('');
  const [trustDevice, setTrustDevice] = useState(true);
  const [useRecovery, setUseRecovery] = useState(false);
  const totpInputRef = useRef<HTMLInputElement>(null);

  // Restore TOTP phase after page reload (mobile: OS suspends PWA on app-switch)
  useEffect(() => {
    try {
      const raw = sessionStorage.getItem(LOGIN_STORAGE_KEY);
      if (!raw) return;
      const saved = JSON.parse(raw);
      if (saved.pendingToken && saved.expiresAt > Date.now()) {
        setPendingToken(saved.pendingToken);
        setPhase('totp');
      } else {
        sessionStorage.removeItem(LOGIN_STORAGE_KEY);
      }
    } catch {}
  }, []);

  // Auto-focus TOTP input when switching to TOTP phase
  useEffect(() => {
    if (phase === 'totp') {
      setTimeout(() => totpInputRef.current?.focus(), 100);
    }
  }, [phase]);

  function saveLoginState(token: string) {
    try {
      // Pending token has 5min server expiry — save with matching client expiry
      sessionStorage.setItem(LOGIN_STORAGE_KEY, JSON.stringify({
        pendingToken: token,
        expiresAt: Date.now() + 4.5 * 60 * 1000,
      }));
    } catch {}
  }

  function clearLoginState() {
    try { sessionStorage.removeItem(LOGIN_STORAGE_KEY); } catch {}
  }

  const handleSubmit = async () => {
    if (!password.trim() || loading) return;
    setLoading(true);
    setError('');

    try {
      const credentials = btoa(`admin:${password}`);
      const res = await fetch('/api/portal/login', {
        headers: { 'Authorization': `Basic ${credentials}` },
        credentials: 'include',
      });
      const data = await res.json();

      if (res.ok && data.token) {
        clearLoginState();
        onLogin(data.token);
      } else if (res.ok && data.requiresTOTP) {
        setPendingToken(data.pendingToken);
        saveLoginState(data.pendingToken);
        setPhase('totp');
        setError('');
      } else {
        setError(data.error || 'Invalid password');
      }
    } catch {
      setError('Could not reach server');
    } finally {
      setLoading(false);
    }
  };

  const handleTotpSubmit = async () => {
    if (!totpCode.trim() || loading) return;
    setLoading(true);
    setError('');

    try {
      const res = await fetch(
        `/api/portal/login/totp?pending=${encodeURIComponent(pendingToken)}&code=${encodeURIComponent(totpCode)}&trust=${trustDevice ? '1' : '0'}`,
        { credentials: 'include' },
      );
      const data = await res.json();

      if (res.ok && data.token) {
        clearLoginState();
        onLogin(data.token);
      } else {
        setError(data.error || 'Invalid code');
      }
    } catch {
      setError('Could not reach server');
    } finally {
      setLoading(false);
    }
  };

  const handleKeyDown = (e: KeyboardEvent) => {
    if (e.key === 'Enter') {
      if (phase === 'password') handleSubmit();
      else handleTotpSubmit();
    }
  };

  const handleBackToPassword = () => {
    setPhase('password');
    setError('');
    setTotpCode('');
    setUseRecovery(false);
    clearLoginState();
  };

  const inputCls = 'w-full bg-white/[0.05] border border-white/[0.08] text-white rounded-xl px-4 py-3 text-base outline-none input-glow placeholder:text-white/20 transition-all';

  return (
    <div className="flex flex-col items-center justify-center h-dvh px-6">
      <div className="w-full max-w-[320px] flex flex-col items-center">
        <AnimatePresence mode="wait">
          {phase === 'password' ? (
            <motion.div
              key="password"
              initial={{ opacity: 0, x: -20 }}
              animate={{ opacity: 1, x: 0 }}
              exit={{ opacity: 0, x: -20 }}
              transition={{ duration: 0.2 }}
              className="w-full flex flex-col items-center"
            >
              <div className="w-14 h-14 rounded-2xl bg-white/[0.04] border border-white/[0.08] flex items-center justify-center mb-5">
                <Lock className="h-6 w-6 text-white/40" />
              </div>

              <h1 className="text-xl font-bold text-white tracking-tight mb-1">
                Welcome back
              </h1>
              <p className="text-white/40 text-[13px] mb-6">
                Enter your password to continue.
              </p>

              {error && (
                <div className="w-full bg-red-500/8 border border-red-500/15 rounded-xl px-4 py-2.5 mb-4">
                  <p className="text-red-400/90 text-[12px]">{error}</p>
                </div>
              )}

              <input
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="Password"
                autoFocus
                autoComplete="current-password"
                className={inputCls}
              />

              <button
                onClick={handleSubmit}
                disabled={!password.trim() || loading}
                className="w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40"
              >
                {loading ? (
                  <><LoaderCircle className="h-4 w-4 animate-spin" />Signing in...</>
                ) : (
                  <>Sign In<ArrowRight className="h-4 w-4" /></>
                )}
              </button>
            </motion.div>
          ) : (
            <motion.div
              key="totp"
              initial={{ opacity: 0, x: 20 }}
              animate={{ opacity: 1, x: 0 }}
              exit={{ opacity: 0, x: 20 }}
              transition={{ duration: 0.2 }}
              className="w-full flex flex-col items-center"
            >
              <div className="w-14 h-14 rounded-2xl bg-[#0069FE]/10 border border-[#0069FE]/20 flex items-center justify-center mb-5">
                <Shield className="h-6 w-6 text-[#0069FE]" />
              </div>

              <h1 className="text-xl font-bold text-white tracking-tight mb-1">
                {useRecovery ? 'Recovery code' : 'Enter your 2FA code'}
              </h1>
              <p className="text-white/40 text-[13px] mb-6">
                {useRecovery
                  ? 'Enter one of your recovery codes.'
                  : 'Open your authenticator app and enter the 6-digit code.'}
              </p>

              {error && (
                <div className="w-full bg-red-500/8 border border-red-500/15 rounded-xl px-4 py-2.5 mb-4">
                  <p className="text-red-400/90 text-[12px]">{error}</p>
                </div>
              )}

              <input
                ref={totpInputRef}
                type="text"
                inputMode={useRecovery ? 'text' : 'numeric'}
                autoComplete="one-time-code"
                maxLength={useRecovery ? 20 : 6}
                value={totpCode}
                onChange={(e) => {
                  setTotpCode(useRecovery ? e.target.value : e.target.value.replace(/\D/g, ''));
                  setError('');
                }}
                onKeyDown={handleKeyDown}
                placeholder={useRecovery ? 'Recovery code' : '000000'}
                autoFocus
                className={inputCls + (useRecovery ? '' : ' tracking-[0.3em] text-center font-mono')}
              />

              {/* Trust device checkbox */}
              <label className="flex items-center gap-2.5 mt-4 w-full cursor-pointer">
                <div
                  onClick={() => setTrustDevice(v => !v)}
                  className={`w-5 h-5 rounded-md border flex items-center justify-center transition-all ${
                    trustDevice
                      ? 'bg-[#0069FE] border-[#0069FE]'
                      : 'bg-white/[0.04] border-white/[0.12]'
                  }`}
                >
                  {trustDevice && <Check className="h-3.5 w-3.5 text-white" />}
                </div>
                <span className="text-[13px] text-white/50">Trust this device for 90 days</span>
              </label>

              <button
                onClick={handleTotpSubmit}
                disabled={!totpCode.trim() || loading}
                className="w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40"
              >
                {loading ? (
                  <><LoaderCircle className="h-4 w-4 animate-spin" />Verifying...</>
                ) : (
                  <>Verify<ArrowRight className="h-4 w-4" /></>
                )}
              </button>

              <div className="flex items-center gap-4 mt-4">
                <button
                  onClick={handleBackToPassword}
                  className="text-[12px] text-white/30 hover:text-white/50 flex items-center gap-1 transition-colors"
                >
                  <ArrowLeft className="h-3 w-3" />
                  Back
                </button>
                <button
                  onClick={() => { setUseRecovery(v => !v); setTotpCode(''); setError(''); }}
                  className="text-[12px] text-white/30 hover:text-white/50 transition-colors"
                >
                  {useRecovery ? 'Use authenticator code' : 'Use a recovery code'}
                </button>
              </div>
            </motion.div>
          )}
        </AnimatePresence>
      </div>
    </div>
  );
}
