import { Head, useForm, Link, router } from '@inertiajs/react';
import { FormEvent, useEffect, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/input-otp';
import { Lock, ShieldCheck, Eye, EyeOff } from 'lucide-react';
import { toast } from 'sonner';

interface LoginProps {
  canResetPassword: boolean;
  status?: string;
  otpRequired?: boolean;
  otpEmail?: string;
}

export default function Login({ canResetPassword, status, otpRequired, otpEmail }: LoginProps) {
  const [step, setStep] = useState<'login' | 'otp'>(otpRequired ? 'otp' : 'login');
  const [email, setEmail] = useState(otpEmail ?? '');
  const [otp, setOtp] = useState('');
  const [otpLoading, setOtpLoading] = useState(false);
  const [resendIn, setResendIn] = useState(0);
  const [resending, setResending] = useState(false);
  const [showPassword, setShowPassword] = useState(false);

  // Inertia re-renders this page with the OTP flash data after the password POST.
  // useState only honours the initializer on first mount, so sync the step to the prop.
  useEffect(() => {
    if (otpRequired) {
      setStep('otp');
      if (otpEmail) setEmail(otpEmail);
      setResendIn(60);
    }
  }, [otpRequired, otpEmail]);

  // 60-second resend cooldown ticker
  useEffect(() => {
    if (resendIn <= 0) return;
    const t = setTimeout(() => setResendIn((s) => s - 1), 1000);
    return () => clearTimeout(t);
  }, [resendIn]);

  const resendOtp = async () => {
    if (resendIn > 0 || resending) return;
    setResending(true);
    try {
      const csrf = (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? '';
      const res = await fetch('/api/functions/send-admin-otp', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrf, Accept: 'application/json' },
        body: JSON.stringify({ email }),
      });
      if (res.status === 429) {
        toast.error('Too many requests. Please wait a minute and try again.');
        setResendIn(60);
        return;
      }
      const body = await res.json().catch(() => ({}));
      if (!res.ok || body?.error) {
        toast.error(body?.error ?? 'Could not resend code');
      } else {
        toast.success('A new code has been sent');
        setOtp('');
        setResendIn(60);
      }
    } catch {
      toast.error('Network error — please try again');
    } finally {
      setResending(false);
    }
  };

  const { data, setData, post, processing, errors } = useForm({
    email: otpEmail ?? '',
    password: '',
    remember: false,
  });

  const submit = (e: FormEvent) => {
    e.preventDefault();
    post(route('login'));
  };

  const verifyOtp = async (e: FormEvent) => {
    e.preventDefault();
    if (otp.length !== 6) return;
    setOtpLoading(true);

    try {
      const csrf = (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? '';
      const res = await fetch('/api/functions/verify-admin-otp', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrf, Accept: 'application/json' },
        body: JSON.stringify({ email, code: otp }),
      });

      if (res.status === 429) {
        toast.error('Too many verification attempts. Please wait a minute and try again.');
        setOtp('');
        setOtpLoading(false);
        return;
      }

      const body = await res.json().catch(() => ({}));

      if (!res.ok || body?.error) {
        toast.error(body?.error ?? 'Verification failed');
        setOtpLoading(false);
        return;
      }

      toast.success('Access granted');
      router.visit(body.redirect ?? '/admin');
    } catch {
      toast.error('Network error — please try again');
      setOtpLoading(false);
    }
  };

  return (
    <>
      <Head title={step === 'otp' ? 'Admin Verification' : 'Sign In'} />
      <div className="min-h-screen bg-background flex items-center justify-center p-4">
        <div className="w-full max-w-md">
          <div className="bg-card border border-border rounded-xl p-8">
            <div className="flex justify-center mb-4">
              {step === 'otp' ? (
                <ShieldCheck className="h-10 w-10 text-primary" />
              ) : (
                <Lock className="h-10 w-10 text-primary" />
              )}
            </div>
            <h1 className="text-2xl font-bold text-foreground mb-2 text-center">
              {step === 'otp' ? 'Admin Verification' : 'Sign In'}
            </h1>
            <p className="text-muted-foreground text-sm text-center mb-6">
              {step === 'otp'
                ? `Enter the 6-digit code sent to ${email}`
                : 'Sign in with your credentials to continue'}
            </p>

            {status && (
              <div className="mb-4 text-sm text-emerald-500 text-center">{status}</div>
            )}

            {step === 'login' ? (
              <form onSubmit={submit} className="space-y-4">
                <div className="space-y-2">
                  <Label htmlFor="email">Email</Label>
                  <Input
                    id="email"
                    type="email"
                    value={data.email}
                    onChange={(e) => {
                      setData('email', e.target.value);
                      setEmail(e.target.value);
                    }}
                    placeholder="you@example.com"
                    autoComplete="username"
                    required
                  />
                  {errors.email && <p className="text-xs text-destructive">{errors.email}</p>}
                </div>
                <div className="space-y-2">
                  <Label htmlFor="password">Password</Label>
                  <div className="relative">
                    <Input
                      id="password"
                      type={showPassword ? 'text' : 'password'}
                      value={data.password}
                      onChange={(e) => setData('password', e.target.value)}
                      placeholder="••••••••"
                      autoComplete="current-password"
                      required
                      minLength={6}
                      className="pr-10"
                    />
                    <button
                      type="button"
                      onClick={() => setShowPassword((v) => !v)}
                      aria-label={showPassword ? 'Hide password' : 'Show password'}
                      aria-pressed={showPassword}
                      className="absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground focus:outline-none"
                    >
                      {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                    </button>
                  </div>
                  {errors.password && <p className="text-xs text-destructive">{errors.password}</p>}
                </div>
                <Button type="submit" size="lg" className="w-full" disabled={processing}>
                  {processing ? 'Signing in…' : 'Sign In'}
                </Button>
                {canResetPassword && (
                  <div className="text-center">
                    <Link
                      href={route('password.request')}
                      className="text-sm text-muted-foreground hover:text-primary hover:underline"
                    >
                      Forgot password?
                    </Link>
                  </div>
                )}
                <div className="text-center text-sm text-muted-foreground">
                  Don't have an account?{' '}
                  <Link href={route('register')} className="text-primary hover:underline">
                    Register
                  </Link>
                </div>
              </form>
            ) : (
              <form onSubmit={verifyOtp} className="space-y-6">
                <p className="text-xs text-muted-foreground text-center bg-muted/50 rounded-lg p-3">
                  Admin accounts require two-factor authentication. A 6-digit code has been sent to your email.
                </p>
                <div className="flex justify-center">
                  <InputOTP maxLength={6} value={otp} onChange={setOtp}>
                    <InputOTPGroup>
                      <InputOTPSlot index={0} />
                      <InputOTPSlot index={1} />
                      <InputOTPSlot index={2} />
                      <InputOTPSlot index={3} />
                      <InputOTPSlot index={4} />
                      <InputOTPSlot index={5} />
                    </InputOTPGroup>
                  </InputOTP>
                </div>
                <Button
                  type="submit"
                  size="lg"
                  className="w-full"
                  disabled={otpLoading || otp.length !== 6}
                >
                  {otpLoading ? 'Verifying…' : 'Verify & Continue'}
                </Button>

                <div className="text-center text-sm">
                  <span className="text-muted-foreground">Didn't get the code? </span>
                  {resendIn > 0 ? (
                    <span className="text-muted-foreground">
                      Resend available in {resendIn}s
                    </span>
                  ) : (
                    <button
                      type="button"
                      onClick={resendOtp}
                      disabled={resending}
                      className="text-primary hover:underline disabled:opacity-60 disabled:no-underline"
                    >
                      {resending ? 'Sending…' : 'Resend code'}
                    </button>
                  )}
                </div>

                <div className="text-center">
                  <button
                    type="button"
                    onClick={() => {
                      setStep('login');
                      setOtp('');
                    }}
                    className="text-sm text-primary hover:underline"
                  >
                    Back to sign in
                  </button>
                </div>
              </form>
            )}
          </div>
        </div>
      </div>
    </>
  );
}
