import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, Text } from "ink";
import { Divider } from "./design/Divider.js";
import { StatusBadge } from "./design/StatusBadge.js";
import { truncateCells } from "./design/textLayout.js";
import { toneColor } from "./design/terminalTheme.js";
export function ResumeTask(props) {
    const width = Math.max(44, props.width);
    return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [_jsx(Divider, { width: Math.max(12, width - 2), title: props.model.title, tone: "muted" }), _jsx(Text, { color: "gray", children: truncateCells(props.model.summary, Math.max(20, width - 4)) }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: props.model.rows.length === 0 ? (_jsx(Text, { color: "gray", children: "No resumable local runs" })) : props.model.rows.map((row) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: toneColor(row.selected ? "brand" : "muted"), children: [row.marker, " "] }), _jsx(StatusBadge, { label: row.status, tone: row.tone }), _jsxs(Text, { color: "cyan", children: [" ", truncateCells(row.runId, 18)] }), _jsxs(Text, { color: "gray", children: [" ", truncateCells(row.message, Math.max(16, width - 34))] })] }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", children: truncateCells(row.detail, Math.max(16, width - 8)) }) })] }, row.key))) }), _jsx(Text, { color: "gray", children: truncateCells(props.model.footer, Math.max(20, width - 4)) })] }));
}
export function resumeTaskModel(runs, options = {}) {
    const visibleCount = Math.max(1, options.visibleCount ?? 5);
    const resumable = runs.filter(isResumableRun);
    const selectedIndex = selectedRunIndex(resumable, options.selectedRunId);
    const start = Math.max(0, Math.min(selectedIndex - Math.floor(visibleCount / 2), resumable.length - visibleCount));
    const visible = resumable.slice(start, start + visibleCount);
    const hiddenBefore = start;
    const hiddenAfter = Math.max(0, resumable.length - start - visible.length);
    return {
        title: options.title ?? "resume task",
        summary: resumeTaskSummary(runs.length, resumable.length, hiddenBefore, hiddenAfter),
        rows: visible.map((run, index) => resumeTaskRow(run, start + index === selectedIndex)),
        footer: resumable.length > 0
            ? "/attach use <run-id> | /tasks <run-id> | /agents drain <run-id>"
            : "/runs | /agents start <agent> <task>",
    };
}
export function isResumableRun(run) {
    return run.status === "running" || run.status === "paused";
}
function resumeTaskRow(run, selected) {
    return {
        key: run.id,
        marker: selected ? ">" : " ",
        runId: run.id,
        status: run.status,
        tone: toneForRunStatus(run.status),
        message: firstLine(run.message || "(no message)", 120),
        detail: [
            `${run.actionCount} actions`,
            `${run.artifactCount} artifacts`,
            `${run.eventCount} events`,
            cacheNote(run),
            relativeRunTime(run.updatedAtMs),
        ].filter(Boolean).join(" | "),
        selected,
    };
}
function selectedRunIndex(runs, selectedRunId) {
    if (runs.length === 0)
        return 0;
    const byId = selectedRunId ? runs.findIndex((run) => run.id === selectedRunId) : -1;
    return byId >= 0 ? byId : 0;
}
function resumeTaskSummary(totalRuns, resumableRuns, hiddenBefore, hiddenAfter) {
    const hidden = [
        hiddenBefore > 0 ? `${hiddenBefore} older` : "",
        hiddenAfter > 0 ? `${hiddenAfter} newer` : "",
    ].filter(Boolean).join(" / ");
    const base = `${resumableRuns}/${totalRuns} resumable local runs`;
    return hidden ? `${base} / hidden ${hidden}` : base;
}
function toneForRunStatus(status) {
    if (status === "running" || status === "paused")
        return "warning";
    if (status === "succeeded")
        return "success";
    if (status === "failed" || status === "cancelled")
        return "error";
    return "muted";
}
function cacheNote(run) {
    const hits = run.cacheHitTokens ?? 0;
    const misses = run.cacheMissTokens ?? 0;
    if (hits === 0 && misses === 0)
        return "";
    const total = hits + misses;
    return `cache=${total > 0 ? Math.round((hits / total) * 100) : 0}%`;
}
function firstLine(value, max) {
    const line = value.split(/\r?\n/)[0]?.trim() ?? "";
    return line.length > max ? `${line.slice(0, Math.max(0, max - 3))}...` : line;
}
function relativeRunTime(updatedAtMs) {
    if (!Number.isFinite(updatedAtMs) || updatedAtMs <= 0)
        return "";
    const seconds = Math.max(0, Math.floor((Date.now() - updatedAtMs) / 1000));
    if (seconds < 60)
        return `${seconds}s ago`;
    const minutes = Math.floor(seconds / 60);
    if (minutes < 60)
        return `${minutes}m ago`;
    const hours = Math.floor(minutes / 60);
    return `${hours}h ago`;
}
