import Link from "next/link";
import { notFound } from "next/navigation";
import { prisma } from "@/lib/prisma";
import { buildPedigree, type PedigreeNode } from "@/lib/pedigree";
import { sexColors } from "@/lib/sex";
import { computeCOI, coiRiskLabel } from "@/lib/coi";

const GENERATIONS = 3;

// Card gets smaller each generation back, like a printed pedigree certificate,
// so the 8 great-grandparent cards don't blow out the chart's total height.
const CARD_SIZE = [
  { width: "w-48", photo: true, name: "text-sm", meta: "text-xs" },
  { width: "w-40", photo: true, name: "text-sm", meta: "text-xs" },
  { width: "w-32", photo: true, name: "text-xs", meta: "text-[11px]" },
  { width: "w-28", photo: false, name: "text-xs", meta: "text-[11px]" },
] as const;

export default async function PedigreePage(props: PageProps<"/horses/[id]/pedigree">) {
  const { id } = await props.params;

  const horse = await prisma.horse.findUnique({
    where: { id },
    select: { id: true, registeredName: true, barnName: true, sireId: true, damId: true },
  });
  if (!horse) notFound();

  const pedigree = await buildPedigree(id, GENERATIONS);
  const coiResult = await computeCOI(horse.sireId, horse.damId);
  const risk = coiResult ? coiRiskLabel(coiResult.coi) : null;

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold">
            {horse.registeredName || horse.barnName || "Unnamed Horse"} — 3-Generation Pedigree
          </h1>
          <p className="text-sm text-neutral-700 dark:text-neutral-300">Sire/dam, grandparents, and great-grandparents.</p>
        </div>
        <Link
          href={`/horses/${horse.id}`}
          className="rounded-md border border-neutral-300 dark:border-neutral-700 px-4 py-2 text-sm font-medium hover:bg-neutral-50 hover:dark:bg-neutral-950"
        >
          Back to Profile
        </Link>
      </div>

      {coiResult && risk ? (
        <div className={`rounded-lg border p-4 ${risk.bg} ${risk.border}`}>
          <p className={`text-sm font-semibold ${risk.text}`}>
            Inbreeding Coefficient (COI): {(coiResult.coi * 100).toFixed(2)}% — {risk.label}
          </p>
          <p className="mt-1 text-xs text-neutral-600 dark:text-neutral-400">
            Estimated from up to {coiResult.maxDepth} generations of recorded pedigree; accuracy depends on how much
            ancestry is in the system, and assumes common ancestors are themselves non-inbred.
          </p>
          {coiResult.commonAncestors.length > 0 && (
            <details className="mt-2 text-sm">
              <summary className="cursor-pointer text-neutral-700 dark:text-neutral-300">
                Common ancestors ({coiResult.commonAncestors.length})
              </summary>
              <ul className="mt-2 space-y-1">
                {coiResult.commonAncestors.map((a) => (
                  <li key={a.ancestorId} className="text-neutral-800 dark:text-neutral-300">
                    <Link href={`/horses/${a.ancestorId}`} className="hover:underline">{a.name}</Link>
                    <span className="text-neutral-600 dark:text-neutral-400"> — contributes {(a.contribution * 100).toFixed(2)}%</span>
                  </li>
                ))}
              </ul>
            </details>
          )}
        </div>
      ) : (
        <div className="rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 p-4 text-sm text-neutral-700 dark:text-neutral-300">
          Add both a sire and dam to calculate an inbreeding coefficient.
        </div>
      )}

      <div className="overflow-x-auto rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 p-6">
        <PedigreeBranch node={pedigree} label={null} depth={0} />
      </div>
    </div>
  );
}

function PedigreeBranch({
  node,
  label,
  depth,
}: {
  node: PedigreeNode;
  label: "Sire" | "Dam" | null;
  depth: number;
}) {
  const hasMoreGenerations = depth < GENERATIONS;

  return (
    <div className="flex items-stretch">
      <div className="flex flex-col justify-center">
        <HorseCard node={node} label={label} depth={depth} />
      </div>
      {hasMoreGenerations && (
        <div className="relative flex flex-col justify-center pl-4">
          <div className="absolute top-0 bottom-0 left-0 w-4 border-l border-neutral-300 dark:border-neutral-700" />
          <div className="flex flex-col gap-2">
            <div className="relative">
              <div className="absolute top-1/2 -left-4 w-4 border-t border-neutral-300 dark:border-neutral-700" />
              <PedigreeBranch node={node?.sire ?? null} label="Sire" depth={depth + 1} />
            </div>
            <div className="relative">
              <div className="absolute top-1/2 -left-4 w-4 border-t border-neutral-300 dark:border-neutral-700" />
              <PedigreeBranch node={node?.dam ?? null} label="Dam" depth={depth + 1} />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function HorseCard({ node, label, depth }: { node: PedigreeNode; label: "Sire" | "Dam" | null; depth: number }) {
  const size = CARD_SIZE[depth] ?? CARD_SIZE[CARD_SIZE.length - 1];

  if (!node) {
    return (
      <div className={`${size.width} shrink-0 rounded-lg border border-dashed border-neutral-300 dark:border-neutral-700 bg-neutral-50 dark:bg-neutral-950 p-2`}>
        {label && <div className="text-[10px] font-semibold uppercase tracking-wide text-neutral-500 dark:text-neutral-400">{label}</div>}
        {size.photo && (
          <div className="flex h-24 max-h-[200px] w-full items-center justify-center rounded-md bg-neutral-100 dark:bg-neutral-900 text-[10px] text-neutral-400 dark:text-neutral-500">
            No photo
          </div>
        )}
        <div className={`mt-1 ${size.name} text-neutral-400 dark:text-neutral-500`}>Unknown</div>
      </div>
    );
  }

  const colors = sexColors(node.sex);

  return (
    <Link
      href={`/horses/${node.id}`}
      className={`block ${size.width} shrink-0 rounded-lg border p-2 shadow-sm transition hover:shadow-md ${colors.bg} ${colors.border}`}
    >
      {label && <div className="text-[10px] font-semibold uppercase tracking-wide text-neutral-600 dark:text-neutral-400">{label}</div>}
      {size.photo && (
        <div className="flex max-h-[200px] w-full items-center justify-center overflow-hidden rounded-md bg-white dark:bg-neutral-900">
          {node.photoUrl ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={node.photoUrl} alt={node.name} className="max-h-[200px] w-full object-contain" />
          ) : (
            <div className="flex h-24 w-full items-center justify-center text-[10px] text-neutral-400 dark:text-neutral-500">No photo</div>
          )}
        </div>
      )}
      <div className={`mt-1 truncate ${size.name} font-semibold ${colors.text}`}>{node.name}</div>
      <div className={`truncate ${size.meta} text-neutral-700 dark:text-neutral-300`}>{node.color ?? "Color unknown"}</div>
      <div className={`truncate ${size.meta} text-neutral-700 dark:text-neutral-300`}>
        {node.registrationNumber ? `#${node.registrationNumber}` : "Unregistered"}
      </div>
    </Link>
  );
}
