"use client";

import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Field, FieldGroup, 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 } 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);

  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;
      }

      const data = await response.json().catch(() => ({}));
      const profile = data?.profile ?? {};
      let redirectPath = "/";

      if (typeof window !== "undefined") {
        localStorage.setItem("user_name", profile.full_name ?? "");
        localStorage.setItem(
          "user_id",
          profile.user_id ? String(profile.user_id) : ""
        );

        const params = new URLSearchParams(window.location.search);
        const fromParam = params.get("from");
        if (
          fromParam &&
          fromParam.startsWith("/") &&
          !fromParam.startsWith("//") &&
          !fromParam.includes("://")
        ) {
          redirectPath = fromParam;
        }
      }

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

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

        <Field>
          <FieldLabel
            htmlFor="email"
            className={`text-xs font-semibold uppercase tracking-wide text-slate-500 transition-all duration-500 ${
              mounted ? "opacity-100 translate-x-0" : "opacity-0 -translate-x-4"
            }`}
          >
            Email
          </FieldLabel>
          <div 
            className={`relative transition-all duration-500 delay-100 ${
              mounted ? "opacity-100 translate-x-0" : "opacity-0 -translate-x-4"
            }`}
          >
            <Mail className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400 transition-colors duration-200" />
            <Input
              id="email"
              type="email"
              name="email"
              placeholder="m@example.com"
              required
              disabled={loading}
              aria-invalid={Boolean(fieldErrors.email)}
              onInput={() => handleClearFieldError("email")}
              className={cn(
                "pl-10 transition-all duration-200 focus:scale-[1.02]",
                fieldErrors.email && "border-red-300 focus-visible:ring-red-200"
              )}
            />
          </div>
          {fieldErrors.email && (
            <p className="mt-1 text-xs text-red-500 animate-[fadeIn_0.2s_ease-in-out]">
              {fieldErrors.email}
            </p>
          )}
        </Field>

        <Field>
          <div 
            className={`flex items-center transition-all duration-500 delay-200 ${
              mounted ? "opacity-100 translate-x-0" : "opacity-0 -translate-x-4"
            }`}
          >
            <FieldLabel
              htmlFor="password"
              className="text-xs font-semibold uppercase tracking-wide text-slate-500"
            >
              Password
            </FieldLabel>
            <a
              href="/forgot_password"
              className="ml-auto text-sm underline-offset-4 hover:underline transition-colors duration-200"
            >
              Forgot your password?
            </a>
          </div>
          <div 
            className={`relative transition-all duration-500 delay-300 ${
              mounted ? "opacity-100 translate-x-0" : "opacity-0 -translate-x-4"
            }`}
          >
            <Lock className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400 transition-colors duration-200" />
            <Input
              id="password"
              type={showPassword ? "text" : "password"}
              name="password"
              required
              disabled={loading}
              aria-invalid={Boolean(fieldErrors.password)}
              onInput={() => handleClearFieldError("password")}
              className={cn(
                "pr-12 pl-10 transition-all duration-200 focus:scale-[1.02]",
                fieldErrors.password && "border-red-300 focus-visible:ring-red-200"
              )}
            />
            <button
              type="button"
              onClick={() => setShowPassword((value) => !value)}
              aria-label={showPassword ? "Hide password" : "Show password"}
              className="absolute right-3 top-1/2 flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded-lg border border-slate-200 text-slate-500 transition hover:border-slate-300 hover:scale-110"
            >
              {showPassword ? (
                <EyeOff className="h-4 w-4" />
              ) : (
                <Eye className="h-4 w-4" />
              )}
            </button>
          </div>
          {fieldErrors.password && (
            <p className="mt-1 text-xs text-red-500 animate-[fadeIn_0.2s_ease-in-out]">
              {fieldErrors.password}
            </p>
          )}
        </Field>

        <Field>
          <Button
            type="submit"
            disabled={loading}
            className={`w-full rounded-lg px-4 py-3 text-sm font-semibold uppercase tracking-[0.3em] text-white transition-all duration-300 hover:scale-[1.02] hover:shadow-lg disabled:opacity-70 disabled:hover:scale-100 ${
              mounted ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"
            }`}
            style={{
              backgroundColor: PRIMARY_COLOR,
              transitionDelay: mounted ? "400ms" : "0ms",
            }}
            onMouseEnter={(e) => {
              if (!loading) {
                e.currentTarget.style.backgroundColor = "#357a3f";
              }
            }}
            onMouseLeave={(e) => {
              if (!loading) {
                e.currentTarget.style.backgroundColor = PRIMARY_COLOR;
              }
            }}
          >
            {loading ? (
              <span className="flex items-center justify-center gap-2">
                <Loader2 className="h-4 w-4 animate-spin" />
                Signing in...
              </span>
            ) : (
              "Sign in"
            )}
          </Button>
        </Field>
      </FieldGroup>
    </form>
  );
}
