import { isServerRuntime } from '../utils/api.js';
/**
 * replay.ts — Replay events from a V3 agent run step-by-step.
 */
import chalk from 'chalk';
import { createRequire } from 'node:module';
import { createSpinner, CH } from '../utils/logger.js';
const require = createRequire(import.meta.url);
export class ReplayCommand {
    config;
    logger;
    constructor(config, logger) {
        this.config = config;
        this.logger = logger;
    }
    getHeaders() {
        const headers = { 'Content-Type': 'application/json' };
        const token = process.env.VIGTHORIA_TOKEN ||
            process.env.VIGTHORIA_AUTH_TOKEN ||
            this.config.get('authToken');
        if (token) {
            headers['Authorization'] = `Bearer ${token}`;
            headers['Cookie'] = `vigthoria-auth-token=${token}`;
        }
        const serviceKey = process.env.VIGTHORIA_V3_SERVICE_KEY;
        if (serviceKey)
            headers['X-Service-Key'] = serviceKey;
        return headers;
    }
    getBaseUrl() {
        const configuredApiUrl = String(this.config.get('apiUrl') || 'https://coder.vigthoria.io').replace(/\/$/, '');
        const allowLocal = isServerRuntime() && process.env.VIGTHORIA_ALLOW_LOCAL_V3_AGENT === '1';
        return (process.env.VIGTHORIA_V3_AGENT_URL ||
            process.env.V3_AGENT_URL ||
            (allowLocal ? 'http://127.0.0.1:8030' : null) ||
            configuredApiUrl);
    }
    resolveWorkspaceRoot(project) {
        if (/^[a-zA-Z]:[\\/]/.test(project) || /^\\\\/.test(project))
            return '';
        if (typeof require !== 'undefined') {
            try {
                const path = require('path');
                if (!path.isAbsolute(project))
                    return '';
            }
            catch { }
        }
        return project;
    }
    sleep(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }
    async run(runId, options) {
        const speed = options.speed || 200;
        const project = options.project || process.cwd();
        const workspace = this.resolveWorkspaceRoot(project);
        const spinner = createSpinner(`Loading events for run ${runId}...`).start();
        try {
            const baseUrl = this.getBaseUrl();
            const params = new URLSearchParams({ workspace_root: workspace });
            const resp = await fetch(`${baseUrl}/api/runs/${encodeURIComponent(runId)}/events?${params}`, {
                headers: this.getHeaders(),
            });
            if (!resp.ok) {
                spinner.stop();
                if (resp.status === 404) {
                    this.logger.error(`No event log found for run ${runId}. Events are only recorded for runs made after the replay system was deployed.`);
                }
                else if (resp.status === 502 || resp.status === 503) {
                    this.logger.error(`V3 run-history route is not available on ${baseUrl}. Backend may not expose /api/runs.`);
                }
                else {
                    this.logger.error(`Failed to fetch events: ${resp.status} ${resp.statusText}`);
                }
                return;
            }
            const data = (await resp.json());
            spinner.stop();
            if (options.json) {
                console.log(JSON.stringify(data, null, 2));
                return;
            }
            console.log(chalk.bold(`\n${CH.success} Replaying run ${chalk.cyan(runId)} (${data.count} events)\n`));
            let toolCallNum = 0;
            for (let i = 0; i < data.events.length; i++) {
                const evt = data.events[i];
                const type = evt.type || 'unknown';
                const idx = chalk.dim(`[${String(i + 1).padStart(3)}/${data.count}]`);
                switch (type) {
                    case 'context':
                        console.log(`${idx} ${chalk.blue('context')} workspace=${evt.workspace_root || '?'}`);
                        break;
                    case 'start':
                        console.log(`${idx} ${chalk.green('▶ START')} task=${evt.task_id || '?'} ${evt.continuation ? chalk.dim(`(continuation #${evt.continuation})`) : ''}`);
                        break;
                    case 'thinking':
                        console.log(`${idx} ${chalk.dim('💭 thinking')} ${(evt.content || '').substring(0, 100)}`);
                        break;
                    case 'plan':
                        const taskCount = evt.tasks?.length || 0;
                        console.log(`${idx} ${chalk.magenta('📋 PLAN')} ${taskCount} tasks`);
                        if (evt.tasks) {
                            for (const t of evt.tasks.slice(0, 5)) {
                                console.log(`       ${chalk.dim('├')} ${t.id || '?'}: ${(t.title || '').substring(0, 60)}`);
                            }
                            if (taskCount > 5)
                                console.log(`       ${chalk.dim('└')} ...and ${taskCount - 5} more`);
                        }
                        break;
                    case 'tool_call':
                        toolCallNum++;
                        console.log(`${idx} ${chalk.yellow(`🔧 tool_call #${toolCallNum}`)} ${chalk.bold(evt.name || '?')}(${JSON.stringify(evt.arguments || {}).substring(0, 80)})`);
                        break;
                    case 'tool_result': {
                        const success = evt.success !== false;
                        const icon = success ? chalk.green('✓') : chalk.red('✗');
                        const output = (evt.output || '').substring(0, 120);
                        console.log(`${idx}   ${icon} ${evt.name || '?'}: ${chalk.dim(output)}`);
                        break;
                    }
                    case 'message':
                        console.log(`${idx} ${chalk.cyan('💬 message')} ${(evt.content || '').substring(0, 120)}`);
                        break;
                    case 'complete': {
                        const summary = (evt.summary || '').substring(0, 200);
                        const seal = evt.seal_score ? ` [${evt.seal_score.tier} ${evt.seal_score.overall}]` : '';
                        console.log(`${idx} ${chalk.green(`✅ COMPLETE`)}${chalk.yellow(seal)} ${evt.iterations || '?'} iterations, ${evt.tool_calls || '?'} tool calls`);
                        if (summary)
                            console.log(`       ${chalk.dim(summary)}`);
                        break;
                    }
                    case 'error':
                        console.log(`${idx} ${chalk.red('❌ ERROR')} ${(evt.message || '').substring(0, 200)}`);
                        if (evt.checkpointed)
                            console.log(`       ${chalk.yellow('Checkpointed — can be continued or forked')}`);
                        break;
                    case 'file_mutation':
                        console.log(`${idx} ${chalk.blue('📁 file_mutation')} ${evt.kind || '?'} ${evt.path || '?'}`);
                        break;
                    default:
                        console.log(`${idx} ${chalk.dim(type)} ${JSON.stringify(evt).substring(0, 100)}`);
                }
                // Delay between events for replay effect
                if (i < data.events.length - 1) {
                    await this.sleep(speed);
                }
            }
            console.log(chalk.bold(`\n${CH.success} Replay complete (${data.count} events)\n`));
        }
        catch (err) {
            spinner.stop();
            this.logger.error(`Replay error: ${err.message}`);
        }
    }
}
