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

type Person = components["schemas"]["PersonRead"];
type Name = components["schemas"]["NameRead"];
type Event = components["schemas"]["EventRead"];
type Relationship = components["schemas"]["RelationshipRead"];

// Public, no-login person view. The /api/v1/public surface returns only what an
// anonymous viewer may see: deceased people in full, living people redacted.
export default function PublicPersonPage() {
  const { treeId, personId } = useParams<{ treeId: string; personId: string }>();
  const [person, setPerson] = useState<Person | null>(null);
  const [names, setNames] = useState<Name[]>([]);
  const [events, setEvents] = useState<Event[]>([]);
  const [people, setPeople] = useState<Person[]>([]);
  const [rels, setRels] = useState<Relationship[]>([]);
  const [status, setStatus] = useState<"loading" | "ready" | "notfound">("loading");

  useEffect(() => {
    let cancelled = false;
    (async () => {
      const pr = await api.GET("/api/v1/public/trees/{tree_id}/persons/{person_id}", {
        params: { path: { tree_id: treeId, person_id: personId } },
      });
      if (cancelled) return;
      if (!pr.data) {
        setStatus("notfound");
        return;
      }
      const [nm, ev, ppl, rl] = await Promise.all([
        api.GET("/api/v1/public/trees/{tree_id}/persons/{person_id}/names", {
          params: { path: { tree_id: treeId, person_id: personId } },
        }),
        api.GET("/api/v1/public/trees/{tree_id}/persons/{person_id}/events", {
          params: { path: { tree_id: treeId, person_id: personId } },
        }),
        api.GET("/api/v1/public/trees/{tree_id}/persons", { params: { path: { tree_id: treeId } } }),
        api.GET("/api/v1/public/trees/{tree_id}/relationships", {
          params: { path: { tree_id: treeId } },
        }),
      ]);
      if (cancelled) return;
      setPerson(pr.data);
      setNames(nm.data ?? []);
      setEvents(ev.data ?? []);
      setPeople(ppl.data ?? []);
      setRels(rl.data ?? []);
      setStatus("ready");
    })();
    return () => {
      cancelled = true;
    };
  }, [treeId, personId]);

  const nameOf = useMemo(
    () => (id: string) => people.find((p) => p.id === id)?.primary_name ?? "Unknown",
    [people],
  );

  const parents = rels.filter((r) => r.type === "parent_child" && r.person_to_id === personId);
  const children = rels.filter((r) => r.type === "parent_child" && r.person_from_id === personId);
  const partners = rels.filter(
    (r) => r.type === "partnership" && (r.person_from_id === personId || r.person_to_id === personId),
  );
  const otherEnd = (r: Relationship) =>
    r.person_from_id === personId ? r.person_to_id : r.person_from_id;

  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 person isn’t publicly visible.</p>
        <Link href={`/p/${treeId}`} className="text-sm text-bronze hover:underline">
          ← Back to the tree
        </Link>
      </div>
    );

  const relGroup = (label: string, items: Relationship[]) =>
    items.length > 0 && (
      <div>
        <h3 className="text-sm font-semibold text-bronze">{label}</h3>
        <ul className="mt-1 space-y-1">
          {items.map((r) => (
            <li key={r.id} className="text-sm">
              <Link
                href={`/p/${treeId}/persons/${otherEnd(r)}`}
                className="hover:underline"
              >
                {nameOf(otherEnd(r))}
                {r.qualifier ? <span className="text-[var(--muted)]"> · {r.qualifier}</span> : null}
              </Link>
            </li>
          ))}
        </ul>
      </div>
    );

  return (
    <div className="space-y-6">
      <Link href={`/p/${treeId}`} className="text-sm text-[var(--muted)] hover:underline">
        ← Back to the tree
      </Link>

      <h1 className="font-serif text-3xl font-semibold">{person?.primary_name ?? "Unnamed"}</h1>

      <div className="grid gap-5 sm:grid-cols-2">
        {events.length > 0 && (
          <Card>
            <CardContent className="space-y-2 p-5">
              <h2 className="font-serif text-base font-semibold">Events</h2>
              <ul className="space-y-1 text-sm">
                {events.map((e) => (
                  <li key={e.id} className="flex justify-between gap-3">
                    <span className="capitalize">{e.event_type}</span>
                    <span className="text-[var(--muted)]">
                      {e.date_value ?? e.date_start ?? ""}
                    </span>
                  </li>
                ))}
              </ul>
            </CardContent>
          </Card>
        )}

        {names.length > 1 && (
          <Card>
            <CardContent className="space-y-2 p-5">
              <h2 className="font-serif text-base font-semibold">Names</h2>
              <ul className="space-y-1 text-sm">
                {names.map((n) => (
                  <li key={n.id} className="flex justify-between gap-3">
                    <span>{[n.given, n.surname].filter(Boolean).join(" ") || "—"}</span>
                    <span className="text-[var(--muted)]">{n.name_type}</span>
                  </li>
                ))}
              </ul>
            </CardContent>
          </Card>
        )}
      </div>

      {(parents.length > 0 || children.length > 0 || partners.length > 0) && (
        <Card>
          <CardContent className="grid gap-4 p-5 sm:grid-cols-3">
            {relGroup("Parents", parents)}
            {relGroup("Partners", partners)}
            {relGroup("Children", children)}
          </CardContent>
        </Card>
      )}
    </div>
  );
}
