import Link from 'next/link';
import { fmtInt, fmtParams, num } from '@/lib/format';
import { routes } from '@/lib/site';
import type { EntitySummary } from '@/lib/types';
/*
Compact server-rendered SVG lineage tree: ancestors → this model → descendants, artifacts collapsed by kind with counts.
Not the force graph (components/graph is not ours); "Open in Graph" links to the interactive explorer in lineage mode.
*/
type Node = { id: string; label: string; sub?: string; href?: string; kind: 'model' | 'this' | 'artifact' };
const W = 720;
const ROW = 34;
const BOX_W = 200;
const BOX_H = 28;
const PAD = 8;
function trunc(s: string, n: number): string {
return s.length > n ? `${s.slice(0, n - 1)}…` : s;
}
function toNode(e: EntitySummary): Node {
const p = num(e.attributes?.parameter_count);
return { id: e.id, label: e.name, sub: p !== null ? fmtParams(p) : e.organization?.name ?? undefined, href: routes.entity(e), kind: 'model' };
}
export function LineageTree({ self, ancestors, descendants, artifactKinds, className }: { self: EntitySummary; ancestors: EntitySummary[]; descendants: EntitySummary[]; artifactKinds: { kind: string; count: number }[]; className?: string }) {
const left = ancestors.slice(0, 6).map(toNode);
const rightModels = descendants.slice(0, 6).map(toNode);
const rightArtifacts: Node[] = artifactKinds.filter((k) => k.count > 0).map((k) => ({ id: `kind-${k.kind}`, label: `${fmtInt(k.count)} ${k.kind}${k.count === 1 ? '' : 's'}`, sub: 'artifacts · collapsed', href: `${routes.entity(self)}#versions-artifacts`, kind: 'artifact' }));
const right = [...rightModels, ...rightArtifacts];
const moreL = ancestors.length - left.length;
const moreR = descendants.length - rightModels.length;
const rows = Math.max(1, left.length + (moreL > 0 ? 1 : 0), right.length + (moreR > 0 ? 1 : 0));
const H = PAD * 2 + rows * ROW;
const colX = [PAD, W / 2 - BOX_W / 2, W - PAD - BOX_W];
const yOf = (i: number, n: number) => PAD + ((H - PAD * 2) / Math.max(1, n)) * (i + 0.5) - BOX_H / 2;
const selfY = H / 2 - BOX_H / 2;
const p = num(self.attributes?.parameter_count);
const Box = ({ n, x, y }: { n: Node; x: number; y: number }) => {
const fill = n.kind === 'this' ? 'var(--accent-soft)' : n.kind === 'artifact' ? 'var(--surface-2)' : 'var(--surface)';
const stroke = n.kind === 'this' ? 'var(--accent)' : 'var(--rule-strong)';
const body = (