"use client";

import Link from "next/link";
import { useParams } from "next/navigation";
import { useEffect, useMemo, useState } from "react";

import { api } from "@/lib/api/client";
import type { components } from "@/lib/api/schema";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";

type Person = components["schemas"]["PersonRead"];
type Event = components["schemas"]["EventRead"];
type Tree = components["schemas"]["PublicTreeRead"];

// Public, no-login view of a tree. Everything here is already redacted by the
// /api/v1/public surface (living people show as "Living person").
export default function PublicTreePage() {
  const { treeId } = useParams<{ treeId: string }>();
  const [tree, setTree] = useState<Tree | null>(null);
  const [people, setPeople] = useState<Person[]>([]);
  const [events, setEvents] = useState<Event[]>([]);
  const [status, setStatus] = useState<"loading" | "ready" | "notfound">("loading");
  const [search, setSearch] = useState("");

  useEffect(() => {
    let cancelled = false;
    (async () => {
      const t = await api.GET("/api/v1/public/trees/{tree_id}", {
        params: { path: { tree_id: treeId } },
      });
      if (cancelled) return;
      if (!t.data) {
        setStatus("notfound");
        return;
      }
      const [p, e] = await Promise.all([
        api.GET("/api/v1/public/trees/{tree_id}/persons", { params: { path: { tree_id: treeId } } }),
        api.GET("/api/v1/public/trees/{tree_id}/events", { params: { path: { tree_id: treeId } } }),
      ]);
      if (cancelled) return;
      setTree(t.data);
      setPeople(p.data ?? []);
      setEvents(e.data ?? []);
      setStatus("ready");
    })();
    return () => {
      cancelled = true;
    };
  }, [treeId]);

  const years = useMemo(() => {
    const m = new Map<string, string>();
    const yr = (e: Event) => (e.date_start ? e.date_start.slice(0, 4) : e.date_value ?? "");
    for (const p of people) {
      const b = events.find((e) => e.person_id === p.id && e.event_type === "birth");
      const d = events.find((e) => e.person_id === p.id && e.event_type === "death");
      const parts = [b ? yr(b) : "", d ? yr(d) : ""];
      if (parts[0] || parts[1]) m.set(p.id, `${parts[0]}–${parts[1]}`.replace(/^–$/, ""));
    }
    return m;
  }, [people, events]);

  const shown = useMemo(() => {
    const q = search.trim().toLowerCase();
    const sorted = [...people].sort((a, b) =>
      (a.primary_name ?? "").localeCompare(b.primary_name ?? ""),
    );
    return (q ? sorted.filter((p) => (p.primary_name ?? "").toLowerCase().includes(q)) : sorted).slice(
      0,
      300,
    );
  }, [people, search]);

  if (status === "loading") return <p className="text-[var(--muted)]">Loading…</p>;
  if (status === "notfound")
    return (
      <div className="space-y-2">
        <h1 className="text-2xl font-semibold">Not available</h1>
        <p className="text-[var(--muted)]">
          This tree isn’t public, or the link is wrong.{" "}
          <Link href="/login" className="text-bronze hover:underline">
            Sign in
          </Link>{" "}
          if it’s yours.
        </p>
      </div>
    );

  return (
    <div className="space-y-6">
      <div>
        <h1 className="font-serif text-3xl font-semibold">{tree?.name}</h1>
        {tree?.description && <p className="mt-1 text-[var(--muted)]">{tree.description}</p>}
        <p className="mt-1 text-sm text-[var(--muted)]">
          {people.length} {people.length === 1 ? "person" : "people"} · living people are hidden
        </p>
      </div>

      <Input
        className="w-72"
        placeholder="Search people…"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
      />

      <Card className="overflow-hidden">
        <CardContent className="p-0">
          {shown.length === 0 ? (
            <div className="px-4 py-6 text-sm text-[var(--muted)]">No matches.</div>
          ) : (
            shown.map((p, i) => (
              <Link
                key={p.id}
                href={`/p/${treeId}/persons/${p.id}`}
                className={`flex items-center justify-between gap-3 px-4 py-2.5 text-sm transition-colors hover:bg-bronze/[0.05] ${
                  i > 0 ? "border-t border-[var(--border)]" : ""
                }`}
              >
                <span className="truncate font-medium">{p.primary_name ?? "Unnamed"}</span>
                <span className="shrink-0 text-xs text-[var(--muted)]">{years.get(p.id) ?? ""}</span>
              </Link>
            ))
          )}
        </CardContent>
      </Card>
    </div>
  );
}
