import { visibleWidth } from "@earendil-works/pi-tui";
import { formatUsageSnapshot, formatUsdCost } from "../../core/utils/format.js";
import { formatAgentActivityText, formatAgentOutputText } from "./agent_activity_format.js";
import { truncateFromEndByWidthPreserveAnsi } from "./components/one_line_segments.js";
const MAX_PANEL_LINES = 6;
const MAX_PANEL_HISTORY = 200;
export class SubagentPanelComponent {
    theme;
    entries = new Map();
    selectedId;
    constructor(theme) {
        this.theme = theme;
    }
    setTheme(theme) {
        this.theme = theme;
    }
    reset() {
        this.entries.clear();
        this.selectedId = undefined;
    }
    hasActiveSubagents() {
        return this.getRunningEntries().length > 0;
    }
    handleEvent(event) {
        if (event.type === "subagent_spawned") {
            const state = event.state;
            this.entries.set(state.id, this.buildEntry(state));
            if (!this.selectedId || this.entries.get(this.selectedId)?.status !== "running") {
                this.selectedId = state.id;
            }
            return;
        }
        if (event.type === "subagent_finished") {
            const entry = this.entries.get(event.state.id);
            if (!entry)
                return;
            this.applySnapshot(entry, event.state);
            const finalText = event.state.finalText?.trim();
            if (finalText && !this.hasOutputLine(entry, finalText)) {
                entry.lines.push({ kind: "output", text: event.state.finalText ?? finalText });
                if (entry.lines.length > MAX_PANEL_HISTORY) {
                    entry.lines.shift();
                }
            }
            if (this.selectedId === entry.id && entry.status !== "running") {
                this.selectedId = this.getFirstRunningId();
            }
            return;
        }
        if (event.type === "subagent_abort_requested") {
            const entry = this.entries.get(event.id);
            if (!entry)
                return;
            entry.abortRequested = true;
            return;
        }
        if (event.type === "subagent_progress") {
            const entry = this.entries.get(event.id);
            if (!entry)
                return;
            entry.costTotal = event.costTotal;
            entry.turns = event.turns;
            entry.toolCalls = event.toolCalls;
            entry.usage = event.usage;
            const text = event.text.trim();
            if (text) {
                entry.lines.push({ kind: "progress", text });
                if (entry.lines.length > MAX_PANEL_HISTORY) {
                    entry.lines.shift();
                }
            }
            return;
        }
        if (event.type === "subagent_emit_output") {
            const entry = this.entries.get(event.id);
            if (!entry)
                return;
            const text = event.text.trim();
            if (text) {
                entry.lines.push({ kind: "output", text });
                if (entry.lines.length > MAX_PANEL_HISTORY) {
                    entry.lines.shift();
                }
            }
        }
    }
    getCostTotal() {
        let total = 0;
        for (const entry of this.entries.values()) {
            total += entry.costTotal;
        }
        return total;
    }
    getSelectedId() {
        if (!this.selectedId)
            return undefined;
        const entry = this.entries.get(this.selectedId);
        if (!entry || entry.status !== "running")
            return undefined;
        return this.selectedId;
    }
    cycleSelection(direction) {
        const activeIds = this.getRunningEntries().map((entry) => entry.id);
        if (activeIds.length === 0) {
            this.selectedId = undefined;
            return undefined;
        }
        const currentIndex = this.selectedId ? activeIds.indexOf(this.selectedId) : -1;
        const nextIndex = currentIndex === -1 ? 0 : (currentIndex + direction + activeIds.length) % activeIds.length;
        this.selectedId = activeIds[nextIndex];
        return this.selectedId;
    }
    invalidate() { }
    render(width) {
        if (width <= 0)
            return [""];
        const runningEntries = this.getRunningEntries();
        if (runningEntries.length === 0)
            return [];
        const { entry, index } = this.resolveSelectedEntry(runningEntries);
        const lines = [];
        lines.push(this.buildHeaderLine(entry));
        const outputLines = this.buildOutputLines(entry);
        lines.push(...outputLines);
        lines.push(this.buildStatusLine(entry));
        lines.push(this.buildFooterLine(index + 1, runningEntries.length));
        return lines.map((line) => this.fitLine(line, width));
    }
    resolveSelectedEntry(runningEntries) {
        let index = this.selectedId
            ? runningEntries.findIndex((entry) => entry.id === this.selectedId)
            : -1;
        if (index === -1) {
            this.selectedId = runningEntries[0]?.id;
            index = 0;
        }
        return { entry: runningEntries[index], index };
    }
    buildHeaderLine(entry) {
        const { palette } = this.theme;
        const name = entry.name.trim();
        const title = entry.title.trim();
        const arrowStyle = name ? palette.textDim : palette.brandAccent;
        const arrow = arrowStyle("⏵");
        if (name && title) {
            return `${arrow} ${palette.textDim(name)} ${palette.brandAccent(title)}`;
        }
        if (name) {
            return `${arrow} ${palette.textDim(name)}`;
        }
        return `${arrow} ${palette.brandAccent(title || "(subagent)")}`;
    }
    buildOutputLines(entry) {
        const { palette } = this.theme;
        const formattedLines = entry.lines
            .map((line) => line.kind === "output"
            ? formatAgentOutputText(line.text)
            : formatAgentActivityText(line.text))
            .filter((line) => Boolean(line?.length));
        const recentLines = formattedLines.slice(-MAX_PANEL_LINES);
        const output = [];
        for (const line of recentLines) {
            output.push(palette.actionOutput(`  · ${line}`));
        }
        for (let i = recentLines.length; i < MAX_PANEL_LINES; i++) {
            output.push("");
        }
        return output;
    }
    buildStatusLine(entry) {
        const { palette } = this.theme;
        const contextUsage = formatUsageSnapshot(entry.usage);
        const cost = formatUsdCost(entry.costTotal);
        return palette.textMuted(`${contextUsage} · ${cost}`);
    }
    buildFooterLine(index, total) {
        const { palette } = this.theme;
        const parts = [`(${index}/${total})`];
        if (total > 1) {
            parts.push("alt+down to cycle");
        }
        parts.push("ctrl+g to terminate");
        return palette.textMuted(parts.join(" · "));
    }
    fitLine(line, width) {
        const truncated = truncateFromEndByWidthPreserveAnsi(line, width);
        const pad = Math.max(0, width - visibleWidth(truncated));
        return `${truncated}${" ".repeat(pad)}`;
    }
    getRunningEntries() {
        return [...this.entries.values()].filter((entry) => entry.status === "running");
    }
    getFirstRunningId() {
        for (const entry of this.entries.values()) {
            if (entry.status === "running")
                return entry.id;
        }
        return undefined;
    }
    hasOutputLine(entry, text) {
        const trimmed = text.trim();
        if (!trimmed)
            return true;
        return entry.lines.some((line) => line.kind === "output" && line.text.trim() === trimmed);
    }
    buildEntry(state) {
        return {
            id: state.id,
            name: state.name,
            title: state.title,
            status: state.status,
            abortRequested: Boolean(state.abortRequested),
            costTotal: state.costTotal,
            turns: state.turns,
            toolCalls: state.toolCalls,
            usage: state.usage,
            lines: [],
        };
    }
    applySnapshot(entry, state) {
        entry.status = state.status;
        entry.abortRequested = Boolean(state.abortRequested);
        entry.costTotal = state.costTotal;
        entry.turns = state.turns;
        entry.toolCalls = state.toolCalls;
        entry.usage = state.usage;
        entry.name = state.name;
        entry.title = state.title;
    }
}
//# sourceMappingURL=subagent_panel.js.map