'use client';

import { Button } from '@/components/actions/Button';
import { TextInput } from '@/components/forms/TextInput';
import { FormField } from '@/components/forms/FormField';
import { AuthShell } from '@/components/auth/AuthShell';
import { API_BASE, EMPLOYEE_PROFILE_KEY } from '@/lib/api';
import { classNames } from '@/lib/components/classNames';
import { localizedModePath, modeFromPathname, type Locale } from '@/lib/localization/config';
import { usePathname, useSearchParams } from 'next/navigation';
import { useState } from 'react';
import styles from './AuthForms.module.css';

interface Dict {
  title: string;
  subtitle: string;
  email: string;
  emailPlaceholder: string;
  password: string;
  signIn: string;
  signingIn: string;
  verify: string;
  verifying: string;
  authCode: string;
  enterCode: string;
  totpPlaceholder: string;
  back: string;
  forgotPassword: string;
  invalidCredentials: string;
  passwordNotSet: string;
  tooManyRequests: string;
  emailNotVerified: string;
  unexpectedError: string;
}

const dicts: Record<string, Dict> = {
  en: {
    title: 'Sign in',
    subtitle: 'Enter your credentials to access your account.',
    email: 'Email',
    emailPlaceholder: 'owner@company.com',
    password: 'Password',
    signIn: 'Sign in',
    signingIn: 'Signing in…',
    verify: 'Verify code',
    verifying: 'Verifying…',
    authCode: 'Authentication code',
    enterCode: 'Enter the 6-digit code from your authenticator app.',
    totpPlaceholder: '000000 or XXXX-XXXX-XXXX',
    back: 'Back to credentials',
    forgotPassword: 'Forgot your password?',
    invalidCredentials: 'Invalid email or password.',
    passwordNotSet:
      'No password set yet. Check your invitation email or use "Forgot your password?"',
    tooManyRequests: 'Too many attempts. Please try again later.',
    emailNotVerified: 'Please verify your email first. Check your inbox for the verification link.',
    unexpectedError: 'Something went wrong. Please try again.',
  },
  fr: {
    title: 'Connexion',
    subtitle: 'Saisissez vos identifiants pour accéder à votre compte.',
    email: 'Email',
    emailPlaceholder: 'owner@company.com',
    password: 'Mot de passe',
    signIn: 'Connexion',
    signingIn: 'Connexion…',
    verify: 'Vérifier le code',
    verifying: 'Vérification…',
    authCode: "Code d'authentification",
    enterCode: "Entrez le code à 6 chiffres de votre application d'authentification.",
    totpPlaceholder: '000000 ou XXXX-XXXX-XXXX',
    back: 'Retour aux identifiants',
    forgotPassword: 'Mot de passe oublié ?',
    invalidCredentials: 'Adresse e-mail ou mot de passe invalide.',
    passwordNotSet:
      "Aucun mot de passe défini. Vérifiez votre e-mail d'invitation ou utilisez « Mot de passe oublié ? »",
    tooManyRequests: 'Trop de tentatives. Veuillez réessayer plus tard.',
    emailNotVerified: 'Veuillez vérifier votre adresse email. Consultez votre boîte de réception.',
    unexpectedError: 'Une erreur est survenue. Veuillez réessayer.',
  },
  ar: {
    title: 'تسجيل الدخول',
    subtitle: 'أدخل بياناتك للوصول إلى حسابك.',
    email: 'البريد الإلكتروني',
    emailPlaceholder: 'owner@company.com',
    password: 'كلمة المرور',
    signIn: 'تسجيل الدخول',
    signingIn: 'جارٍ تسجيل الدخول…',
    verify: 'تحقق من الرمز',
    verifying: 'جارٍ التحقق…',
    authCode: 'رمز المصادقة',
    enterCode: 'أدخل الرمز المكون من 6 أرقام من تطبيق المصادقة.',
    totpPlaceholder: '000000 أو XXXX-XXXX-XXXX',
    back: 'العودة إلى بيانات الدخول',
    forgotPassword: 'نسيت كلمة المرور؟',
    invalidCredentials: 'البريد الإلكتروني أو كلمة المرور غير صحيحة.',
    passwordNotSet: 'لم يتم تعيين كلمة مرور بعد. تحقق من بريد الدعوة أو استخدم "نسيت كلمة المرور؟"',
    tooManyRequests: 'محاولات كثيرة جدًا. يرجى المحاولة لاحقًا.',
    emailNotVerified: 'يرجى التحقق من بريدك الإلكتروني أولاً. تحقق من صندوق الوارد.',
    unexpectedError: 'حدث خطأ ما. يرجى المحاولة مرة أخرى.',
  },
};

