import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, Text } from "ink";
import { buildCacheStabilityReport, formatCacheStabilityReport } from "../services/cache/cacheStability.js";
import { useTerminalSize } from "../hooks/useTerminalSize.js";
import { Pane } from "./design/Pane.js";
import { ProgressBar } from "./design/ProgressBar.js";
import { StatusBadge } from "./design/StatusBadge.js";
import { truncateCells } from "./design/textLayout.js";
export function CachePlanPanel(props) {
    const { columns } = useTerminalSize();
    const width = Math.max(62, Math.min(116, columns - 4));
    const titleWidth = Math.max(18, width - 58);
    return (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsxs(Pane, { width: width, title: "cache plan", tone: "brand", paddingX: 1, children: [_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: "cyan", children: props.model.title }), _jsx(Text, { color: "gray", children: truncateCells(props.model.subtitle, Math.max(24, width - 20)) })] }), _jsx(StatusBadge, { label: props.model.badge, tone: "brand" })] }), _jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsx(StatusBadge, { label: "dynamic", tone: props.model.ratio > 0.9 ? "warning" : "success" }), _jsx(Text, { children: " " }), _jsx(ProgressBar, { ratio: props.model.ratio, width: Math.max(12, Math.min(28, width - 48)), showPercent: true }), _jsxs(Text, { color: "gray", children: [" ", truncateCells(props.model.summary, Math.max(16, width - 46))] })] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(StatusBadge, { label: "stability", tone: props.model.stabilityTone }), _jsxs(Text, { children: [" ", props.model.stabilityBadge] }), _jsxs(Text, { color: "gray", children: [" ", truncateCells(props.model.stabilitySummary, Math.max(16, width - 24))] })] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(StatusBadge, { label: "shape", tone: "brand" }), _jsxs(Text, { color: "gray", children: [" ", truncateCells(props.model.shapeNote, Math.max(16, width - 12))] })] }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: props.model.rows.map((row) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(StatusBadge, { label: row.label, tone: row.tone }), _jsxs(Text, { color: "gray", children: [" ", truncateCells(row.chars.padStart(7), 7), " "] }), _jsx(Text, { children: truncateCells(row.title.padEnd(titleWidth), titleWidth) }), _jsxs(Text, { color: "gray", children: [" ", truncateCells(row.note, Math.max(10, width - titleWidth - 24))] })] }, row.key))) }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "gray", children: truncateCells(props.model.recommendation, Math.max(24, width - 4)) }), _jsx(Text, { color: "gray", children: truncateCells(props.model.footer, Math.max(24, width - 4)) })] })] }) }));
}
export function buildCachePlanPanelModel(input) {
    const plannedChars = input.plan.blocks.reduce((sum, block) => sum + block.chars, 0);
    const truncatedCount = input.plan.blocks.filter((block) => block.truncated).length;
    const ratio = input.maxDynamicChars > 0 ? plannedChars / input.maxDynamicChars : 0;
    const stability = buildCacheStabilityReport(input.plan);
    return {
        title: "DeepSeek cache plan",
        subtitle: input.goal,
        badge: input.effort,
        ratio,
        summary: `tokens~${input.plan.approxTokens} dropped=${input.plan.droppedChars}`,
        stabilityBadge: stability.risk,
        stabilityTone: stabilityTone(stability.risk),
        stabilitySummary: formatCacheStabilityReport(stability),
        shapeNote: input.shapeNote ?? "shape fingerprint is content-free; repeated shapes usually improve DeepSeek cache-hit odds.",
        rows: input.plan.blocks.map((block) => ({
            key: `${block.priority}:${block.title}`,
            label: priorityLabel(block.priority),
            title: block.title,
            chars: String(block.chars),
            tone: block.truncated ? "warning" : toneForPriority(block.priority),
            note: block.truncated ? "truncated by dynamic budget" : noteForPriority(block.priority),
        })),
        recommendation: recommendationFor(input.plan.droppedChars, truncatedCount, stability.recommendation),
        footer: "/cache pin add <name> <fact> | /effort low|medium|high|max | /cache doctor",
    };
}
function priorityLabel(priority) {
    if (priority === "sticky")
        return "pin";
    if (priority === "project")
        return "project";
    if (priority === "context")
        return "context";
    if (priority === "feedback")
        return "feedback";
    return "request";
}
function toneForPriority(priority) {
    if (priority === "sticky")
        return "success";
    if (priority === "project")
        return "brand";
    if (priority === "context")
        return "muted";
    if (priority === "feedback")
        return "warning";
    return "success";
}
function noteForPriority(priority) {
    if (priority === "sticky")
        return "stable prefix";
    if (priority === "project")
        return "cache-friendly prefix";
    if (priority === "context")
        return "dynamic context";
    if (priority === "feedback")
        return "append-only feedback";
    return "latest turn preserved";
}
function recommendationFor(droppedChars, truncatedCount, stabilityRecommendation) {
    if (droppedChars <= 0 && truncatedCount === 0) {
        return stabilityRecommendation;
    }
    return "Dynamic context was clipped: pin stable facts, narrow selected files, or raise /effort before a large edit.";
}
function stabilityTone(risk) {
    if (risk === "high")
        return "error";
    if (risk === "medium")
        return "warning";
    return "success";
}
