import { Args, Flags } from '@oclif/core';
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
import { styles } from '../../lib/styles.js';
import { getRelativeEpicPath } from '../../lib/pmo/epic-files.js';
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
// Progress bar helper
function progressBar(percent, width = 20) {
    const filled = Math.round((percent / 100) * width);
    const empty = width - filled;
    return '█'.repeat(filled) + '░'.repeat(empty);
}
export default class EpicProgress extends PMOCommand {
    static description = 'Show epic completion progress';
    static examples = [
        '<%= config.bin %> <%= command.id %> EPIC-001',
        '<%= config.bin %> <%= command.id %> --all',
    ];
    static args = {
        id: Args.string({
            description: 'Epic ID',
            required: false,
        }),
    };
    static flags = {
        ...pmoBaseFlags,
        all: Flags.boolean({
            char: 'a',
            description: 'Show progress for all epics',
            default: false,
        }),
    };
    async execute() {
        const { args, flags } = await this.parse(EpicProgress);
        const projectId = await this.requireProject();
        // Check if JSON output mode is active
        const jsonMode = shouldOutputJson(flags);
        if (flags.all) {
            await this.showAllProgress(projectId);
        }
        else {
            let epicId = args.id;
            // If no ID provided, prompt for selection
            if (!epicId) {
                const epics = await this.storage.listEpics(projectId);
                if (epics.length === 0) {
                    if (jsonMode) {
                        outputErrorAsJson('NO_EPICS', 'No epics found.', createMetadata('epic progress', flags));
                        return;
                    }
                    this.log(styles.muted('\nNo epics found.'));
                    return;
                }
                const epicChoices = epics.map(e => ({
                    name: `${e.id} ${e.title} (${e.status})`,
                    value: e.id,
                    command: `prlt epic progress ${e.id} --json`,
                }));
                const jsonModeConfig = jsonMode ? { flags, commandName: 'epic progress' } : null;
                const { selected } = await this.prompt([{
                        type: 'list',
                        name: 'selected',
                        message: 'Select epic to view progress:',
                        choices: epicChoices,
                    }], jsonModeConfig);
                epicId = selected;
            }
            await this.showSingleProgress(projectId, epicId);
        }
    }
    async showSingleProgress(projectId, epicId) {
        const epic = await this.storage.getEpic(epicId);
        if (!epic) {
            this.error(`Epic not found: ${epicId}`);
        }
        const tickets = await this.storage.getTicketsForEpic(projectId, epicId);
        const doneTickets = tickets.filter((t) => t.status === 'done').length;
        const percent = tickets.length > 0 ? Math.round((doneTickets / tickets.length) * 100) : 0;
        const relativePath = getRelativeEpicPath(this.pmoPath, epic.id, epic.status, projectId);
        this.log(`\n🎯 Epic Progress: ${styles.emphasis(epic.id)} - ${epic.title}`);
        this.log('═'.repeat(55));
        this.log(`\nStatus: ${epic.status}`);
        this.log(`File: ${relativePath}`);
        this.log(`Tickets: ${doneTickets}/${tickets.length} complete (${percent}%)`);
        this.log(`\n${progressBar(percent)} ${percent}%`);
        // Group tickets by status/column
        const byStatus = new Map();
        for (const ticket of tickets) {
            const key = ticket.statusName || 'Unknown';
            const list = byStatus.get(key) || [];
            list.push(ticket);
            byStatus.set(key, list);
        }
        if (byStatus.size > 0) {
            this.log('\nBreakdown by column:');
            const statusEmoji = {
                done: '✅',
                'in_progress': '🚧',
                blocked: '🔴',
                ready: '📋',
                backlog: '📥',
            };
            for (const [status, statusTickets] of byStatus) {
                const emoji = statusEmoji[status.toLowerCase()] || '📋';
                this.log(`  ${emoji} ${status}: ${statusTickets.length} ticket${statusTickets.length === 1 ? '' : 's'}`);
            }
        }
        // Show remaining work
        const remaining = tickets.filter((t) => t.status !== 'done');
        if (remaining.length > 0) {
            this.log('\nRemaining work:');
            for (const ticket of remaining) {
                const statusLabel = ticket.statusName || ticket.status;
                this.log(`  ${ticket.id}: ${ticket.title} [${statusLabel}]`);
            }
        }
    }
    async showAllProgress(projectId) {
        const epics = await this.storage.listEpics(projectId);
        if (epics.length === 0) {
            this.log(styles.muted('\nNo epics found.'));
            return;
        }
        this.log('\n📊 Epic Progress - All Epics');
        this.log('═'.repeat(55));
        // Group by status
        const grouped = new Map();
        for (const epic of epics) {
            const list = grouped.get(epic.status) || [];
            list.push(epic);
            grouped.set(epic.status, list);
        }
        const statusOrder = ['active', 'draft', 'complete', 'dropped', 'future'];
        const statusEmoji = {
            active: '🟢',
            draft: '🟡',
            complete: '✅',
            dropped: '❌',
            future: '🔮',
        };
        // Fetch all epic ticket counts in parallel
        const epicProgress = new Map();
        await Promise.all(epics.map(async (epic) => {
            const tickets = await this.storage.getTicketsForEpic(projectId, epic.id);
            const doneTickets = tickets.filter((t) => t.status === 'done').length;
            epicProgress.set(epic.id, { done: doneTickets, total: tickets.length });
        }));
        for (const status of statusOrder) {
            const statusEpics = grouped.get(status);
            if (!statusEpics || statusEpics.length === 0)
                continue;
            this.log(`\n${statusEmoji[status]} ${status.toUpperCase()} (${statusEpics.length})`);
            for (const epic of statusEpics) {
                const progress = epicProgress.get(epic.id) || { done: 0, total: 0 };
                const percent = progress.total > 0 ? Math.round((progress.done / progress.total) * 100) : 0;
                const bar = progressBar(percent);
                const readyToArchive = percent === 100 && status === 'active' ? ' ← ready to archive' : '';
                this.log(`  ${epic.id.padEnd(10)} ${epic.title.substring(0, 30).padEnd(30)} ${bar} ${String(percent).padStart(3)}% (${progress.done}/${progress.total})${readyToArchive}`);
            }
        }
        this.log(styles.muted('\nCommands:'));
        this.log(styles.muted('  prlt epic progress <id>    View detailed progress'));
        this.log(styles.muted('  prlt epic archive <id>     Archive completed epic'));
    }
}
//# sourceMappingURL=progress.js.map