import { Flags, Args } from '@oclif/core';
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
import { styles } from '../../lib/styles.js';
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
import { FlagResolver } from '../../lib/flags/index.js';
export default class SpecView extends PMOCommand {
    static description = 'View a spec and its linked tickets';
    static examples = [
        '<%= config.bin %> <%= command.id %> user-authentication',
        '<%= config.bin %> <%= command.id %> --spec api-design',
    ];
    static args = {
        spec: Args.string({
            description: 'Spec ID',
            required: false,
        }),
    };
    static flags = {
        ...pmoBaseFlags,
        spec: Flags.string({
            char: 's',
            description: 'Spec ID',
        }),
        full: Flags.boolean({
            char: 'f',
            description: 'Show all spec sections',
            default: false,
        }),
    };
    async execute() {
        const { args, flags } = await this.parse(SpecView);
        // Check if JSON output mode is active
        const jsonMode = shouldOutputJson(flags);
        // This command requires project context for listing linked tickets (with JSON mode support)
        const projectId = await this.requireProject({
            jsonMode: jsonMode ? {
                flags,
                commandName: 'spec view',
                baseCommand: 'prlt spec view',
            } : undefined,
        });
        // Helper to handle errors in JSON mode
        const handleError = (code, message) => {
            if (jsonMode) {
                outputErrorAsJson(code, message, createMetadata('spec view', flags));
                this.exit(1);
            }
            this.error(message);
        };
        // Get spec ID
        let specId = args.spec || flags.spec;
        if (!specId) {
            const specs = await this.storage.listSpecs();
            if (specs.length === 0) {
                return handleError('NO_SPECS', 'No specs found. Create one first with: prlt spec create');
            }
            // Use FlagResolver for spec selection
            const resolver = new FlagResolver({
                commandName: 'spec view',
                baseCommand: 'prlt spec view',
                jsonMode,
                flags: { spec: flags.spec },
            });
            resolver.addPrompt({
                flagName: 'spec',
                type: 'list',
                message: 'Select spec to view:',
                choices: () => specs.map(s => ({
                    name: `${s.title} [${s.status}]${s.type ? ` (${s.type})` : ''}`,
                    value: s.id,
                })),
            });
            const resolved = await resolver.resolve();
            specId = resolved.spec;
        }
        // Get the spec
        const spec = await this.storage.getSpec(specId);
        if (!spec) {
            this.error(`Spec not found: ${specId}`);
        }
        // Get linked tickets
        const tickets = await this.storage.getTicketsForSpec(projectId, spec.id);
        // Get dependencies
        const dependencies = await this.storage.getSpecDependencies(spec.id);
        const dependents = await this.storage.getSpecDependents(spec.id);
        // JSON output mode
        if (jsonMode) {
            this.log(JSON.stringify({
                success: true,
                spec: {
                    id: spec.id,
                    title: spec.title,
                    status: spec.status,
                    type: spec.type,
                    problem: spec.problem,
                    solution: spec.solution,
                    decisions: spec.decisions,
                    notNow: spec.notNow,
                    uiUx: spec.uiUx,
                    acceptanceCriteria: spec.acceptanceCriteria,
                    openQuestions: spec.openQuestions,
                    requirementsFunctional: spec.requirementsFunctional,
                    requirementsTechnical: spec.requirementsTechnical,
                    context: spec.context,
                    tags: spec.tags,
                    createdAt: spec.createdAt.toISOString(),
                    updatedAt: spec.updatedAt.toISOString(),
                    dependencies: dependencies.map(d => ({ id: d.id, title: d.title, status: d.status })),
                    dependents: dependents.map(d => ({ id: d.id, title: d.title, status: d.status })),
                    tickets: tickets.map(t => ({ id: t.id, title: t.title, status: t.status })),
                },
            }, null, 2));
            return;
        }
        // Display spec info
        this.log(styles.title(`\n📄 ${spec.title}`));
        this.log(styles.muted('═'.repeat(60)));
        this.log(styles.muted(`ID: ${spec.id}`));
        this.log(styles.muted(`Status: ${spec.status}`));
        if (spec.type)
            this.log(styles.muted(`Type: ${spec.type}`));
        if (spec.tags && spec.tags.length > 0) {
            this.log(styles.muted(`Tags: ${spec.tags.join(', ')}`));
        }
        this.log(styles.muted(`Created: ${spec.createdAt.toLocaleDateString()}`));
        this.log(styles.muted(`Updated: ${spec.updatedAt.toLocaleDateString()}`));
        // Problem
        if (spec.problem) {
            this.log(styles.emphasis('\n## Problem'));
            this.log(spec.problem);
        }
        // Solution
        if (spec.solution) {
            this.log(styles.emphasis('\n## Solution'));
            this.log(spec.solution);
        }
        // Decisions (always show)
        if (spec.decisions) {
            this.log(styles.emphasis('\n## Decisions'));
            this.log(spec.decisions);
        }
        // Show more sections if --full
        if (flags.full) {
            if (spec.notNow) {
                this.log(styles.emphasis('\n## Not Now'));
                this.log(spec.notNow);
            }
            if (spec.uiUx) {
                this.log(styles.emphasis('\n## UI/UX'));
                this.log(spec.uiUx);
            }
            if (spec.acceptanceCriteria) {
                this.log(styles.emphasis('\n## Acceptance Criteria'));
                this.log(spec.acceptanceCriteria);
            }
            if (spec.openQuestions) {
                this.log(styles.emphasis('\n## Open Questions'));
                this.log(spec.openQuestions);
            }
            if (spec.requirementsFunctional) {
                this.log(styles.emphasis('\n## Functional Requirements'));
                this.log(spec.requirementsFunctional);
            }
            if (spec.requirementsTechnical) {
                this.log(styles.emphasis('\n## Technical Requirements'));
                this.log(spec.requirementsTechnical);
            }
            if (spec.context) {
                this.log(styles.emphasis('\n## Context'));
                this.log(spec.context);
            }
        }
        // Dependencies
        if (dependencies.length > 0) {
            this.log(styles.emphasis(`\n📦 Depends On (${dependencies.length}):`));
            for (const dep of dependencies) {
                this.log(`  ${styles.code(dep.id)}: ${dep.title} [${dep.status}]`);
            }
        }
        if (dependents.length > 0) {
            this.log(styles.emphasis(`\n📦 Depended On By (${dependents.length}):`));
            for (const dep of dependents) {
                this.log(`  ${styles.code(dep.id)}: ${dep.title} [${dep.status}]`);
            }
        }
        // Linked tickets
        if (tickets.length > 0) {
            this.log(styles.emphasis(`\n🎫 Linked Tickets (${tickets.length}):`));
            for (const ticket of tickets) {
                this.log(`  ${styles.code(ticket.id)}: ${ticket.title} [${ticket.status}]`);
            }
        }
        else {
            this.log(styles.muted('\n🎫 No linked tickets'));
        }
        this.log(styles.muted('\n' + '═'.repeat(60)));
        if (!flags.full) {
            this.log(styles.muted('Use --full to see all sections'));
        }
    }
}
//# sourceMappingURL=view.js.map