import { formatUsageSnapshot, formatUsdCost } from "../../core/utils/format.js";
import { formatToolActivityText } from "./agent_activity_format.js";
import { buildBashAbortedView, buildBashBlockedView, buildBashExecutionView, buildBashRunningView, } from "./bash_execution.js";
import { buildEditBlockedView, buildEditSuccessView, buildViewImageBlockedView, buildViewImageSuccessView, buildWriteBlockedView, buildWriteSuccessView, } from "./file_execution.js";
import { buildSection, buildToolHeaderLine, inlineText, renderToolUiCompactText, renderToolUiTextLines, } from "./tool_output.js";
function buildSimpleToolRunningView(theme, label, target) {
    const { palette, text } = theme;
    const runningColor = (s) => palette.actionRunning(s);
    const header = buildToolHeaderLine({
        bulletStyle: runningColor,
        bullet: "⏵",
        label: `${label} (running)`,
        labelStyle: palette.textMuted,
        accent: inlineText(target),
        accentStyle: palette.brandAccent,
    });
    return {
        borderColor: runningColor,
        expanded: { title: runningColor(text.bold(`${label} ${target}`)) },
        compact: { header },
    };
}
function buildSimpleToolFinishedView(args) {
    const { theme, label, target, status, message } = args;
    const { palette, text } = theme;
    const successColor = (s) => palette.actionSuccess(s);
    const errorColor = (s) => palette.actionError(s);
    const isSuccess = status === "success";
    const borderColor = isSuccess ? successColor : errorColor;
    const header = buildToolHeaderLine({
        bulletStyle: borderColor,
        bullet: isSuccess ? "✓" : "✗",
        label: isSuccess ? label : `${label} failed`,
        labelStyle: palette.textMuted,
        accent: inlineText(target),
        accentStyle: palette.brandAccent,
    });
    const messageLine = message
        ? isSuccess
            ? palette.textMuted(message)
            : errorColor(message)
        : undefined;
    const section = buildSection(messageLine ? [messageLine] : []);
    return {
        borderColor,
        expanded: {
            title: borderColor(text.bold(`${label} ${target}`)),
            sections: section ? [section] : [],
        },
        compact: {
            header,
            extraText: messageLine ? `    ${messageLine}` : undefined,
        },
    };
}
function formatDiffReviewTitle(command) {
    const trimmed = command?.trim() ?? "";
    return trimmed || "current working tree";
}
function splitDiffToolUiText(text) {
    const trimmed = text?.trim();
    return trimmed ? trimmed.split(/\r?\n/).map((line) => line.trimEnd()) : [];
}
function buildDiffReviewAgentLines(reviewAgents) {
    const lines = [];
    reviewAgents.forEach((agent, index) => {
        lines.push(`${agent.threadId} (${agent.status})`);
        const activityText = formatToolActivityText(agent.lastActivityText ?? "");
        if (activityText) {
            lines.push(activityText);
        }
        lines.push(`${formatUsageSnapshot(agent.usage)} · ${formatUsdCost(agent.costTotal)}`);
        if (index < reviewAgents.length - 1) {
            lines.push("");
        }
    });
    return lines;
}
function buildDiffReviewUiText(args) {
    const diffToolLines = splitDiffToolUiText(args.diffToolUiText);
    const agentLines = buildDiffReviewAgentLines(args.reviewAgents);
    const separator = diffToolLines.length > 0 && agentLines.length > 0 ? [""] : [];
    const lines = [...diffToolLines, ...separator, ...agentLines];
    const fallbackLines = args.message ? [args.message] : [];
    const contentLines = lines.length > 0 ? lines : fallbackLines;
    const fileCount = args.reviewedFiles.length;
    const fileLabel = `${fileCount} reviewed file${fileCount === 1 ? "" : "s"}`;
    const statusLine = [args.status, fileLabel].filter(Boolean).join(" · ");
    return {
        previewLines: contentLines.map((text) => ({ text })),
        statusLine,
        fullLines: contentLines.map((text) => ({ text })),
    };
}
function buildDiffReviewRunningView(args) {
    const { theme, command, uiText } = args;
    const { palette, text } = theme;
    const runningColor = (s) => palette.actionRunning(s);
    const title = formatDiffReviewTitle(command);
    const header = buildToolHeaderLine({
        bulletStyle: runningColor,
        bullet: "⏵",
        label: "diff review",
        labelStyle: palette.textMuted,
        accent: inlineText(title),
        accentStyle: palette.brandAccent,
    });
    const compactText = uiText
        ? renderToolUiCompactText({
            uiText,
            theme,
            previewStyle: palette.textDim,
            statusStyle: palette.textMuted,
        })
        : undefined;
    const fullText = uiText
        ? renderToolUiTextLines({
            uiText,
            kind: "full",
            theme,
            baseStyle: palette.actionOutput,
        })
        : undefined;
    return {
        borderColor: runningColor,
        expanded: {
            title: runningColor(text.bold(`diff review ${title}`)),
            sections: fullText ? [fullText] : [],
        },
        compact: { header, extraText: compactText },
    };
}
function buildDiffReviewFinishedView(args) {
    const { theme, command, status, uiText } = args;
    const { palette, text } = theme;
    const isSuccess = status === "success";
    const isCancelled = status === "cancelled";
    const borderColor = isSuccess
        ? (s) => palette.actionSuccess(s)
        : isCancelled
            ? (s) => palette.statusWarn(s)
            : (s) => palette.actionError(s);
    const title = formatDiffReviewTitle(command);
    const label = isSuccess
        ? "diff reviewed"
        : isCancelled
            ? "diff review cancelled"
            : "diff review failed";
    const header = buildToolHeaderLine({
        bulletStyle: borderColor,
        bullet: isSuccess ? "✓" : "✗",
        label,
        labelStyle: palette.textMuted,
        accent: inlineText(title),
        accentStyle: palette.brandAccent,
    });
    const compactText = renderToolUiCompactText({
        uiText,
        theme,
        previewStyle: palette.textDim,
        statusStyle: palette.textMuted,
    });
    const fullText = renderToolUiTextLines({
        uiText,
        kind: "full",
        theme,
        baseStyle: palette.actionOutput,
    });
    return {
        borderColor,
        expanded: {
            title: borderColor(text.bold(`diff review ${title}`)),
            sections: fullText ? [fullText] : [],
        },
        compact: { header, extraText: compactText },
    };
}
function formatSubagentTitle(title) {
    const trimmed = title?.trim() ?? "";
    return trimmed || "(subagent)";
}
function ensureSubagentUiText(args) {
    if (args.uiText) {
        return args.uiText;
    }
    const fallbackLine = args.message?.trim() || (args.status === "success" ? "ok" : "failed");
    return {
        previewLines: [{ text: fallbackLine }],
        statusLine: args.statusLine,
        fullLines: [{ text: fallbackLine }],
    };
}
function buildSubagentRunningView(args) {
    const { theme, label, title } = args;
    const { palette, text } = theme;
    const runningColor = (s) => palette.actionRunning(s);
    const target = formatSubagentTitle(title);
    const header = buildToolHeaderLine({
        bulletStyle: runningColor,
        bullet: "⏵",
        label,
        labelStyle: palette.textMuted,
        accent: inlineText(target),
        accentStyle: palette.brandAccent,
    });
    return {
        borderColor: runningColor,
        expanded: { title: runningColor(text.bold(target)) },
        compact: { header },
    };
}
function buildSubagentFinishedView(args) {
    const { theme, label, failureLabel, title, status, uiText } = args;
    const { palette, text } = theme;
    const successColor = (s) => palette.actionSuccess(s);
    const errorColor = (s) => palette.actionError(s);
    const isSuccess = status === "success";
    const borderColor = isSuccess ? successColor : errorColor;
    const headerLabel = isSuccess ? label : failureLabel;
    const target = formatSubagentTitle(title);
    const header = buildToolHeaderLine({
        bulletStyle: borderColor,
        bullet: isSuccess ? "✓" : "✗",
        label: headerLabel,
        labelStyle: palette.textMuted,
        accent: inlineText(target),
        accentStyle: palette.brandAccent,
    });
    const compactText = renderToolUiCompactText({
        uiText,
        theme,
        previewStyle: palette.textDim,
        statusStyle: palette.textMuted,
    });
    const fullText = renderToolUiTextLines({
        uiText,
        kind: "full",
        theme,
        baseStyle: palette.actionOutput,
    });
    return {
        borderColor,
        expanded: {
            title: borderColor(text.bold(target)),
            sections: fullText ? [fullText] : [],
        },
        compact: {
            header,
            extraText: compactText,
        },
    };
}
export class ToolUiRegistry {
    renderers = new Map();
    register(type, renderer) {
        this.renderers.set(type, renderer);
    }
    render(event, context) {
        const renderer = this.renderers.get(event.type);
        if (!renderer) {
            throw new Error(`missing tool ui renderer for event type '${event.type}'.`);
        }
        return renderer(event, context);
    }
    renderBashAborted(command, reason, context) {
        const headerTarget = command.split(/\r?\n/)[0] ?? command;
        return buildBashAbortedView(context.theme, command, reason, headerTarget);
    }
}
export function createToolUiRegistry() {
    const registry = new ToolUiRegistry();
    registry.register("bash_started", (event, context) => {
        const uiEvent = event;
        return buildBashRunningView(context.theme, uiEvent.command, uiEvent.headerTarget);
    });
    registry.register("bash_execution", (event, context) => {
        const uiEvent = event;
        return buildBashExecutionView(context.theme, uiEvent.command, uiEvent.exitCode, uiEvent.uiText, uiEvent.labelOverride, uiEvent.headerTarget);
    });
    registry.register("bash_aborted", (event, context) => {
        const uiEvent = event;
        return buildBashAbortedView(context.theme, uiEvent.command, uiEvent.reason, uiEvent.headerTarget);
    });
    registry.register("bash_blocked", (event, context) => {
        const uiEvent = event;
        return buildBashBlockedView(context.theme, uiEvent.command, uiEvent.reason, uiEvent.headerTarget);
    });
    registry.register("diff_review_started", (event, context) => {
        const uiEvent = event;
        return buildDiffReviewRunningView({
            theme: context.theme,
            command: uiEvent.command,
        });
    });
    registry.register("diff_review_updated", (event, context) => {
        const uiEvent = event;
        return buildDiffReviewRunningView({
            theme: context.theme,
            command: uiEvent.command,
            uiText: buildDiffReviewUiText({
                diffToolUiText: uiEvent.diffToolUiText,
                reviewAgents: uiEvent.reviewAgents,
                reviewedFiles: uiEvent.reviewedFiles,
                status: "active",
            }),
        });
    });
    registry.register("diff_review_finished", (event, context) => {
        const uiEvent = event;
        return buildDiffReviewFinishedView({
            theme: context.theme,
            command: uiEvent.command,
            status: uiEvent.status,
            uiText: uiEvent.uiText ??
                buildDiffReviewUiText({
                    diffToolUiText: uiEvent.diffToolUiText,
                    reviewAgents: uiEvent.reviewAgents,
                    reviewedFiles: uiEvent.reviewedFiles,
                    message: uiEvent.message,
                    status: uiEvent.status,
                }),
        });
    });
    registry.register("diff_review_blocked", (event, context) => {
        const uiEvent = event;
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "diff review",
            target: uiEvent.headerTarget,
            status: "error",
            message: uiEvent.reason,
        });
    });
    registry.register("spawn_agent_started", (event, context) => {
        const uiEvent = event;
        return buildSubagentRunningView({
            theme: context.theme,
            label: "spawning",
            title: uiEvent.headerTarget,
        });
    });
    registry.register("spawn_agent_finished", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        return buildSubagentFinishedView({
            theme: context.theme,
            label: "spawned",
            failureLabel: "spawn failed",
            title,
            status: uiEvent.status,
            uiText: ensureSubagentUiText({
                uiText: uiEvent.uiText,
                status: uiEvent.status,
                message: uiEvent.message,
            }),
        });
    });
    registry.register("spawn_agent_blocked", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "spawn",
            target: title,
            status: "error",
            message: uiEvent.reason,
        });
    });
    registry.register("send_input_to_agent_started", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        return buildSubagentRunningView({
            theme: context.theme,
            label: "sending",
            title,
        });
    });
    registry.register("send_input_to_agent_finished", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        return buildSubagentFinishedView({
            theme: context.theme,
            label: "sent input",
            failureLabel: "send failed",
            title,
            status: uiEvent.status,
            uiText: ensureSubagentUiText({
                uiText: uiEvent.uiText,
                status: uiEvent.status,
                message: uiEvent.message,
            }),
        });
    });
    registry.register("send_input_to_agent_blocked", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "send input",
            target: title,
            status: "error",
            message: uiEvent.reason,
        });
    });
    registry.register("wait_for_agent_started", (event, context) => {
        const uiEvent = event;
        const title = uiEvent.headerTarget;
        return buildSubagentRunningView({
            theme: context.theme,
            label: "waiting",
            title,
        });
    });
    registry.register("wait_for_agent_finished", (event, context) => {
        const uiEvent = event;
        const title = uiEvent.headerTarget;
        return buildSubagentFinishedView({
            theme: context.theme,
            label: "waited",
            failureLabel: "wait failed",
            title,
            status: uiEvent.status,
            uiText: ensureSubagentUiText({
                uiText: uiEvent.uiText,
                status: uiEvent.status,
                message: uiEvent.message,
            }),
        });
    });
    registry.register("wait_for_agent_blocked", (event, context) => {
        const uiEvent = event;
        const title = uiEvent.headerTarget;
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "wait",
            target: title,
            status: "error",
            message: uiEvent.reason,
        });
    });
    registry.register("terminate_agent_started", (event, context) => {
        const uiEvent = event;
        return buildSubagentRunningView({
            theme: context.theme,
            label: "terminating",
            title: uiEvent.headerTarget,
        });
    });
    registry.register("terminate_agent_finished", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        const fallbackMessage = uiEvent.finalStatus && uiEvent.finalStatus !== "success"
            ? `final status: ${uiEvent.finalStatus}`
            : uiEvent.message;
        return buildSubagentFinishedView({
            theme: context.theme,
            label: "terminated",
            failureLabel: "terminate failed",
            title,
            status: uiEvent.status,
            uiText: ensureSubagentUiText({
                uiText: uiEvent.uiText,
                status: uiEvent.status,
                message: fallbackMessage,
            }),
        });
    });
    registry.register("terminate_agent_blocked", (event, context) => {
        const uiEvent = event;
        const title = formatSubagentTitle(uiEvent.headerTarget);
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "terminate",
            target: title,
            status: "error",
            message: uiEvent.reason,
        });
    });
    registry.register("web_search_started", (event, context) => {
        const uiEvent = event;
        return buildSimpleToolRunningView(context.theme, "web search", uiEvent.headerTarget);
    });
    registry.register("web_search_finished", (event, context) => {
        const uiEvent = event;
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "web search",
            target: uiEvent.headerTarget,
            status: uiEvent.status,
            message: uiEvent.message,
        });
    });
    registry.register("web_fetch_started", (event, context) => {
        const uiEvent = event;
        return buildSimpleToolRunningView(context.theme, "web fetch", uiEvent.headerTarget);
    });
    registry.register("web_fetch_finished", (event, context) => {
        const uiEvent = event;
        return buildSimpleToolFinishedView({
            theme: context.theme,
            label: "web fetch",
            target: uiEvent.headerTarget,
            status: uiEvent.status,
            message: uiEvent.message,
        });
    });
    registry.register("write_success", (event, context) => {
        const uiEvent = event;
        return buildWriteSuccessView(context.theme, uiEvent.path, uiEvent.uiText, uiEvent.headerTarget);
    });
    registry.register("write_blocked", (event, context) => {
        const uiEvent = event;
        return buildWriteBlockedView(context.theme, uiEvent.path, uiEvent.reason, uiEvent.headerTarget);
    });
    registry.register("edit_success", (event, context) => {
        const uiEvent = event;
        return buildEditSuccessView(context.theme, uiEvent.path, uiEvent.uiText, uiEvent.headerTarget);
    });
    registry.register("edit_blocked", (event, context) => {
        const uiEvent = event;
        return buildEditBlockedView(context.theme, uiEvent.path, uiEvent.reason, uiEvent.headerTarget);
    });
    registry.register("view_image_success", (event, context) => {
        const uiEvent = event;
        return buildViewImageSuccessView(context.theme, uiEvent.path, uiEvent.uiText, uiEvent.headerTarget);
    });
    registry.register("view_image_blocked", (event, context) => {
        const uiEvent = event;
        return buildViewImageBlockedView(context.theme, uiEvent.path, uiEvent.reason, uiEvent.headerTarget);
    });
    return registry;
}
//# sourceMappingURL=tool_ui_registry.js.map