"use client";
import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Badge, Button, ConfidenceBadge, EmptyState, RelativeTime, SearchInput, SkeletonBlock, SkeletonRows, Tab, TabList, TabPanel, Tabs, Table, TBody, Td, Th, THead, Tr } from "@/components/ui";
import { cn } from "@/components/ui/cn";
import { DASH, fmtDateTimeUtc, fmtInt, fmtValue } from "@/lib/format";
import { ENTITY_TYPE_LABEL } from "@/lib/labels";
import { entityHref } from "@/lib/routes";
import { adminFetchText, adminProxyUrl, type AdminDocumentDetail, type AdminDocVersion } from "@/lib/admin-api";
import { Code, countMatches, DiffView, ErrorNote, ExtLink, fmtBytes, JsonView, KV, LevelBadge, Mono, Panel, RefreshButton, Spinner, Stat } from "./primitives";
import { AdminPageHeader } from "./shell";
import { useToast } from "./toast";
import { useAdminMutation, useAdminQuery } from "./use-admin-query";
const HTML_PREVIEW_CAP = 400_000;
function isHtml(ct: string | null | undefined, body: string): boolean {
return /html|xml/i.test(ct ?? "") || / n.remove());
const blocks = new Set(["P", "DIV", "LI", "TR", "H1", "H2", "H3", "H4", "H5", "H6", "BR", "SECTION", "ARTICLE", "HEADER", "FOOTER", "TD", "TH", "UL", "OL", "TABLE", "BLOCKQUOTE", "PRE", "DD", "DT", "FIGCAPTION", "NAV", "ASIDE", "MAIN"]);
const out: string[] = [];
const walk = (node: Node) => {
if (node.nodeType === Node.TEXT_NODE) out.push(node.textContent ?? "");
else if (node.nodeType === Node.ELEMENT_NODE) {
const el = node as Element;
const block = blocks.has(el.tagName);
if (block) out.push("\n");
el.childNodes.forEach(walk);
if (block) out.push("\n");
}
};
walk(doc.body ?? doc);
return out
.join("")
.split("\n")
.map((l) => l.replace(/\s+/g, " ").trim())
.filter((l, i, arr) => l || (i > 0 && arr[i - 1]))
.join("\n")
.trim();
} catch {
return html;
}
}
/** Injects so relative assets resolve; scripts are stripped and the frame is sandboxed. */
export function srcDocFor(html: string, baseUrl: string | null): string {
const clean = html.replace(/