"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { AlertTriangle, ChevronDown, ChevronLeft, OctagonAlert } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";

// Page-level layout for rebuilt screens: consistent padding and max width inside the app shell.
export function PageContent({ className, children }) {
  return <div className={cn("mx-auto flex w-full max-w-[1480px] flex-col gap-6 px-4 py-6 md:px-6 lg:px-8", className)}>{children}</div>;
}

/**
 * Title row for a page or record. `back` = { href, label } renders a small back link above the title;
 * `meta` sits under the title (badges, key facts); `actions` align right.
 */
export function PageHeader({ title, description, back, meta, actions, className }) {
  return <div className={cn("flex flex-col gap-4 md:flex-row md:items-start md:justify-between", className)}>
    <div className="min-w-0 space-y-1.5">
      {back && <Button variant="link" size="sm" className="-ml-1 h-auto gap-1 px-1 text-muted-foreground" asChild><Link href={back.href}><ChevronLeft className="size-4" />{back.label}</Link></Button>}
      <h1 className="truncate text-2xl font-semibold tracking-tight">{title}</h1>
      {description && <div className="max-w-3xl text-sm text-muted-foreground">{description}</div>}
      {meta && <div className="flex flex-wrap items-center gap-2 pt-1">{meta}</div>}
    </div>
    {actions && <div className="flex shrink-0 flex-wrap items-center gap-2">{actions}</div>}
  </div>;
}

/**
 * Card section with a header. Set `collapsible` to let users fold it away; collapsible sections start collapsed
 * (pass `defaultOpen` for the one section a page should open with). Open state is local to the page view.
 * `summary` shows next to the title when collapsed, so a folded section still says what it holds.
 * `alerts` are compact warning/danger badges shown in the header (also while collapsed) for things that need attention:
 * [{ label: "1 blocking", tone: "danger" | "warning" }] or plain strings (warning). Falsy entries are skipped.
 */