export function SignInForm({ locale }: { locale: Locale }) {
  const dict = (dicts[locale] ?? dicts.en) as Dict;
  const searchParams = useSearchParams();
  const mode = modeFromPathname(usePathname());
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [showPassword, setShowPassword] = useState(false);
  const [totpCode, setTotpCode] = useState('');
  const [step, setStep] = useState<'credentials' | 'totp'>('credentials');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const requestedPortal = searchParams.get('portal');
  const employeeRedirect = searchParams.get('redirect') || '/dashboard';
  const preferAdminAuth = requestedPortal === 'admin';

  async function handleCredentials(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    try {
      const tryAdminLogin = async () => {
        const adminRes = await fetch(`${API_BASE}/admin/auth/login`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ email, password }),
        });
        const adminJson = await adminRes.json();

        if (adminRes.ok && adminJson?.data?.admin) {
          window.location.href = `${window.location.origin}/admin/dashboard`;
          return true;
        }

        if (adminRes.status === 401 && adminJson?.error === 'totp_required') {
          setStep('totp');
          return true;
        }

        if (adminRes.status === 429) {
          setError(dict.tooManyRequests);
          return true;
        }

        return false;
      };

      const tryEmployeeLogin = async () => {
        const empRes = await fetch(`${API_BASE}/auth/employee/login`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ email, password }),
        });
        const empJson = await empRes.json();

        if (empRes.ok && empJson?.data?.employee) {
          if (empJson?.data?.employee) {
            localStorage.setItem(EMPLOYEE_PROFILE_KEY, JSON.stringify(empJson.data.employee));
            const prefLang = empJson.data.employee?.preferredLanguage;
            if (prefLang === 'en' || prefLang === 'fr' || prefLang === 'ar') {
              document.cookie = `rentaldrivego-language=${prefLang}; path=/; max-age=31536000; samesite=lax`;
            }
          }
          window.dispatchEvent(new CustomEvent('rentaldrivego:auth-changed'));
          window.location.replace(employeeRedirect);
          return true;
        }

        if (empJson?.error === 'password_not_set') {
          setError(dict.passwordNotSet);
          return true;
        }

        if (empJson?.error === 'email_not_verified') {
          setError(dict.emailNotVerified);
          return true;
        }

        if (empRes.status === 429) {
          setError(dict.tooManyRequests);
          return true;
        }

        return false;
      };

      if (preferAdminAuth) {
        if (await tryAdminLogin()) return;
        setError(dict.invalidCredentials);
        return;
      }

      if (await tryEmployeeLogin()) return;

      setError(dict.invalidCredentials);
    } catch {
      setError(dict.unexpectedError);
    } finally {
      setLoading(false);
    }
  }

  async function handleTotp(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    try {
      const normalizedCode = totpCode.trim().toUpperCase();
      const secondFactor = /^\d{6}$/.test(normalizedCode)
        ? { totpCode: normalizedCode }
        : { recoveryCode: normalizedCode };

      const adminRes = await fetch(`${API_BASE}/admin/auth/login`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ email, password, ...secondFactor }),
      });
      const adminJson = await adminRes.json();

      if (adminRes.ok && adminJson?.data?.admin) {
        window.location.href = `${window.location.origin}/admin/dashboard`;
        return;
      }

      setError(dict.invalidCredentials);
    } catch {
      setError(dict.unexpectedError);
    } finally {
      setLoading(false);
    }
  }

  const hrefBase = localizedModePath('forgot-password', locale, mode);

  return (
    <AuthShell locale={locale} title={dict.title} subtitle={dict.subtitle}>
      {error ? (
        <div
          className={classNames(styles.error, styles.spacedError)}
        >
          {error}
        </div>
      ) : null}

      {step === 'credentials' ? (
        <form
          onSubmit={handleCredentials}
          className={styles.formStack}
        >
          <FormField id="signin-email" label={dict.email} required>
            <TextInput
              id="signin-email"
              type="email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder={dict.emailPlaceholder}
              autoComplete="email"
            />
          </FormField>

          <FormField id="signin-password" label={dict.password} required>
            <div className={styles.passwordField}>
              <input
                id="signin-password"
                type={showPassword ? 'text' : 'password'}
                required
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                placeholder="••••••••"
                autoComplete="current-password"
                className={styles.passwordInput}
              />
              <button
                type="button"
                onClick={() => setShowPassword((v) => !v)}
                tabIndex={-1}
                className={styles.passwordToggle}
              >
                {showPassword ? (
                  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
                  </svg>
                ) : (
                  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
                    <path strokeLinecap="round" strokeLinejoin="round" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
                  </svg>
                )}
              </button>
            </div>
          </FormField>

          <Button type="submit" intent="primary" fullWidth loading={loading} disabled={loading}>
            {loading ? dict.signingIn : dict.signIn}
          </Button>

          <div className={styles.forgotLinkWrap}>
            <a
              href={hrefBase}
              className={styles.mutedLink}
            >
              {dict.forgotPassword}
            </a>
          </div>
        </form>
      ) : (
        <form
          onSubmit={handleTotp}
          className={styles.formStack}
        >
          <div className={styles.infoBox}>
            {dict.enterCode}
          </div>

          <FormField id="signin-totp" label={dict.authCode} required>
            <TextInput
              id="signin-totp"
              type="text"
              inputMode="text"
              required
              maxLength={14}
              value={totpCode}
              onChange={(e) =>
                setTotpCode(e.target.value.replace(/[^0-9A-Za-z-]/g, '').toUpperCase())
              }
              placeholder={dict.totpPlaceholder}
              className={styles.totpInput}
            />
          </FormField>

          <Button type="submit" intent="primary" fullWidth loading={loading} disabled={loading}>
            {loading ? dict.verifying : dict.verify}
          </Button>

          <button
            type="button"
            onClick={() => {
              setStep('credentials');
              setTotpCode('');
              setError(null);
            }}
            className={styles.plainButton}
          >
            {dict.back}
          </button>
        </form>
      )}
    </AuthShell>
  );
}
