import React, { useEffect, useState } from "react";
import { usePage } from "@inertiajs/react";
import { useTranslation } from "react-i18next";
import toast from "react-hot-toast";
import { LoaderCircle } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import InputError from "@/components/input-error";
import TextLink from "@/components/text-link";

declare const route: (name: string, params?: Record<string, unknown>) => string;

export interface AuthUserPayload {
  id?: number;
  email?: string;
  name?: string | null;
  pending_purchase?: boolean;
}

interface LoginFormProps {
  onSuccess?: (userData: AuthUserPayload | null) => void;
  canResetPassword?: boolean;
  locale?: string;
  packageId?: number | null;
}

type SharedPageProps = {
  locale?: string;
};

type FieldErrors = Record<string, string>;

const metaCsrfToken = () =>
  (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? "";

const xsrfCookieToken = () => {
  if (typeof document === "undefined") {
    return "";
  }

  const match = document.cookie.match(/(?:^|; )XSRF-TOKEN=([^;]*)/);
  return match ? decodeURIComponent(match[1]) : "";
};

export default function LoginForm({ onSuccess, canResetPassword = true, locale, packageId }: LoginFormProps) {
  const page = usePage<SharedPageProps>();
  const { t } = useTranslation("auth");
  const resolvedLocale = locale ?? page.props.locale ?? "de";

  const loginEndpoint = '/checkout/login';
      
  const [values, setValues] = useState({
    identifier: "",
    password: "",
    remember: false,
  });
  const [errors, setErrors] = useState<FieldErrors>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [hasTriedSubmit, setHasTriedSubmit] = useState(false);
  const [shouldFocusError, setShouldFocusError] = useState(false);

  useEffect(() => {
    if (!hasTriedSubmit) {
      return;
    }

    const collected = Object.values(errors).filter(Boolean);
    if (collected.length > 0) {
      toast.error(collected.join(" \u2022 "));
    }
  }, [errors, hasTriedSubmit]);

  useEffect(() => {
    if (!hasTriedSubmit || !shouldFocusError) {
      return;
    }

    const firstKey = Object.keys(errors).find((key) => Boolean(errors[key]));
    if (!firstKey) {
      return;
    }

    const field = document.querySelector<HTMLInputElement>(`[name="${firstKey}"]`);
    field?.scrollIntoView({ behavior: "smooth", block: "center" });
    field?.focus();
    setShouldFocusError(false);
  }, [errors, hasTriedSubmit, shouldFocusError]);

  const updateValue = (key: keyof typeof values, value: string | boolean) => {
    setValues((current) => ({ ...current, [key]: value }));
    setErrors((current) => ({ ...current, [key as string]: "" }));
    setShouldFocusError(false);
  };

  const submit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setHasTriedSubmit(true);
    setErrors({});
    setIsSubmitting(true);

    try {
      const cookieToken = xsrfCookieToken();
      const metaToken = metaCsrfToken();

      const response = await fetch(loginEndpoint, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
          ...(cookieToken
            ? { "X-XSRF-TOKEN": cookieToken }
            : metaToken
              ? { "X-CSRF-TOKEN": metaToken }
              : {}),
        },
        credentials: "same-origin",
        body: JSON.stringify({
          identifier: values.identifier,
          password: values.password,
          remember: values.remember,
          locale: resolvedLocale,
          package_id: packageId ?? null,
        }),
      });

      if (response.ok) {
        const payload = await response.json();
        const nextUser: AuthUserPayload | null = payload?.user ?? payload?.data ?? null;

        toast.success(t("login.success_toast", "Login erfolgreich"));
        onSuccess?.(nextUser);
        setValues((current) => ({ ...current, password: "" }));
        setHasTriedSubmit(false);
        return;
      }

      if (response.status === 422) {
        const payload = await response.json();
        const fieldErrors: FieldErrors = {};
        const source = payload?.errors ?? {};
        Object.entries(source).forEach(([key, message]) => {
          if (Array.isArray(message) && message.length > 0) {
            fieldErrors[key] = String(message[0]);
          } else if (typeof message === "string") {
            fieldErrors[key] = message;
          }
        });

        setErrors(fieldErrors);
        setShouldFocusError(true);
        toast.error(t("login.failed_generic", "Ungueltige Anmeldedaten"));
        return;
      }

      toast.error(t("login.unexpected_error", "Beim Login ist ein Fehler aufgetreten."));
      setShouldFocusError(false);
    } catch (error) {
      console.error("Login request failed", error);
      toast.error(t("login.unexpected_error", "Beim Login ist ein Fehler aufgetreten."));
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <form onSubmit={submit} className="flex flex-col gap-6" noValidate>
      <div className="grid gap-6">
        <div className="grid gap-2">
          <Label htmlFor="identifier">{t("login.identifier") || t("login.email")}</Label>
          <Input
            id="identifier"
            type="text"
            name="identifier"
            required
            autoFocus
            placeholder={t("login.identifier_placeholder") || t("login.email_placeholder")}
            value={values.identifier}
            onChange={(event) => updateValue("identifier", event.target.value)}
          />
          <InputError message={errors.identifier || errors.email} />
        </div>
  
        <div className="grid gap-2">
          <div className="flex items-center">
            <Label htmlFor="password">{t("login.password")}</Label>
            {canResetPassword && (
              <TextLink href={typeof route === "function" ? route("password.request") : "/forgot-password"} className="ml-auto text-sm">
                {t("login.forgot")}
              </TextLink>
            )}
          </div>
          <Input
            id="password"
            type="password"
            name="password"
            required
            placeholder={t("login.password_placeholder")}
            value={values.password}
            onChange={(event) => updateValue("password", event.target.value)}
          />
          <InputError message={errors.password} />
        </div>
  
        <div className="flex items-center space-x-3">
          <Checkbox
            id="remember"
            name="remember"
            checked={values.remember}
            onCheckedChange={(checked) => updateValue("remember", Boolean(checked))}
          />
          <Label htmlFor="remember">{t("login.remember")}</Label>
        </div>
  
        <Button type="submit" className="w-full" disabled={isSubmitting}>
          {isSubmitting && <LoaderCircle className="h-4 w-4 animate-spin mr-2" />}
          {t("login.submit")}
        </Button>
      </div>

      {Object.values(errors).some(Boolean) && (
        <div className="p-4 bg-red-50 border border-red-200 rounded-md">
          <p className="text-sm text-red-800">{Object.values(errors).filter(Boolean).join(" \u2022 ")}</p>
        </div>
      )}
    </form>
  );
}
