"use client";

import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { AlertMessage } from "@/components/ui/AlertMessage";
import { FormEvent, useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { Eye, EyeOff, Loader2, Mail, Lock } from "lucide-react";
import { validateEmail, validatePassword, clearFieldError } from "@/utils/form-validation";
import { PRIMARY_COLOR, PRIMARY_COLOR_HOVER } from "@/lib/common";

export function LoginForm({
  className,
  ...props
}: React.ComponentProps<"form">) {
  const router = useRouter();
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [fieldErrors, setFieldErrors] = useState<
    Partial<Record<"email" | "password", string>>
  >({});
  const [showPassword, setShowPassword] = useState(false);
  const [mounted, setMounted] = useState(false);
  const [redirectingToAddSubdomain, setRedirectingToAddSubdomain] = useState(false);
  const [verifyingImpersonate, setVerifyingImpersonate] = useState(false);

  // Apex oxyworkspace.com: redirect /login to /signin_step (same as middleware)
  useEffect(() => {
    if (typeof window === "undefined") return;
    const hostname = window.location.hostname ?? "";
    const normalized = hostname.replace(/^www\./i, "");
    if (normalized === "oxyfinz.com") {
      setRedirectingToAddSubdomain(true);
      router.replace("/signin_step");
      return;
    }
  }, [router]);

  // Impersonation: handle #token=<jwt> in URL hash
  useEffect(() => {
    if (typeof window === "undefined") return;
    const hash = window.location.hash;
    if (!hash.startsWith("#token=")) return;

    const token = hash.slice("#token=".length);
    if (!token) return;

    // Clear the hash immediately so the token is no longer in the URL
    window.history.replaceState(null, "", window.location.pathname + window.location.search);

    setVerifyingImpersonate(true);

    fetch("/api/verify-impersonate-token", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ token }),
      credentials: "include",
    })
      .then(async (res) => {
        if (!res.ok) {
          const body = await res.json().catch(() => ({}));
          setErrorMsg(body?.error ?? "Impersonation login failed. The link may have expired.");
          setVerifyingImpersonate(false);
          return;
        }
        router.replace("/dashboard");
        router.refresh();
      })
      .catch(() => {
        setErrorMsg("Unexpected error during impersonation login.");
        setVerifyingImpersonate(false);
      });
  }, [router]);

  useEffect(() => {
    setMounted(true);
  }, []);

  const handleClearFieldError = (field: "email" | "password") => {
    setFieldErrors((prev) => clearFieldError(prev, field));
  };

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setErrorMsg(null);

    const formData = new FormData(event.currentTarget);
    const email = String(formData.get("email") ?? "").trim();
    const password = String(formData.get("password") ?? "").trim();

    const nextFieldErrors: Partial<Record<"email" | "password", string>> = {};

    const emailError = validateEmail(email);
    if (emailError) nextFieldErrors.email = emailError;

    const passwordError = validatePassword(password);
    if (passwordError) nextFieldErrors.password = passwordError;

    if (Object.keys(nextFieldErrors).length > 0) {
      setFieldErrors(nextFieldErrors);
      return;
    }

    setFieldErrors({});
    setLoading(true);

    try {
      const payload = new FormData();
      payload.append("username", email);
      payload.append("password", password);

      const response = await fetch(`/api/login`, {
        method: "POST",
        body: payload,
        credentials: "include",
        headers: { Accept: "application/json" },
      });

      if (!response.ok) {
        if (response.status === 401 || response.status === 403) {
          setErrorMsg("Username and password is incorrect");
          return;
        }

        const contentType = response.headers.get("content-type") ?? "";
        let upstreamMessage: string | null = null;

        if (contentType.includes("application/json")) {
          const body = await response.json().catch(() => null);
          upstreamMessage =
            typeof body?.error === "string"
              ? body.error
              : typeof body?.message === "string"
              ? body.message
              : null;
        } else {
          const text = await response.text().catch(() => "");
          upstreamMessage = text.trim() || null;
        }

        const fallbackMessage =
          response.status >= 500
            ? "Authentication service is unavailable. Please try again later."
            : "Invalid credentials. Please double-check your email and password.";

        setErrorMsg(upstreamMessage || fallbackMessage);
        return;
      }

      await response.json().catch(() => ({}));
      let redirectPath = "/dashboard";

      if (typeof window !== "undefined") {
        const params = new URLSearchParams(window.location.search);
        const fromParam = params.get("from");
        if (fromParam) {
          try {
            // Resolve against current origin and verify it stays on the same origin.
            // This rejects //evil.com, /\evil.com, javascript:, data:, and any
            // URL-encoded variants that browsers would normalize to an external host.
            const resolved = new URL(fromParam, window.location.origin);
            if (resolved.origin === window.location.origin) {
              redirectPath = fromParam;
            }
          } catch {
            // Malformed URL — keep default /dashboard redirect
          }
        }
      }

      router.replace(redirectPath);
      router.refresh();
    } catch (err: any) {
      console.error("Unexpected error:", err);
      setErrorMsg("Unexpected error connecting to server.");
    } finally {
      setLoading(false);
    }
  }

  if (redirectingToAddSubdomain || verifyingImpersonate) {
    return (
      <div className="flex flex-col items-center justify-center gap-4 py-8">
        <Loader2 className="h-8 w-8 animate-spin text-slate-400" />
        <p className="text-sm text-slate-500">
          {verifyingImpersonate ? "Signing in…" : "Redirecting..."}
        </p>
      </div>
    );
  }

  return (
    <form
      className={cn("flex flex-col gap-4", className)}
      {...props}
      noValidate
      onSubmit={handleSubmit}
    >
      {errorMsg && (
        <AlertMessage
          type="error"
          message={errorMsg}
          onDismiss={() => setErrorMsg(null)}
          className="animate-[fadeIn_0.3s_ease-in-out,slideDown_0.3s_ease-in-out]"
        />
      )}

      {/* Fields grouped in a subtle container */}
      <div
        className={`overflow-hidden rounded-xl border border-slate-100 bg-slate-50/60 transition-all duration-500 delay-100 ${
          mounted ? "opacity-100 translate-y-0" : "opacity-0 translate-y-3"
        }`}
      >
        {/* Email field */}
        <div className="px-3.5 pt-3.5 pb-3">
          <Field>
            <FieldLabel
              htmlFor="email"
              className="mb-1.5 block text-[10px] font-semibold uppercase tracking-widest text-slate-400"
            >
              Email
            </FieldLabel>
            <div className="group relative">
              <Mail className="absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400 transition-colors duration-200 group-focus-within:text-[#428B4D]" />
              <Input
                id="email"
                type="email"
                name="email"
                placeholder="you@example.com"
                required
                disabled={loading}
                aria-invalid={Boolean(fieldErrors.email)}
                onInput={() => handleClearFieldError("email")}
                className={cn(
                  "pl-9 h-9 rounded-lg border-slate-200 bg-white/80 text-sm placeholder:text-slate-400",
                  "shadow-sm transition-all duration-200",
                  "focus-visible:bg-white focus-visible:ring-2 focus-visible:ring-[#428B4D]/20 focus-visible:shadow-none",
                  fieldErrors.email && "border-red-300 bg-red-50/40 focus-visible:ring-red-200 focus-visible:border-red-400"
                )}
              />
            </div>
            {fieldErrors.email && (
              <p className="mt-1.5 flex items-center gap-1.5 text-[10px] text-red-500 animate-[fadeIn_0.2s_ease-in-out]">
                <span className="inline-block h-1 w-1 rounded-full bg-red-400 flex-shrink-0" />
                {fieldErrors.email}
              </p>
            )}
          </Field>
        </div>

        {/* Hairline divider */}
        <div className="mx-3.5 h-px bg-slate-100" />

        {/* Password field */}
        <div className="px-3.5 pt-3 pb-3.5">
          <Field>
            <div className="mb-1.5 flex items-center">
              <FieldLabel
                htmlFor="password"
                className="text-[10px] font-semibold uppercase tracking-widest text-slate-400"
              >
                Password
              </FieldLabel>
              <a
                href="/forgot_password"
                className="ml-auto text-[10px] font-semibold text-[#428B4D] underline-offset-4 hover:underline transition-colors duration-200"
              >
                Forgot?
              </a>
            </div>
            <div className="group relative">
              <Lock className="absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400 transition-colors duration-200 group-focus-within:text-[#428B4D]" />
              <Input
                id="password"
                type={showPassword ? "text" : "password"}
                name="password"
                required
                disabled={loading}
                aria-invalid={Boolean(fieldErrors.password)}
                onInput={() => handleClearFieldError("password")}
                className={cn(
                  "pr-11 pl-9 h-9 rounded-lg border-slate-200 bg-white/80 text-sm",
                  "shadow-sm transition-all duration-200",
                  "focus-visible:bg-white focus-visible:ring-2 focus-visible:ring-[#428B4D]/20 focus-visible:shadow-none",
                  fieldErrors.password && "border-red-300 bg-red-50/40 focus-visible:ring-red-200 focus-visible:border-red-400"
                )}
              />
              <button
                type="button"
                onClick={() => setShowPassword((v) => !v)}
                aria-label={showPassword ? "Hide password" : "Show password"}
                className="absolute right-2.5 top-1/2 flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded text-slate-400 transition-all duration-200 hover:text-[#428B4D] hover:scale-110 active:scale-95"
              >
                {showPassword ? <EyeOff className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />}
              </button>
            </div>
            {fieldErrors.password && (
              <p className="mt-1.5 flex items-center gap-1.5 text-[10px] text-red-500 animate-[fadeIn_0.2s_ease-in-out]">
                <span className="inline-block h-1 w-1 rounded-full bg-red-400 flex-shrink-0" />
                {fieldErrors.password}
              </p>
            )}
          </Field>
        </div>
      </div>

      {/* Submit button */}
      <div
        className={`transition-all duration-500 delay-200 ${
          mounted ? "opacity-100 translate-y-0" : "opacity-0 translate-y-3"
        }`}
      >
        <Button
          type="submit"
          disabled={loading}
          className={cn(
            "relative w-full overflow-hidden rounded-xl h-9 text-xs font-bold uppercase tracking-[0.3em] text-white",
            "transition-all duration-300 hover:scale-[1.015] hover:brightness-110 active:scale-[0.99]",
            "disabled:opacity-60 disabled:hover:scale-100 disabled:hover:brightness-100 disabled:cursor-not-allowed",
          )}
          style={{
            background: `linear-gradient(135deg, ${PRIMARY_COLOR} 0%, ${PRIMARY_COLOR_HOVER} 100%)`,
            boxShadow: "0 4px 18px -2px rgba(66,139,77,0.40)",
          }}
        >
          {/* Shimmer sweep on hover */}
          {!loading && (
            <span
              className="pointer-events-none absolute inset-0 -translate-x-full skew-x-[-12deg] bg-white/20"
              style={{ animation: "shimmer 2.4s ease-in-out infinite" }}
              aria-hidden
            />
          )}
          {loading ? (
            <span className="relative flex items-center justify-center gap-2">
              <Loader2 className="h-3.5 w-3.5 animate-spin" />
              Signing in…
            </span>
          ) : (
            <span className="relative">Sign in</span>
          )}
        </Button>
      </div>
    </form>
  );
}
