"use client";

import Image from "next/image";
import Link from "next/link";
import { useEffect, useRef, useState } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useDashboardI18n } from "@/components/I18nProvider";
import PublicShell from "@/components/layout/PublicShell";
import { adminUrl, websiteUrl } from "@/lib/urls";
import { EMPLOYEE_PROFILE_KEY, resolveApiBase } from "@/lib/api";
import { toPublicDashboardPath } from "@/lib/dashboardPaths";

const DASHBOARD_LOGO_SRC = "/dashboard/rentaldrivego.png";

function notifyParent(message: Record<string, unknown>) {
  if (typeof window === "undefined" || window.parent === window) return;
  window.parent.postMessage(message, "*");
}

export default function SignInPageClient({
  embedded = false,
}: {
  embedded?: boolean;
}) {
  const { language, theme, setLanguage, setTheme } = useDashboardI18n();
  const pathname = usePathname();
  const router = useRouter();
  const searchParams = useSearchParams();
  const requestedLanguage = searchParams.get("lang");
  const requestedTheme = searchParams.get("theme");
  const initializedFromQuery = useRef(false);
  const dict = {
    en: {
      brandName: "RentalDriveGo",
      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.",
      resendVerification: "Resend verification email",
      resendingVerification: "Sending…",
      verificationResent:
        "If that email is registered and not yet verified, a new verification link has been sent.",
      unexpectedError: "Something went wrong. Please try again.",
    },
    fr: {
      brandName: "RentalDriveGo",
      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.",
      resendVerification: "Renvoyer l'e-mail de vérification",
      resendingVerification: "Envoi…",
      verificationResent:
        "Si cette adresse existe et n'est pas encore vérifiée, un nouveau lien a été envoyé.",
      unexpectedError: "Une erreur est survenue. Veuillez réessayer.",
    },
    ar: {
      brandName: "RentalDriveGo",
      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:
        "يرجى التحقق من بريدك الإلكتروني أولاً. تحقق من صندوق الوارد.",
      resendVerification: "إعادة إرسال رسالة التحقق",
      resendingVerification: "جارٍ الإرسال…",
      verificationResent:
        "إذا كان هذا البريد مسجلاً ولم يتم التحقق منه بعد، فقد تم إرسال رابط جديد.",
      unexpectedError: "حدث خطأ ما. يرجى المحاولة مرة أخرى.",
    },
  }[language];

  useEffect(() => {
    if (initializedFromQuery.current) return;

    if (
      (requestedLanguage === "en" ||
        requestedLanguage === "fr" ||
        requestedLanguage === "ar") &&
      requestedLanguage !== language
    ) {
      setLanguage(requestedLanguage);
    }

    if (
      (requestedTheme === "light" || requestedTheme === "dark") &&
      requestedTheme !== theme
    ) {
      setTheme(requestedTheme);
    }

    initializedFromQuery.current = true;
  }, [
    language,
    requestedLanguage,
    requestedTheme,
    setLanguage,
    setTheme,
    theme,
  ]);

  useEffect(() => {
    if (!initializedFromQuery.current) return;

    const params = new URLSearchParams(searchParams.toString());
    let changed = false;

    if (params.get("lang") !== language) {
      params.set("lang", language);
      changed = true;
    }

    if (params.get("theme") !== theme) {
      params.set("theme", theme);
      changed = true;
    }

    // useSearchParams() can return empty params during hydration without a Suspense boundary.
    // Always preserve embedded=1 when the component was server-rendered as embedded so
    // the router.replace doesn't strip it and trigger an unintended redirect.
    if (embedded && params.get("embedded") !== "1") {
      params.set("embedded", "1");
      changed = true;
    }

    if (!changed) return;

    const nextQuery = params.toString();
    router.replace(nextQuery ? `${pathname}?${nextQuery}` : pathname, {
      scroll: false,
    });
  }, [embedded, language, pathname, router, searchParams, theme]);

  useEffect(() => {
    const currentPath =
      window.location.pathname + (window.location.search || "");
    notifyParent({ type: "rentaldrivego:embedded-path", path: currentPath });
  }, [pathname, searchParams]);

  return (
    <PublicShell embedded={embedded} hideFooter hideHeaderActions>
      <main className="flex flex-1 items-center justify-center px-4 py-12">
        <div className="w-full max-w-md">
          <div className="mb-8 text-center">
            <div className="flex justify-center">
              <a href={websiteUrl} target="_top">
                <Image
                  src={DASHBOARD_LOGO_SRC}
                  alt="RentalDriveGo"
                  width={104}
                  height={104}
                  unoptimized
                  className="h-24 w-24 rounded-[1.75rem] border border-stone-200/80 bg-white/85 p-1.5 shadow-sm transition-colors dark:border-blue-800 dark:bg-blue-950/80"
                />
              </a>
            </div>
            <p className="mt-2 text-sm text-stone-600 dark:text-stone-300">
              {dict.subtitle}
            </p>
            <div className="mt-4 flex items-center justify-center gap-2">
              {(["en", "fr", "ar"] as const).map((lang) => (
                <button
                  key={lang}
                  type="button"
                  onClick={() => setLanguage(lang)}
                  className={`rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wider transition-colors text-orange-700 dark:text-orange-300 ${
                    language === lang
                      ? "ring-1 ring-current opacity-100"
                      : "opacity-45 hover:opacity-80"
                  }`}
                >
                  {lang}
                </button>
              ))}
            </div>
          </div>

          <section className="rounded-[2rem] border border-stone-200/80 bg-white/82 p-8 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:border-blue-900 dark:bg-blue-950/78 dark:shadow-[0_30px_80px_rgba(0,0,0,0.26)]">
            <LocalSignInForm dict={dict} />
          </section>
        </div>
      </main>
    </PublicShell>
  );
}

