"use client";

import type { FormEvent } from "react";
import { useMemo, useState } from "react";

import { useSearchParams } from "next/navigation";
import { ArrowRight, Eye, EyeOff, LockKeyhole, Mail, ShieldCheck, type LucideIcon } from "lucide-react";
import { toast } from "sonner";

import { ErrorBanner } from "@/components/shared/error-banner";
import { AppPoweredByFooter } from "@/components/layout/app-powered-by-footer";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import type { AuthAudience } from "@/lib/frontend-auth/constants";

type LoginFeature = {
  icon: LucideIcon;
  label: string;
};

type LoginPageShellProps = {
  brandIcon: LucideIcon;
  brandTitle: string;
  brandSubtitle: string;
  badgeLabel: string;
  headline: string;
  description: string;
  features: LoginFeature[];
  cardTitle: string;
  cardDescription: string;
  emailPlaceholder: string;
  protectedText: string;
  redirectTo: string;
  authEndpoint?: string;
  forgotPasswordEndpoint?: string | null;
  audience?: AuthAudience;
  gridClassName?: string;
  backgroundClassName?: string;
  emailId?: string;
  passwordId?: string;
};

export function LoginPageShell({
  brandIcon: BrandIcon,
  brandTitle,
  brandSubtitle,
  badgeLabel,
  headline,
  description,
  features,
  cardTitle,
  cardDescription,
  emailPlaceholder,
  protectedText,
  redirectTo,
  authEndpoint = "/guest/index",
  forgotPasswordEndpoint = null,
  audience = "backend",
  gridClassName,
  backgroundClassName,
  emailId = "email",
  passwordId = "password",
}: LoginPageShellProps) {
  const searchParams = useSearchParams();
  const destination = useMemo(() => {
    const requestedRedirect = searchParams.get("redirect");
    if (
      requestedRedirect &&
      requestedRedirect.startsWith("/") &&
      !requestedRedirect.startsWith("//")
    ) {
      return requestedRedirect;
    }

    return redirectTo;
  }, [redirectTo, searchParams]);
  const [showPassword, setShowPassword] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isResettingPassword, setIsResettingPassword] = useState(false);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);

  async function handleForgotPassword(email: string) {
    if (!forgotPasswordEndpoint) {
      toast.message("Password reset is not available here. Contact your administrator.");
      return;
    }

    const trimmed = email.trim();
    if (!trimmed) {
      toast.error("Enter your email address first.");
      return;
    }

    setIsResettingPassword(true);
    try {
      const response = await fetch(forgotPasswordEndpoint, {
        method: "POST",
        credentials: "same-origin",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({ email: trimmed }),
      });
      const data = (await response.json().catch(() => null)) as {
        status?: string;
        message?: string;
      } | null;

      if (!response.ok || data?.status !== "success") {
        throw new Error(data?.message ?? "Could not send password reset email.");
      }

      toast.success(data.message ?? "Please check your email address.");
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "Could not send password reset email.";
      toast.error(message);
    } finally {
      setIsResettingPassword(false);
    }
  }

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

    const formData = new FormData(event.currentTarget);
    const email = String(formData.get("email") ?? "");
    const password = String(formData.get("password") ?? "");
    const rememberMe = formData.get("remember_me") === "on" || formData.get("remember_me") === "true";

    try {
      const usesUnifiedAuth = authEndpoint === "/guest/index" || authEndpoint.includes("/guest/index");
      const response = await fetch(authEndpoint, {
        method: "POST",
        credentials: "same-origin",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify(
          usesUnifiedAuth
            ? { email, password, audience, remember_me: rememberMe }
            : { email, password, remember_me: rememberMe },
        ),
      });

      const data = (await response.json().catch(() => null)) as {
        status?: string;
        message?: string;
      } | null;

      if (!response.ok || data?.status !== "success") {
        throw new Error(data?.message ?? "Login failed. Please check your credentials.");
      }

      toast.success(data.message ?? "Logged in successfully");
      window.location.assign(destination);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Login failed. Please try again.";
      setErrorMessage(message);
      toast.error(message);
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <main className="relative flex min-h-screen flex-col overflow-hidden bg-[#f7f8fb] text-foreground dark:bg-background">
      <div
        className={cn(
          "absolute inset-0 bg-[radial-gradient(circle_at_18%_18%,rgba(59,130,246,0.16),transparent_28%),radial-gradient(circle_at_86%_22%,rgba(15,23,42,0.10),transparent_30%),linear-gradient(135deg,rgba(255,255,255,0.92),rgba(241,245,249,0.8))] dark:bg-[radial-gradient(circle_at_18%_18%,rgba(59,130,246,0.22),transparent_28%),radial-gradient(circle_at_86%_22%,rgba(255,255,255,0.08),transparent_30%),linear-gradient(135deg,rgba(255,255,255,0.05),rgba(255,255,255,0.01))]",
          backgroundClassName,
        )}
      />
      <div className="absolute top-20 left-1/2 h-72 w-72 -translate-x-1/2 rounded-full bg-primary/10 blur-3xl dark:bg-primary/15" />

      <div
        className={cn(
          "relative mx-auto grid w-full max-w-7xl flex-1 items-center gap-10 px-6 py-10 lg:grid-cols-[1.08fr_0.92fr] lg:px-10",
          gridClassName,
        )}
      >
        <section className="space-y-10">
          <div className="flex items-center gap-3">
            <div className="flex size-12 items-center justify-center rounded-2xl bg-foreground text-background shadow-lg shadow-foreground/10">
              <BrandIcon className="size-5" />
            </div>
            <div>
              <p className="font-semibold text-lg leading-tight" suppressHydrationWarning>
                {brandTitle}
              </p>
              <p className="text-muted-foreground text-sm" suppressHydrationWarning>
                {brandSubtitle}
              </p>
            </div>
          </div>

          <div className="max-w-2xl space-y-6">
            <div className="inline-flex items-center gap-2 rounded-full border bg-background/70 px-3 py-1 font-medium text-muted-foreground text-xs shadow-sm backdrop-blur">
              <ShieldCheck className="size-3.5 text-primary" />
              {badgeLabel}
            </div>
            <div className="space-y-4">
              <h1
                className="font-semibold text-4xl tracking-tight sm:text-5xl lg:text-6xl"
                suppressHydrationWarning
              >
                {headline}
              </h1>
              <p
                className="max-w-xl text-base text-muted-foreground leading-7"
                suppressHydrationWarning
              >
                {description}
              </p>
            </div>
          </div>

          <div className="grid max-w-2xl gap-3 sm:grid-cols-3">
            {features.map((item) => (
              <div key={item.label} className="rounded-2xl border bg-background/70 p-4 shadow-sm backdrop-blur">
                <item.icon className="mb-3 size-5 text-primary" />
                <p className="font-medium text-sm" suppressHydrationWarning>
                  {item.label}
                </p>
              </div>
            ))}
          </div>
        </section>

        <section className="flex justify-center lg:justify-end">
          <Card className="w-full max-w-[460px] border-white/70 bg-background/85 shadow-2xl shadow-slate-950/10 backdrop-blur-xl dark:border-white/10 dark:shadow-black/40">
            <CardHeader className="space-y-3 p-8 pb-4">
              <div className="flex size-12 items-center justify-center rounded-2xl bg-primary/10 text-primary">
                <LockKeyhole className="size-5" />
              </div>
              <div className="space-y-1">
                <CardTitle className="text-2xl">{cardTitle}</CardTitle>
                <CardDescription>{cardDescription}</CardDescription>
              </div>
            </CardHeader>
            <CardContent className="p-8 pt-4">
              <form className="space-y-5" onSubmit={handleSubmit}>
                <ErrorBanner message={errorMessage} />

                <div className="space-y-2">
                  <Label htmlFor={emailId} suppressHydrationWarning>
                    Email address
                  </Label>
                  <div className="relative">
                    <Mail className="-translate-y-1/2 absolute top-1/2 left-3 size-4 text-muted-foreground" />
                    <Input
                      id={emailId}
                      name="email"
                      type="email"
                      autoComplete="email"
                      placeholder={emailPlaceholder}
                      className="h-11 rounded-xl bg-background/90 pl-9"
                      required
                      suppressHydrationWarning
                    />
                  </div>
                </div>

                <div className="space-y-2">
                  <div className="flex items-center justify-between gap-2">
                    <Label htmlFor={passwordId} suppressHydrationWarning>
                      Password
                    </Label>
                    <button
                      type="button"
                      className="text-muted-foreground text-xs hover:text-foreground disabled:opacity-50"
                      disabled={isResettingPassword}
                      suppressHydrationWarning
                      onClick={() => {
                        const emailInput = document.getElementById(emailId) as HTMLInputElement | null;
                        void handleForgotPassword(emailInput?.value ?? "");
                      }}
                    >
                      {isResettingPassword ? "Sending…" : "Forgot password?"}
                    </button>
                  </div>
                  <div className="relative">
                    <LockKeyhole className="-translate-y-1/2 absolute top-1/2 left-3 size-4 text-muted-foreground" />
                    <Input
                      id={passwordId}
                      name="password"
                      type={showPassword ? "text" : "password"}
                      autoComplete="current-password"
                      placeholder="Enter password"
                      className="h-11 rounded-xl bg-background/90 pr-10 pl-9"
                      required
                      suppressHydrationWarning
                    />
                    <button
                      type="button"
                      className="-translate-y-1/2 absolute top-1/2 right-3 text-muted-foreground hover:text-foreground"
                      onClick={() => setShowPassword((value) => !value)}
                      aria-label={showPassword ? "Hide password" : "Show password"}
                      suppressHydrationWarning
                    >
                      {showPassword ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
                    </button>
                  </div>
                </div>

                <label className="flex items-center gap-2 text-muted-foreground text-sm">
                  <input
                    type="checkbox"
                    name="remember_me"
                    defaultChecked
                    className="size-4 rounded border-input"
                    suppressHydrationWarning
                  />
                  <span suppressHydrationWarning>Remember me</span>
                </label>

                <Button
                  type="submit"
                  className="h-11 w-full rounded-xl gap-2"
                  disabled={isSubmitting}
                  suppressHydrationWarning
                >
                  {isSubmitting ? "Signing in..." : "Login"}
                  {!isSubmitting ? <ArrowRight className="size-4" /> : null}
                </Button>
              </form>

              <p className="mt-6 text-center text-muted-foreground text-xs" suppressHydrationWarning>
                {protectedText}
              </p>
            </CardContent>
          </Card>
        </section>
      </div>
      <AppPoweredByFooter className="sticky bottom-0 z-10" />
    </main>
  );
}
