import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import { Box, Text } from 'ink';
import { memo } from 'react';
import AssistantMessage from '../components/assistant-message.js';
import AssistantReasoning from '../components/assistant-reasoning.js';
import { InfoMessage } from '../components/message-box.js';
import UserMessage from '../components/user-message.js';
import { useTerminalWidth } from '../hooks/useTerminalWidth.js';
import { useTheme } from '../hooks/useTheme.js';
import { generateKey } from '../session/key-generator.js';
import { parseToolArguments } from '../utils/tool-args-parser.js';
/**
 * Cap on how many trailing messages are replayed into scrollback on resume.
 * The point of the replay is recognition ("did I resume the right session?"),
 * not a full re-render of a possibly huge history. Older messages are still
 * loaded into model context — only their UI replay is omitted, with a note.
 */
const MAX_REPLAYED_MESSAGES = 60;
/** Length past which a tool descriptor (command, query, etc.) is truncated. */
const MAX_DESCRIPTOR_LENGTH = 80;
function truncate(value, max = MAX_DESCRIPTOR_LENGTH) {
    const single = value.replace(/\s+/g, ' ').trim();
    return single.length > max ? `${single.slice(0, max - 1)}…` : single;
}
/**
 * Derive a short, human-readable descriptor for a tool call from its arguments
 * (file path, command, search pattern, etc.). Display-only: parsed leniently so
 * a malformed arg string never throws while replaying history.
 */
function describeToolCall(toolCall) {
    const name = toolCall.function.name;
    const args = parseToolArguments(toolCall.function.arguments);
    const str = (key) => typeof args[key] === 'string' ? args[key] : '';
    switch (name) {
        case 'read_file':
        case 'write_file':
        case 'string_replace':
        case 'list_directory':
            return str('path') || str('file_path');
        case 'execute_bash':
            return str('command');
        case 'search_file_contents':
            return str('pattern') || str('query');
        case 'find_files':
            return str('pattern') || str('name') || str('query');
        case 'web_search':
            return str('query');
        case 'fetch_url':
            return str('url');
        case 'agent': {
            const type = str('subagent_type');
            const desc = str('description');
            return [type, desc].filter(Boolean).join(': ');
        }
        default: {
            // Fall back to a compact JSON-ish view of the args so unknown/custom
            // tools still show something identifying.
            const keys = Object.keys(args);
            if (keys.length === 0)
                return '';
            const first = args[keys[0]];
            return typeof first === 'string' ? first : keys.join(', ');
        }
    }
}
/** True when a tool result string represents an error the user should notice. */
function isErrorResult(content) {
    if (!content)
        return false;
    return (content.startsWith('Error: ') || content.startsWith('⚒ Validation failed'));
}
/**
 * Compact one-line summary of a historical tool call and its result. Mirrors the
 * live compact-tool look (the ⚒ glyph in tool color) without re-running the
 * tool's formatter — replaying history must be side-effect free (formatters can
 * touch VS Code, the filesystem, etc.) and cheap.
 */
const HistoryToolSummary = memo(function HistoryToolSummary({ toolCall, resultContent, }) {
    const { colors } = useTheme();
    const boxWidth = useTerminalWidth();
    const descriptor = describeToolCall(toolCall);
    const failed = isErrorResult(resultContent);
    const label = descriptor
        ? `${toolCall.function.name}  ${truncate(descriptor)}`
        : toolCall.function.name;
    return (_jsx(Box, { width: boxWidth, children: _jsxs(Text, { color: failed ? colors.error : colors.tool, children: ['⚒', " ", label, failed ? ' (failed)' : ''] }) }));
});
/**
 * Convert a persisted session's message history into a list of components that
 * replay the conversation in scrollback when a session is resumed.
 *
 * Replay is deliberately faithful-but-light: user prompts and assistant text
 * render in full (so the session is recognizable), reasoning renders collapsed,
 * and tool calls render as compact one-liners paired with their result status.
 * Tool formatters are intentionally NOT invoked (they can have side effects and
 * dump large output). Only the trailing `MAX_REPLAYED_MESSAGES` are replayed;
 * the rest are summarized with a leading note.
 *
 * @param messages - The full persisted message array.
 * @param model - The model label to show on assistant messages.
 */
export function buildSessionHistoryComponents(messages, model) {
    const components = [];
    // Map every tool result by its tool_call_id across the FULL history, so an
    // in-window assistant tool call can still find its result even if windowing
    // trims nearby messages.
    const resultsById = new Map();
    for (const message of messages) {
        if (message.role === 'tool' && message.tool_call_id) {
            resultsById.set(message.tool_call_id, message.content);
        }
    }
    // Replay only the trailing window; note how many earlier messages are hidden.
    const hiddenCount = Math.max(0, messages.length - MAX_REPLAYED_MESSAGES);
    const replayed = hiddenCount > 0 ? messages.slice(hiddenCount) : messages;
    if (hiddenCount > 0) {
        components.push(_jsx(InfoMessage, { message: `${hiddenCount} earlier message${hiddenCount === 1 ? '' : 's'} hidden (still in context). Showing the most recent ${replayed.length}.`, hideBox: true }, generateKey('resume-history-truncated')));
    }
    for (const message of replayed) {
        switch (message.role) {
            case 'user':
                if (message.content.trim()) {
                    components.push(_jsx(UserMessage, { message: message.content }, generateKey('resume-user')));
                }
                break;
            case 'assistant': {
                if (message.reasoning?.trim()) {
                    components.push(_jsx(AssistantReasoning, { reasoning: message.reasoning, expand: false }, generateKey('resume-reasoning')));
                }
                if (message.content.trim()) {
                    components.push(_jsx(AssistantMessage, { message: message.content, model: model }, generateKey('resume-assistant')));
                }
                if (message.tool_calls && message.tool_calls.length > 0) {
                    components.push(_jsx(Box, { flexDirection: "column", marginBottom: 1, children: message.tool_calls.map(toolCall => (_jsx(HistoryToolSummary, { toolCall: toolCall, resultContent: resultsById.get(toolCall.id) }, toolCall.id))) }, generateKey('resume-tools')));
                }
                break;
            }
            // Tool results are folded into their assistant tool-call summary above;
            // system messages are never displayed.
            default:
                break;
        }
    }
    return components;
}
//# sourceMappingURL=session-history-renderer.js.map