function LocalSignInForm({
  dict,
}: {
  dict: {
    email: string;
    password: string;
    signIn: string;
    signingIn: string;
    verify: string;
    verifying: string;
    authCode: string;
    enterCode: string;
    back: string;
    forgotPassword: string;
    invalidCredentials: string;
    passwordNotSet: string;
    tooManyRequests: string;
    emailPlaceholder: string;
    totpPlaceholder: string;
    emailNotVerified: string;
    resendVerification: string;
    resendingVerification: string;
    verificationResent: string;
    unexpectedError: string;
  };
}) {
  const searchParams = useSearchParams();
  const { setLanguage } = useDashboardI18n();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [totpCode, setTotpCode] = useState("");
  const [step, setStep] = useState<"credentials" | "totp">("credentials");
  const [showPassword, setShowPassword] = useState(false);
  const [loading, setLoading] = useState(false);
  const [resendingVerification, setResendingVerification] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [canResendVerification, setCanResendVerification] = useState(false);
  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);
    setCanResendVerification(false);

    try {
      const apiBase = resolveApiBase();

      const tryAdminLogin = async () => {
        const adminRes = await fetch(`${apiBase}/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 = `${adminUrl}/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(`${apiBase}/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) {
          const targetPath = toPublicDashboardPath(employeeRedirect);
          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") {
              setLanguage(prefLang);
              document.cookie = `rentaldrivego-language=${prefLang}; path=/; max-age=31536000; samesite=lax`;
            }
          }
          window.dispatchEvent(new CustomEvent("rentaldrivego:auth-changed"));
          notifyParent({
            type: "rentaldrivego:employee-login",
            path: targetPath,
          });
          // Use a document navigation here so the authenticated dashboard bootstraps
          // from a fresh request after the token cookie and localStorage are set.
          window.location.replace(targetPath);
          return true;
        }

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

        if (empJson?.error === "email_not_verified") {
          setError(dict.emailNotVerified);
          setCanResendVerification(true);
          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 handleResendVerification() {
    setResendingVerification(true);
    setError(null);

    try {
      const res = await fetch(`${resolveApiBase()}/auth/employee/resend-verification`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ email }),
      });

      if (!res.ok) throw new Error(`HTTP ${res.status}`);

      setCanResendVerification(false);
      setError(dict.verificationResent);
    } catch {
      setError(dict.unexpectedError);
      setCanResendVerification(true);
    } finally {
      setResendingVerification(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(`${resolveApiBase()}/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 = `${adminUrl}/dashboard`;
        return;
      }

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

  return (
    <>
      {error ? (
        <div className="mb-5 rounded-[1.5rem] border border-red-200/80 bg-red-50/90 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-300">
          <div>{error}</div>
          {canResendVerification ? (
            <button
              type="button"
              onClick={handleResendVerification}
              disabled={resendingVerification}
              className="mt-3 text-sm font-semibold underline decoration-red-300 underline-offset-4 disabled:cursor-not-allowed disabled:opacity-60 dark:decoration-red-700"
            >
              {resendingVerification ? dict.resendingVerification : dict.resendVerification}
            </button>
          ) : null}
        </div>
      ) : null}

      {step === "credentials" ? (
        <form onSubmit={handleCredentials} className="space-y-5">
          <div>
            <label className="mb-1.5 block text-sm font-medium text-stone-700 dark:text-stone-200">
              {dict.email}
            </label>
            <input
              type="email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder={dict.emailPlaceholder}
              className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-blue-950/80 dark:text-stone-100 dark:placeholder:text-stone-500"
            />
          </div>

          <div>
            <label className="mb-1.5 block text-sm font-medium text-stone-700 dark:text-stone-200">
              {dict.password}
            </label>
            <div className="relative">
              <input
                type={showPassword ? "text" : "password"}
                required
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                placeholder="••••••••"
                className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 pr-10 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-blue-950/80 dark:text-stone-100 dark:placeholder:text-stone-500"
              />
              <button
                type="button"
                onClick={() => setShowPassword((v) => !v)}
                className="absolute inset-y-0 right-3 flex items-center text-stone-400 hover:text-stone-700 dark:text-stone-500 dark:hover:text-stone-200"
                tabIndex={-1}
              >
                {showPassword ? (
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    className="h-5 w-5"
                    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"
                    className="h-5 w-5"
                    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>
          </div>

          <button
            type="submit"
            disabled={loading}
            className="inline-flex w-full justify-center rounded-full bg-orange-600 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 disabled:cursor-not-allowed disabled:opacity-60 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
          >
            {loading ? dict.signingIn : dict.signIn}
          </button>

          <div className="text-center">
            <Link
              href="/forgot-password"
              className="text-sm text-stone-500 underline decoration-stone-300 underline-offset-4 hover:text-stone-900 dark:text-stone-400 dark:decoration-stone-600 dark:hover:text-stone-100"
            >
              {dict.forgotPassword}
            </Link>
          </div>
        </form>
      ) : (
        <form onSubmit={handleTotp} className="space-y-5">
          <div className="rounded-[1.5rem] border border-stone-200/80 bg-stone-50/90 px-4 py-4 text-center text-sm text-stone-600 dark:border-blue-800 dark:bg-blue-950/50 dark:text-stone-300">
            {dict.enterCode}
          </div>

          <div>
            <label className="mb-1.5 block text-sm font-medium text-stone-700 dark:text-stone-200">
              {dict.authCode}
            </label>
            <input
              type="text"
              inputMode="text"
              pattern="[0-9A-Za-z-]{6,14}"
              maxLength={14}
              required
              value={totpCode}
              onChange={(e) =>
                setTotpCode(
                  e.target.value.replace(/[^0-9A-Za-z-]/g, "").toUpperCase(),
                )
              }
              placeholder={dict.totpPlaceholder}
              className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-center text-xl tracking-[0.45em] text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-blue-950/80 dark:text-stone-100 dark:placeholder:text-stone-500"
            />
          </div>

          <button
            type="submit"
            disabled={loading}
            className="inline-flex w-full justify-center rounded-full bg-orange-600 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 disabled:cursor-not-allowed disabled:opacity-60 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
          >
            {loading ? dict.verifying : dict.verify}
          </button>

          <button
            type="button"
            onClick={() => {
              setStep("credentials");
              setTotpCode("");
              setError(null);
            }}
            className="w-full text-sm text-stone-500 hover:text-stone-900 dark:text-stone-400 dark:hover:text-stone-100"
          >
            {dict.back}
          </button>
        </form>
      )}
    </>
  );
}
