"use strict";
/**
 * v1.12.0 — Story command surface.
 *
 *   openlife story list [--epic <id>] [--status <s>] [--cluster <c>]
 *   openlife story show <id>
 *   openlife story validate <id>
 *   openlife story transition <id> <to-status> [--role <role>] [--author <a>]
 *   openlife story epics
 *
 * All actions are lazy-imported inside the action handlers so
 * `openlife --help` keeps its sub-500ms target.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerStoryCommands = registerStoryCommands;
function emit(value) {
    process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
}
function errMsg(e) {
    return e instanceof Error ? e.message : String(e);
}
async function listAction(opts) {
    const { StoryRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryRegistry')));
    const { isStoryStatus } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StorySchema')));
    const reg = new StoryRegistry();
    await reg.load();
    const filter = {};
    if (opts.epic)
        filter.epicId = opts.epic;
    if (opts.cluster)
        filter.cluster = opts.cluster;
    let status = opts.status;
    if (status) {
        if (!isStoryStatus(status)) {
            console.error(`Unknown status: ${status}. Expected Draft|Ready|InProgress|InReview|Done.`);
            process.exitCode = 1;
            return;
        }
    }
    const stories = reg.list({
        epicId: filter.epicId,
        cluster: filter.cluster,
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        status: status,
    });
    if (opts.json) {
        emit({ ok: true, count: stories.length, stories: stories.map(s => ({ id: s.id, epicId: s.epicId, title: s.title, status: s.status, severity: s.severity, cluster: s.cluster, dependsOn: s.dependsOn })) });
        return;
    }
    if (stories.length === 0) {
        console.log('No stories matched (or no docs/stories/ in cwd).');
        return;
    }
    const sorted = stories.slice().sort((a, b) => a.id.localeCompare(b.id, undefined, { numeric: true }));
    for (const s of sorted) {
        const sev = s.severity ? `[${s.severity}] ` : '';
        const clu = s.cluster ? ` (${s.cluster})` : '';
        console.log(`${s.id}  ${s.status.padEnd(11)}  ${sev}${s.title}${clu}`);
    }
}
async function showAction(id, opts) {
    const { StoryRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryRegistry')));
    const reg = new StoryRegistry();
    await reg.load();
    const story = reg.get(id);
    if (!story) {
        console.error(`Story "${id}" not found.`);
        process.exitCode = 1;
        return;
    }
    if (opts.raw) {
        process.stdout.write(story.raw);
        return;
    }
    if (opts.json) {
        emit({ ok: true, story });
        return;
    }
    console.log(`# Story ${story.id} — ${story.title}`);
    console.log(`  Epic:     ${story.epicId}`);
    console.log(`  Status:   ${story.status}`);
    if (story.severity)
        console.log(`  Severity: ${story.severity}`);
    if (story.cluster)
        console.log(`  Cluster:  ${story.cluster}`);
    if (story.dependsOn.length)
        console.log(`  Depends:  ${story.dependsOn.join(', ')}`);
    console.log(`  Path:     ${story.sourcePath}`);
    console.log('');
    if (story.description) {
        console.log('## Description');
        console.log(story.description);
        console.log('');
    }
    if (story.acceptanceCriteria.length > 0) {
        console.log('## Acceptance Criteria');
        for (const ac of story.acceptanceCriteria) {
            console.log(`- [${ac.checked ? 'x' : ' '}] ${ac.text}`);
        }
    }
}
async function validateAction(id, opts) {
    const { StoryRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryRegistry')));
    const reg = new StoryRegistry();
    await reg.load();
    const story = reg.get(id);
    if (!story) {
        if (opts.json)
            emit({ ok: false, error: 'not_found', id });
        else
            console.error(`Story "${id}" not found.`);
        process.exitCode = 1;
        return;
    }
    const issues = [];
    if (!story.severity)
        issues.push('missing Severity');
    if (!story.cluster)
        issues.push('missing Cluster');
    if (story.acceptanceCriteria.length === 0)
        issues.push('no acceptance criteria');
    const openACs = story.acceptanceCriteria.filter(a => !a.checked).length;
    if (opts.json) {
        emit({ ok: issues.length === 0, id, issues, openAcceptanceCriteria: openACs, status: story.status });
        return;
    }
    console.log(`Story ${story.id} — validation`);
    console.log(`  Status: ${story.status}`);
    console.log(`  Open ACs: ${openACs}/${story.acceptanceCriteria.length}`);
    if (issues.length === 0)
        console.log('  ✓ no structural issues found');
    else {
        for (const i of issues)
            console.log(`  ✗ ${i}`);
        process.exitCode = 1;
    }
}
async function transitionAction(id, toStatus, opts) {
    const { StoryRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryRegistry')));
    const { canTransition, currentRole } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryLifecycle')));
    const { updateStoryStatus } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryWriter')));
    const reg = new StoryRegistry();
    await reg.load();
    const story = reg.get(id);
    if (!story) {
        if (opts.json)
            emit({ ok: false, error: 'not_found', id });
        else
            console.error(`Story "${id}" not found.`);
        process.exitCode = 1;
        return;
    }
    const role = currentRole(opts.role);
    const decision = canTransition(story.status, toStatus, role);
    if (!decision.allowed) {
        if (opts.json)
            emit({ ok: false, error: 'transition_denied', reason: decision.reason });
        else
            console.error(`Transition denied: ${decision.reason}`);
        process.exitCode = 1;
        return;
    }
    try {
        updateStoryStatus(story.sourcePath, story.status, toStatus, {
            author: opts.author,
            note: opts.note,
        });
    }
    catch (err) {
        if (opts.json)
            emit({ ok: false, error: 'write_failed', detail: errMsg(err) });
        else
            console.error(`Write failed: ${errMsg(err)}`);
        process.exitCode = 1;
        return;
    }
    if (opts.json)
        emit({ ok: true, id: story.id, from: story.status, to: toStatus, path: story.sourcePath });
    else
        console.log(`Story ${story.id}: ${story.status} → ${toStatus} (${story.sourcePath})`);
}
async function epicsAction(opts) {
    const { StoryRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/story/StoryRegistry')));
    const reg = new StoryRegistry();
    await reg.load();
    const epics = reg.listEpics();
    if (opts.json) {
        emit({ ok: true, count: epics.length, epics: epics.map(e => ({ id: e.id, title: e.title, status: e.status, storyIds: e.storyIds })) });
        return;
    }
    if (epics.length === 0) {
        console.log('No epics found.');
        return;
    }
    for (const e of epics) {
        console.log(`${e.id}  ${e.status || '-'.padEnd(11)}  ${e.title} (${e.storyIds.length} stories)`);
    }
}
function registerStoryCommands(program) {
    const story = program
        .command('story')
        .description('v1.12.0 — read, validate and transition stories under docs/stories/');
    story
        .command('list')
        .description('List stories with optional filters')
        .option('--epic <id>', 'Filter by epic id')
        .option('--status <s>', 'Filter by status (Draft|Ready|InProgress|InReview|Done)')
        .option('--cluster <c>', 'Filter by cluster tag')
        .option('--json', 'Emit JSON')
        .action((opts) => { void listAction(opts); });
    story
        .command('show <id>')
        .description('Print parsed story by id')
        .option('--json', 'Emit JSON')
        .option('--raw', 'Emit raw markdown')
        .action((id, opts) => { void showAction(id, opts); });
    story
        .command('validate <id>')
        .description('Structural validation of a story file')
        .option('--json', 'Emit JSON')
        .action((id, opts) => { void validateAction(id, opts); });
    story
        .command('transition <id> <to>')
        .description('Apply a lifecycle transition with role + writer')
        .option('--role <role>', 'Override OPENLIFE_USER_ROLE (po|dev|qa|admin)')
        .option('--author <a>', 'Change log author marker, e.g. "@dev (Charlie)"')
        .option('--note <n>', 'Change log note (defaults to "Status: X → Y")')
        .option('--json', 'Emit JSON')
        .action((id, to, opts) => { void transitionAction(id, to, opts); });
    story
        .command('epics')
        .description('List epics discovered under docs/stories/<epic-id>/epic.md')
        .option('--json', 'Emit JSON')
        .action((opts) => { void epicsAction(opts); });
    // v1.17.0 — Autonomous Story Loop. Registered as a child of `story`.
    try {
        // eslint-disable-next-line @typescript-eslint/no-var-requires
        const { registerStoryExecuteCommand } = require('./StoryExecuteCommand');
        registerStoryExecuteCommand(story);
    }
    catch (err) {
        if ((process.env.OPENLIFE_DEBUG || '').toLowerCase() === 'true') {
            console.error('[story execute] failed to register:', err);
        }
    }
}
