import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@sheason/pi-tui";
import { messageSourceHeaderPrefix } from "../agent/types.js";
export function isDynamicMcpToolName(name) {
    return name.startsWith("mcp__");
}
export function appendDPiExtensionFactory(options, factory) {
    return {
        ...(options ?? {}),
        extensionFactories: [...(options?.extensionFactories ?? []), factory],
    };
}
// =============================================================================
// Sheason customizations: date removal + error bar
// =============================================================================
function removeDateFromSystemPrompt(systemPrompt) {
    return systemPrompt
        .split("\n")
        .filter((line) => !line.startsWith("Current date:"))
        .join("\n");
}
const MAX_COLLAPSED_LINES = 4;
class HelperMessageBlockComponent {
    _messages = [];
    _expanded = false;
    get messages() {
        return this._messages;
    }
    get expanded() {
        return this._expanded;
    }
    pushMessage(message) {
        this._messages.push(message);
    }
    clear() {
        this._messages = [];
        this._expanded = false;
    }
    toggleExpanded() {
        this._expanded = !this._expanded;
    }
    dismissLast() {
        this._messages.pop();
        if (this._messages.length === 0) {
            this._expanded = false;
        }
    }
    get hasMessages() {
        return this._messages.length > 0;
    }
    invalidate() {
        // No cached state
    }
    render(_width) {
        // Theme is not available here; use createThemedComponent() instead
        return [];
    }
}
/** Create a Component that wraps errorBar with theme access at render time */
function createThemedErrorBarComponent(errorBar) {
    return (theme) => {
        const component = {
            invalidate() {
                // No cached state
            },
            render(width) {
                if (errorBar.messages.length === 0) {
                    return [];
                }
                const latest = errorBar.messages[errorBar.messages.length - 1];
                const colorFn = latest.level === "error" ? "error" : "warning";
                const prefix = latest.level === "error" ? "Error: " : "Warning: ";
                const fullText = prefix + latest.text;
                const contentWidth = Math.max(1, width - 2);
                const wrappedLines = wrapTextWithAnsi(fullText, contentWidth);
                let displayLines;
                let showExpandHint = false;
                if (!errorBar.expanded && wrappedLines.length > MAX_COLLAPSED_LINES) {
                    displayLines = wrappedLines.slice(0, MAX_COLLAPSED_LINES);
                    showExpandHint = true;
                }
                else {
                    displayLines = wrappedLines;
                }
                const lines = [];
                // Top separator
                lines.push(theme.fg(colorFn, "─".repeat(width)));
                // Content lines
                for (const line of displayLines) {
                    const padded = ` ${line}`;
                    const visiblePad = Math.max(0, width - visibleWidth(padded));
                    lines.push(theme.fg(colorFn, padded + " ".repeat(visiblePad)));
                }
                // Expand hint
                if (showExpandHint) {
                    const hint = `  ... Ctrl+E to expand full error (${wrappedLines.length} lines)`;
                    lines.push(truncateToWidth(theme.fg("dim", hint), width));
                }
                else if (errorBar.expanded) {
                    const hint = "  Ctrl+E to collapse / Esc to dismiss";
                    lines.push(truncateToWidth(theme.fg("dim", hint), width));
                }
                // Multiple messages indicator
                if (errorBar.messages.length > 1) {
                    const countHint = `  (${errorBar.messages.length} messages)`;
                    lines.push(truncateToWidth(theme.fg("dim", countHint), width));
                }
                return lines;
            },
        };
        return component;
    };
}
export function createDPiExtensionFactory(options) {
    const tools = [...options.tools];
    return (pi) => {
        for (const tool of tools) {
            pi.registerTool(tool);
        }
        pi.on("context", (event) => ({
            messages: event.messages.map(addMessageSourceHeader),
        }));
        pi.on("session_before_compact", (event) => {
            addMessageSourceHeadersToCompactionPreparation(event.preparation);
        });
        pi.on("session_before_tree", (event) => {
            addMessageSourceHeadersToTreePreparation(event.preparation);
        });
        // --- Sheason customizations ---
        // 1. Remove date from system prompt
        pi.on("before_agent_start", (event) => {
            const cleaned = removeDateFromSystemPrompt(event.systemPrompt);
            if (cleaned !== event.systemPrompt) {
                return { systemPrompt: cleaned };
            }
            return undefined;
        });
        // 2. HelperMessageBlock — persistent error bar widget
        const errorBar = new HelperMessageBlockComponent();
        const themedErrorBarFactory = createThemedErrorBarComponent(errorBar);
        function updateErrorBarWidget(ui) {
            if (!errorBar.hasMessages) {
                ui.setWidget("sheason-error-bar", undefined, { placement: "belowEditor" });
                return;
            }
            ui.setWidget("sheason-error-bar", ((_tui, theme) => themedErrorBarFactory(theme)), {
                placement: "belowEditor",
            });
        }
        pi.on("message_end", (event, ctx) => {
            if (event.message.role !== "assistant")
                return;
            const msg = event.message;
            if (msg.stopReason === "error" || msg.stopReason === "aborted") {
                const errorMsg = msg.errorMessage || (msg.stopReason === "aborted" ? "Operation aborted" : "Unknown error");
                errorBar.pushMessage({ text: errorMsg, level: "error", timestamp: Date.now() });
                if (ctx.hasUI)
                    updateErrorBarWidget(ctx.ui);
            }
            else {
                errorBar.clear();
                if (ctx.hasUI)
                    updateErrorBarWidget(ctx.ui);
            }
        });
        pi.on("tool_execution_end", (event, ctx) => {
            if (!event.isError)
                return;
            const resultText = event.result?.content
                ?.filter((c) => c.type === "text")
                ?.map((c) => c.text ?? "")
                ?.join("\n")
                ?.trim() || `Tool "${event.toolName}" failed`;
            errorBar.pushMessage({ text: resultText, level: "warning", timestamp: Date.now() });
            if (ctx.hasUI)
                updateErrorBarWidget(ctx.ui);
        });
        pi.on("agent_start", (_event, ctx) => {
            errorBar.clear();
            if (ctx.hasUI)
                updateErrorBarWidget(ctx.ui);
        });
        pi.registerShortcut("ctrl+e", {
            description: "Expand/collapse error details",
            handler: (ctx) => {
                if (!errorBar.hasMessages)
                    return;
                errorBar.toggleExpanded();
                if (ctx.hasUI)
                    updateErrorBarWidget(ctx.ui);
            },
        });
        pi.on("session_start", (_event, ctx) => {
            if (!ctx.hasUI)
                return;
            ctx.ui.onTerminalInput((data) => {
                if (data === "\x1b" && errorBar.hasMessages && errorBar.expanded) {
                    errorBar.dismissLast();
                    updateErrorBarWidget(ctx.ui);
                    return { consume: true };
                }
                return undefined;
            });
        });
    };
}
export function addMessageSourceHeadersToCompactionPreparation(preparation) {
    preparation.messagesToSummarize = preparation.messagesToSummarize.map(addMessageSourceHeader);
    preparation.turnPrefixMessages = preparation.turnPrefixMessages.map(addMessageSourceHeader);
}
export function addMessageSourceHeadersToTreePreparation(preparation) {
    preparation.entriesToSummarize.splice(0, preparation.entriesToSummarize.length, ...preparation.entriesToSummarize.map(addMessageSourceHeaderToEntry));
}
function addMessageSourceHeaderToEntry(entry) {
    if (entry.type !== "message") {
        return entry;
    }
    const message = addMessageSourceHeader(entry.message);
    return message === entry.message ? entry : { ...entry, message };
}
export function addMessageSourceHeader(message) {
    if (message.role !== "user") {
        return message;
    }
    const sourceAwareMessage = message;
    const source = sourceAwareMessage.messageSource;
    if (!source) {
        return message;
    }
    const { messageSource: _messageSource, ...messageWithoutSource } = sourceAwareMessage;
    const prefix = messageSourceHeaderPrefix(source);
    if (typeof sourceAwareMessage.content === "string") {
        if (sourceAwareMessage.content.startsWith(prefix) || sourceAwareMessage.content.startsWith("[message source:")) {
            return messageWithoutSource;
        }
        return { ...messageWithoutSource, content: `${prefix}${sourceAwareMessage.content}` };
    }
    const parts = [...sourceAwareMessage.content];
    const textIndex = parts.findIndex(isTextContent);
    if (textIndex === -1) {
        return {
            ...messageWithoutSource,
            content: [{ type: "text", text: prefix }, ...parts],
        };
    }
    const textPart = parts[textIndex];
    if (!isTextContent(textPart)) {
        return messageWithoutSource;
    }
    if (textPart.text.startsWith(prefix) || textPart.text.startsWith("[message source:")) {
        return messageWithoutSource;
    }
    parts[textIndex] = { ...textPart, text: `${prefix}${textPart.text}` };
    return { ...messageWithoutSource, content: parts };
}
function isTextContent(content) {
    return content.type === "text" && "text" in content && typeof content.text === "string";
}
//# sourceMappingURL=d-pi-extension.js.map