// `primaryAction`: one or two compact key actions (small outline buttons) that stay visible while the section is
// collapsed; clicking inside it also opens the section. `actions` only show when open.
// A collapsible section with an `id` opens itself when the URL hash is `#id` (worklist, notifications, "Go to" links).
export function SectionCard({ id, title, description, icon: Icon, actions, primaryAction, summary, alerts, collapsible = false, defaultOpen = false, open: openProp, onOpenChange, className, contentClassName, children }) {
  // Uncontrolled by default; pass `open` + `onOpenChange` to open it from elsewhere (e.g. a "Go to section" link).
  const [openState, setOpenState] = useState(defaultOpen);
  const open = openProp ?? openState;
  const setOpen = (next) => { if (openProp === undefined) setOpenState(next); onOpenChange?.(next); };

  useEffect(() => {
    if (!collapsible || !id) return undefined;
    const openFromHash = () => {
      if (window.location.hash.slice(1).split(":")[0] !== id) return;
      if (openProp === undefined) setOpenState(true);
      onOpenChange?.(true);
      window.requestAnimationFrame(() => document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" }));
    };
    openFromHash();
    window.addEventListener("hashchange", openFromHash);
    return () => window.removeEventListener("hashchange", openFromHash);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [collapsible, id]);
  // minmax(0,1fr) lets long titles truncate instead of wrapping word by word next to header actions.
  const header = <CardHeader className={cn("gap-1 has-data-[slot=card-action]:grid-cols-[minmax(0,1fr)_auto]", collapsible && !open && "pb-0")}>
    <CardTitle className="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 text-base">
      <span className="flex min-w-0 max-w-full items-center gap-2">
        {Icon && <Icon className="size-4 shrink-0 text-muted-foreground" />}
        <span className="min-w-0 truncate" title={typeof title === "string" ? title : undefined}>{title}</span>
      </span>
      {collapsible && !open && summary && <span className="min-w-0 max-w-full truncate text-sm font-normal text-muted-foreground">· {summary}</span>}
      <SectionAlerts alerts={alerts} />
    </CardTitle>
    {description && (!collapsible || open) && <CardDescription>{description}</CardDescription>}
    {/* max-w in container units: on a phone several header buttons wrap inside their own column instead of squeezing
        the title and description into a sliver. */}
    {(actions || primaryAction || collapsible) && <CardAction className="flex max-w-[60cqw] flex-wrap items-center justify-end gap-2">
      {primaryAction && <span className="contents" onClickCapture={() => { if (collapsible && !open) setOpen(true); }}>{primaryAction}</span>}
      {(!collapsible || open) && actions}
      {collapsible && <CollapsibleTrigger asChild><Button variant="ghost" size="icon" className="size-8" aria-label={`${open ? "Collapse" : "Expand"} ${typeof title === "string" ? title : "section"}`}><ChevronDown className={cn("transition-transform", open && "rotate-180")} /></Button></CollapsibleTrigger>}
    </CardAction>}
  </CardHeader>;

  const card = <Card id={id} className={cn("scroll-mt-20 gap-4", className)}>
    {header}
    {collapsible ? <CollapsibleContent><CardContent className={contentClassName}>{children}</CardContent></CollapsibleContent> : <CardContent className={contentClassName}>{children}</CardContent>}
  </Card>;

  return collapsible ? <Collapsible open={open} onOpenChange={setOpen}>{card}</Collapsible> : card;
}

// Header alert chips for SectionCard: icon + short text so colour is never the only signal.
function SectionAlerts({ alerts }) {
  const items = (alerts || []).filter(Boolean).map((alert) => typeof alert === "string" ? { label: alert, tone: "warning" } : alert).filter((alert) => alert.label);
  if (!items.length) return null;
  return <span className="flex min-w-0 max-w-full flex-wrap items-center gap-1.5 font-normal">
    {items.map((alert) => {
      const danger = alert.tone === "danger" || alert.tone === "destructive";
      const AlertIcon = danger ? OctagonAlert : AlertTriangle;
      return <Badge key={alert.label} variant={danger ? "danger" : "warning"} className="h-5 px-1.5" title={alert.hint}><AlertIcon aria-hidden="true" />{alert.label}</Badge>;
    })}
  </span>;
}

// Compact KPI tile: label, value, optional hint/trend line.
export function StatCard({ label, value, hint, icon: Icon, tone, className }) {
  return <Card className={cn("gap-1 py-4", className)}>
    <CardContent className="px-4">
      <div className="flex items-center justify-between text-sm text-muted-foreground"><span>{label}</span>{Icon && <Icon className="size-4" />}</div>
      <div className={cn("mt-1 text-2xl font-semibold tabular-nums tracking-tight", tone === "warning" && "text-warning", tone === "danger" && "text-destructive", tone === "success" && "text-success")}>{value}</div>
      {hint && <p className="mt-0.5 text-xs text-muted-foreground">{hint}</p>}
    </CardContent>
  </Card>;
}

// Label/value pairs in a responsive grid. items: [[label, value], ...]; falsy entries are skipped.
export function FactList({ items, columns = 3, className }) {
  return <dl className={cn("grid gap-x-6 gap-y-4", columns === 2 && "sm:grid-cols-2", columns === 3 && "sm:grid-cols-2 lg:grid-cols-3", columns === 4 && "sm:grid-cols-2 lg:grid-cols-4", className)}>
    {items.filter(Boolean).map(([label, value]) => <div key={label} className="min-w-0 space-y-1">
      <dt className="text-xs font-medium text-muted-foreground">{label}</dt>
      <dd className="text-sm font-medium break-words">{value ?? <span className="text-muted-foreground">Not set</span>}</dd>
    </div>)}
  </dl>;
}

// Loading placeholders shaped like the page that is coming, instead of a spinner.
export function ListPageSkeleton({ filters = 4, rows = 8 }) {
  return <PageContent>
    <div className="grid gap-2"><Skeleton className="h-8 w-56" /><Skeleton className="h-4 w-96 max-w-full" /></div>
    <div className="flex flex-wrap gap-2"><Skeleton className="h-9 w-72" />{Array.from({ length: filters }).map((_, index) => <Skeleton key={index} className="h-9 w-32" />)}</div>
    <div className="overflow-hidden rounded-lg border">
      <Skeleton className="h-10 rounded-none" />
      {Array.from({ length: rows }).map((_, index) => <div key={index} className="flex items-center gap-4 border-t px-4 py-3"><Skeleton className="h-4 w-40" /><Skeleton className="h-4 flex-1" /><Skeleton className="h-5 w-20 rounded-full" /><Skeleton className="h-4 w-16" /></div>)}
    </div>
  </PageContent>;
}

export function DetailPageSkeleton({ stats = 4, sections = 2 }) {
  return <PageContent>
    <div className="grid gap-2"><Skeleton className="h-4 w-28" /><Skeleton className="h-8 w-72" /><div className="flex gap-2"><Skeleton className="h-5 w-20 rounded-full" /><Skeleton className="h-5 w-24 rounded-full" /></div></div>
    {stats > 0 && <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">{Array.from({ length: stats }).map((_, index) => <Skeleton key={index} className="h-24 rounded-xl" />)}</div>}
    {Array.from({ length: sections }).map((_, index) => <Skeleton key={index} className="h-64 rounded-xl" />)}
  </PageContent>;
}

export function FormPageSkeleton({ fields = 6 }) {
  return <PageContent className="max-w-4xl">
    <div className="grid gap-2"><Skeleton className="h-4 w-28" /><Skeleton className="h-8 w-64" /></div>
    <div className="grid gap-5 rounded-xl border p-6 sm:grid-cols-2">{Array.from({ length: fields }).map((_, index) => <div key={index} className="grid gap-2"><Skeleton className="h-4 w-24" /><Skeleton className="h-9" /></div>)}</div>
  </PageContent>;
}
