/**
 * Slash command registry for interactive mode.
 *
 * Each command is a standalone handler function that receives a CommandContext.
 * Commands are testable in isolation — no TUI or InteractiveMode instance required.
 */
import { computeSessionCreditsUsed } from '../../app/credits/session-credits.js';
import { getLastAssistantText } from '../../app/session/assistant-text.js';
import { BUDGET_USAGE_TEXT } from '../../app/session/budget-command.js';
import { Spacer, Text } from '../../tui/index.js';
import { getChangelogPath, parseChangelog } from '../changelog.js';
import { copyToClipboard } from '../clipboard/clipboard.js';
import { buildChangelogComponents, buildHotkeysComponents, buildSessionInfoText, buildSkillsComponents, buildSkillsText } from '../presentation/slash-command-rendering.js';
import { theme } from '../theme/runtime.js';
import { collabCommand } from './collab-command.js';
// ============================================================================
// Command Implementations
// ============================================================================
export function copyCommand(_args, ctx) {
    const text = getLastAssistantText(ctx.session.messages);
    if (!text) {
        ctx.feedback.showError('No agent messages to copy yet.');
        return;
    }
    try {
        copyToClipboard(text);
        ctx.feedback.showStatus('Copied last agent message to clipboard');
    }
    catch (error) {
        ctx.feedback.showError(error instanceof Error ? error.message : String(error));
    }
}
export function nameCommand(args, ctx) {
    const name = args.trim();
    if (!name) {
        const currentName = ctx.sessionManager.getSessionName();
        if (currentName) {
            ctx.chat.addChild(new Spacer(1));
            ctx.chat.addChild(new Text(theme.fg('dim', `Session name: ${currentName}`), 1, 0));
        }
        else {
            ctx.feedback.showWarning('Usage: /name <name>');
        }
        ctx.requestRender();
        return;
    }
    ctx.sessionManager.appendSessionInfo(name);
    ctx.updateTerminalTitle();
    ctx.chat.addChild(new Spacer(1));
    ctx.chat.addChild(new Text(theme.fg('dim', `Session name set: ${name}`), 1, 0));
    ctx.requestRender();
}
export function sessionCommand(_args, ctx) {
    const stats = ctx.session.getSessionStats();
    const creditBalance = ctx.footerDataProvider.getCreditBalance();
    const sessionCreditsUsed = creditBalance && !creditBalance.hasTeamBilling
        ? computeSessionCreditsUsed(ctx.session.messages, ctx.session.modelRegistry)
        : null;
    const info = buildSessionInfoText({
        sessionName: ctx.sessionManager.getSessionName() ?? undefined,
        sessionFile: stats.sessionFile ?? null,
        sessionId: stats.sessionId,
        userMessages: stats.userMessages,
        assistantMessages: stats.assistantMessages,
        toolCalls: stats.toolCalls,
        toolResults: stats.toolResults,
        totalMessages: stats.totalMessages,
        tokens: stats.tokens,
        cost: stats.cost,
        creditBalance: creditBalance && sessionCreditsUsed !== null
            ? {
                isUnlimited: creditBalance.isUnlimited,
                creditsUsed: sessionCreditsUsed
            }
            : null,
        usesCredits: ctx.footerDataProvider.usesCredits
    });
    ctx.chat.addChild(new Spacer(1));
    ctx.chat.addChild(new Text(info, 1, 0));
    ctx.requestRender();
}
export async function budgetCommand(args, ctx) {
    const trimmed = args.trim();
    if (!trimmed) {
        ctx.feedback.showWarning(BUDGET_USAGE_TEXT);
        return;
    }
    try {
        await ctx.session.prompt(`/budget ${trimmed}`);
    }
    catch (error) {
        ctx.feedback.showError(error instanceof Error ? error.message : String(error));
    }
}
export async function autonomousCommand(args, ctx) {
    const trimmed = args.trim();
    if (!trimmed) {
        ctx.feedback.showWarning('Usage: /autonomous <task>');
        return;
    }
    try {
        await ctx.session.startAutonomous(trimmed);
    }
    catch (error) {
        ctx.feedback.showError(error instanceof Error ? error.message : String(error));
    }
}
export function changelogCommand(_args, ctx) {
    const changelogPath = getChangelogPath();
    const allEntries = parseChangelog(changelogPath);
    const changelogMarkdown = allEntries.length > 0
        ? allEntries
            .reverse()
            .map((e) => e.content)
            .join('\n\n')
        : 'No changelog entries found.';
    for (const component of buildChangelogComponents(changelogMarkdown, ctx.getMarkdownTheme())) {
        ctx.chat.addChild(component);
    }
    ctx.requestRender();
}
export function hotkeysCommand(_args, ctx) {
    for (const component of buildHotkeysComponents(ctx.keybindings, ctx.getMarkdownTheme())) {
        ctx.chat.addChild(component);
    }
    ctx.requestRender();
}
export function skillsCommand(_args, ctx) {
    if (ctx.showSkillsSelector) {
        ctx.showSkillsSelector();
        return;
    }
    const resourceLoader = ctx.session.resourceLoader;
    const skillsResult = resourceLoader.getSkills();
    const skills = skillsResult.skills;
    const skillsText = skills.length === 0
        ? null
        : (() => {
            const metadata = resourceLoader.getPathMetadata();
            const groups = ctx.resourceDisplay.buildScopeGroups(skills.map((skill) => skill.filePath), metadata);
            return buildSkillsText(skills, groups, ctx.resourceDisplay.formatDisplayPath);
        })();
    for (const component of buildSkillsComponents(skillsText)) {
        ctx.chat.addChild(component);
    }
    ctx.requestRender();
}
export function hideThinkingCommand(_args, ctx) {
    const current = ctx.settingsManager.getHideThinkingBlock();
    const next = !current;
    ctx.settingsManager.setHideThinkingBlock(next);
    // Chat rebuild is handled by InteractiveMode after this returns — see rebuildAfter flag.
    ctx.feedback.showStatus(`Thinking blocks: ${next ? 'hidden' : 'visible'}`);
}
// ============================================================================
// Registry builder
// ============================================================================
/** Commands that need chat to be rebuilt after execution (e.g. thinking toggle). */
export const REBUILD_CHAT_COMMANDS = new Set(['hide-thinking']);
/**
 * Build the default command registry.
 * Commands that need deep InteractiveMode access (clear, reload, compact, model,
 * thinking, settings, tree, resume, login, logout, quit, download-skills, upload-skills)
 * are registered by InteractiveMode itself via registerCommand().
 */
export function buildDefaultCommands(additionalCommands = []) {
    const commands = new Map();
    commands.set('copy', copyCommand);
    commands.set('name', nameCommand);
    commands.set('session', sessionCommand);
    commands.set('budget', budgetCommand);
    commands.set('autonomous', autonomousCommand);
    commands.set('changelog', changelogCommand);
    commands.set('hotkeys', hotkeysCommand);
    commands.set('skills', skillsCommand);
    commands.set('hide-thinking', hideThinkingCommand);
    commands.set('collab', collabCommand);
    for (const command of additionalCommands) {
        commands.set(command.name, command.handler);
    }
    return commands;
}
//# sourceMappingURL=slash-commands.js.map