import { acp, resolveOutputFormat, text } from "toolcraft-design";
import { toRenderKind } from "./session-update-converter.js";
function writeLine(line) {
    acp.getAcpWriter()(line);
}
/**
 * Render a single ACP event using design-system rendering primitives.
 *
 * Example:
 * `await renderAcpStream(spawnStreaming(...).events)`
 */
export function renderAcpEvent(event) {
    switch (event.event) {
        case "session_start":
            return;
        case "agent_message":
            acp.renderAgentMessage(event.text);
            return;
        case "tool_start":
            acp.renderToolStart(event.kind, event.title);
            return;
        case "tool_complete":
            acp.renderToolComplete(event.kind);
            return;
        case "reasoning":
            acp.renderReasoning(event.text);
            return;
        case "usage":
            acp.renderUsage({
                input: event.inputTokens,
                output: event.outputTokens,
                cached: event.cachedTokens,
                costUsd: event.costUsd
            });
            return;
        case "permission_rejected":
            acp.renderPermissionRejected(event.title);
            return;
        case "error":
            acp.renderError((() => {
                const { message, stack } = event;
                return typeof stack === "string" && stack.length > 0
                    ? `${message}\n${stack}`
                    : message;
            })());
            return;
        case "spawn_result":
            if (resolveOutputFormat() === "json") {
                writeLine(JSON.stringify(event));
            }
            return;
        default:
            writeLine(text.muted(event.event));
            return;
    }
}
export async function renderAcpStream(events) {
    let messageBuffer = "";
    let reasoningBuffer = "";
    function flushMessageBuffer() {
        if (messageBuffer.length > 0) {
            acp.renderAgentMessage(messageBuffer);
            messageBuffer = "";
        }
    }
    function flushReasoningBuffer() {
        if (reasoningBuffer.length > 0) {
            acp.renderReasoning(reasoningBuffer);
            reasoningBuffer = "";
        }
    }
    function flushAll() {
        flushMessageBuffer();
        flushReasoningBuffer();
    }
    for await (const event of events) {
        if (event.event === "agent_message") {
            flushReasoningBuffer();
            messageBuffer += event.text;
            continue;
        }
        if (event.event === "reasoning") {
            flushMessageBuffer();
            reasoningBuffer += event.text;
            continue;
        }
        flushAll();
        renderAcpEvent(event);
    }
    flushAll();
}
function renderSessionUpdate(update) {
    if (update.sessionUpdate === "agent_message_chunk" && update.content.type === "text") {
        acp.renderAgentMessage(update.content.text);
        return;
    }
    if (update.sessionUpdate === "agent_thought_chunk" && update.content.type === "text") {
        acp.renderReasoning(update.content.text);
        return;
    }
    if (update.sessionUpdate === "tool_call") {
        acp.renderToolStart(toRenderKind(update.kind), update.title);
        return;
    }
    if (update.sessionUpdate === "tool_call_update") {
        const status = update.status;
        if (status === "completed" || status === "failed" || status === "cancelled") {
            acp.renderToolComplete(toRenderKind(update.kind ?? undefined));
        }
        return;
    }
    if (update.sessionUpdate === "usage_update") {
        const meta = (update._meta ?? {});
        const input = typeof meta.inputTokens === "number" ? meta.inputTokens : update.used;
        const output = typeof meta.outputTokens === "number" ? meta.outputTokens : 0;
        const cached = typeof meta.cachedTokens === "number"
            ? meta.cachedTokens
            : Math.max(0, update.size - update.used);
        acp.renderUsage({
            input,
            output,
            ...(cached > 0 ? { cached } : {}),
            ...(update.cost?.currency === "USD" ? { costUsd: update.cost.amount } : {}),
        });
        return;
    }
}
export async function renderSessionUpdateStream(updates) {
    let messageBuffer = "";
    let reasoningBuffer = "";
    function flushMessageBuffer() {
        if (messageBuffer.length > 0) {
            acp.renderAgentMessage(messageBuffer);
            messageBuffer = "";
        }
    }
    function flushReasoningBuffer() {
        if (reasoningBuffer.length > 0) {
            acp.renderReasoning(reasoningBuffer);
            reasoningBuffer = "";
        }
    }
    function flushAll() {
        flushMessageBuffer();
        flushReasoningBuffer();
    }
    for await (const update of updates) {
        if (update.sessionUpdate === "agent_message_chunk" && update.content.type === "text") {
            flushReasoningBuffer();
            messageBuffer += update.content.text;
            continue;
        }
        if (update.sessionUpdate === "agent_thought_chunk" && update.content.type === "text") {
            flushMessageBuffer();
            reasoningBuffer += update.content.text;
            continue;
        }
        flushAll();
        renderSessionUpdate(update);
    }
    flushAll();
}
