import chalk from 'chalk';
import { createSpinner, CH } from '../utils/logger.js';
import { APIClient } from '../utils/api.js';
export class BackgroundCommand {
    config;
    logger;
    api;
    constructor(config, logger) {
        this.config = config;
        this.logger = logger;
        this.api = new APIClient(config, logger);
    }
    async start(promptParts, options = {}) {
        const prompt = promptParts.join(' ').trim();
        if (!prompt) {
            this.logger.error('Usage: vigthoria background start "<task>"');
            return;
        }
        const workspacePath = options.workspace || process.cwd();
        const spinner = createSpinner('Starting background agent job...').start();
        try {
            const job = await this.api.startV3BackgroundJob(prompt, {
                workspacePath,
                projectPath: workspacePath,
                targetPath: workspacePath,
                localMachineCapable: true,
                executionSurface: 'cli',
                clientSurface: 'cli',
                clientToolExecution: false,
            });
            spinner.stop();
            if (options.json) {
                console.log(JSON.stringify(job, null, 2));
                return;
            }
            console.log(chalk.green(`${CH.success} Background job started`));
            console.log(chalk.gray(`  Job:       ${job.job_id}`));
            console.log(chalk.gray(`  Status:    ${job.status}`));
            console.log(chalk.gray(`  Workspace: ${workspacePath}`));
            console.log();
            console.log(chalk.gray(`Use ${chalk.cyan(`vigthoria background status ${job.job_id}`)} to check progress.`));
            console.log(chalk.gray(`Use ${chalk.cyan(`vigthoria background apply ${job.job_id}`)} when it is completed.`));
        }
        catch (error) {
            spinner.stop();
            this.logger.error(error?.message || String(error));
        }
    }
    async list(options = {}) {
        const spinner = createSpinner('Loading background jobs...').start();
        try {
            const jobs = await this.api.listV3BackgroundJobs(options.limit || 20);
            spinner.stop();
            if (options.json) {
                console.log(JSON.stringify({ jobs }, null, 2));
                return;
            }
            if (jobs.length === 0) {
                console.log(chalk.gray('No background jobs found.'));
                return;
            }
            console.log(chalk.bold(`\n${CH.success} Background Jobs\n`));
            for (const job of jobs) {
                const color = job.status === 'completed' ? chalk.green : job.status === 'failed' ? chalk.red : job.status === 'cancelled' ? chalk.yellow : chalk.cyan;
                console.log(`${color(String(job.status || 'unknown').padEnd(10))} ${chalk.cyan(job.job_id)} ${chalk.gray(job.updated_at || '')}`);
                console.log(chalk.gray(`  ${String(job.request || '').slice(0, 100)}`));
                console.log(chalk.gray(`  files: ${job.file_count || 0} workspace: ${job.local_workspace_path || job.workspace_name || '-'}`));
            }
            console.log();
        }
        catch (error) {
            spinner.stop();
            this.logger.error(error?.message || String(error));
        }
    }
    async status(jobId, options = {}) {
        if (!jobId) {
            this.logger.error('Usage: vigthoria background status <job-id>');
            return;
        }
        const spinner = createSpinner('Loading background job...').start();
        try {
            const job = await this.api.getV3BackgroundJob(jobId);
            spinner.stop();
            const outcome = this.extractBackgroundOutcome(job);
            if (options.json) {
                console.log(JSON.stringify({ ...job, outcomeTruth: outcome }, null, 2));
                return;
            }
            console.log(chalk.bold(`\nBackground Job ${chalk.cyan(job.job_id)}\n`));
            console.log(`Status:    ${job.status}`);
            console.log(`Files:     ${job.file_count || 0}`);
            console.log(`Updated:   ${job.updated_at || '-'}`);
            console.log(`Workspace: ${job.local_workspace_path || job.workspace_name || '-'}`);
            if (outcome.tasksTotal > 0 || outcome.tasksCompleted > 0) {
                console.log(`Tasks:     ${outcome.tasksCompleted}/${outcome.tasksTotal}${outcome.success === true ? chalk.green(' (complete)') : outcome.success === false ? chalk.red(' (incomplete)') : ''}`);
            }
            if (outcome.headline) {
                console.log(chalk.gray(`Outcome:   ${outcome.headline}`));
            }
            if (job.error)
                console.log(chalk.red(`Error:     ${job.error}`));
            console.log(chalk.gray(`\n${String(job.request || '').slice(0, 500)}`));
            if (job.status === 'completed' && (job.file_count || 0) > 0) {
                console.log(chalk.gray(`\nUse ${chalk.cyan(`vigthoria background apply ${job.job_id}`)} to apply files locally.`));
            }
        }
        catch (error) {
            spinner.stop();
            this.logger.error(error?.message || String(error));
        }
    }
    async apply(jobId, options = {}) {
        if (!jobId) {
            this.logger.error('Usage: vigthoria background apply <job-id>');
            return;
        }
        const workspacePath = options.workspace || process.cwd();
        const spinner = createSpinner('Applying background job files...').start();
        try {
            const result = await this.api.applyV3BackgroundJobFiles(jobId, {
                workspacePath,
                projectPath: workspacePath,
                targetPath: workspacePath,
            });
            spinner.stop();
            if (options.json) {
                console.log(JSON.stringify(result, null, 2));
                return;
            }
            console.log(chalk.green(`${CH.success} Applied ${result.applied.length} file(s) from ${jobId}`));
            for (const file of result.applied.slice(0, 20)) {
                console.log(chalk.gray(`  + ${file}`));
            }
            if (result.applied.length > 20) {
                console.log(chalk.gray(`  ... and ${result.applied.length - 20} more`));
            }
            if (result.skipped.length > 0) {
                console.log(chalk.yellow(`Skipped ${result.skipped.length} unchanged or unsafe file(s).`));
            }
        }
        catch (error) {
            spinner.stop();
            this.logger.error(error?.message || String(error));
        }
    }
    async cancel(jobId, options = {}) {
        if (!jobId) {
            this.logger.error('Usage: vigthoria background cancel <job-id>');
            return;
        }
        const spinner = createSpinner('Cancelling background job...').start();
        try {
            const result = await this.api.cancelV3BackgroundJob(jobId);
            spinner.stop();
            if (options.json) {
                console.log(JSON.stringify(result, null, 2));
                return;
            }
            console.log(chalk.yellow(`${CH.warn} Background job cancelled: ${jobId}`));
        }
        catch (error) {
            spinner.stop();
            this.logger.error(error?.message || String(error));
        }
    }
    extractBackgroundOutcome(job) {
        const result = (job?.result && typeof job.result === 'object') ? job.result : {};
        const events = Array.isArray(job?.events) ? job.events : [];
        let tasksCompleted = Number(result.tasks_completed ?? result.tasksCompleted ?? 0);
        let tasksTotal = Number(result.tasks_total ?? result.tasksTotal ?? 0);
        let success = typeof result.success === 'boolean' ? result.success : null;
        for (const event of events) {
            if (!event || typeof event !== 'object')
                continue;
            if (event.type === 'result' || event.event === 'result') {
                const payload = event.data || event.payload || event;
                if (payload && typeof payload === 'object') {
                    if (payload.tasks_completed != null)
                        tasksCompleted = Number(payload.tasks_completed);
                    if (payload.tasksCompleted != null)
                        tasksCompleted = Number(payload.tasksCompleted);
                    if (payload.tasks_total != null)
                        tasksTotal = Number(payload.tasks_total);
                    if (payload.tasksTotal != null)
                        tasksTotal = Number(payload.tasksTotal);
                    if (typeof payload.success === 'boolean')
                        success = payload.success;
                }
            }
        }
        if (success == null && tasksTotal > 0) {
            success = tasksCompleted >= tasksTotal;
        }
        if (success == null && job?.status === 'completed') {
            success = true;
        }
        if (success == null && job?.status === 'failed') {
            success = false;
        }
        let headline = '';
        if (tasksTotal > 0) {
            headline = success === true
                ? `All ${tasksTotal} task(s) completed`
                : success === false
                    ? `${tasksCompleted}/${tasksTotal} task(s) completed`
                    : `${tasksCompleted}/${tasksTotal} task(s) reported`;
        }
        else if (typeof result.message === 'string' && result.message.trim()) {
            headline = result.message.trim();
        }
        return { tasksCompleted, tasksTotal, success, headline };
    }
}
