import { ti } from '../i18n/index.js';
import { specStore, metricsStore } from '../storage/index.js';
import { calculateAccuracy } from '../engine/estimator.js';
import { validateDoR, validateDoD } from '../engine/dor-dod.js';
import { cascadeCheck } from '../engine/spec-versioner.js';
import { dispatchFeedbackEvent } from './learn.js';
import { handleCreateBranch } from './git/branch-ops.js';
/**
 * Valid state transitions for spec lifecycle.
 * draft -> review -> approved -> implementing -> done
 * Also allow: review -> draft (send back), approved -> review (reconsider)
 */
const VALID_TRANSITIONS = {
    draft: ['review'],
    review: ['draft', 'approved'],
    approved: ['review', 'implementing'],
    implementing: ['approved', 'done'],
    done: [], // terminal state
};
export async function handleUpdateStatus(params) {
    const { specId, projectId, status: newStatus, actuals, autoCreateBranch } = params;
    try {
        // Get the current spec
        const spec = await specStore.getSpec(projectId, specId);
        if (!spec) {
            return {
                content: [{ type: 'text', text: ti('spec.notFound', { id: specId }) }],
                isError: true,
            };
        }
        const currentStatus = spec.status;
        // Validate state transition
        const validNextStates = VALID_TRANSITIONS[currentStatus];
        if (!validNextStates.includes(newStatus)) {
            return {
                content: [
                    {
                        type: 'text',
                        text: ti('spec.invalidTransition', {
                            from: currentStatus,
                            to: newStatus,
                        }),
                    },
                ],
                isError: true,
            };
        }
        // Gate: DoR must pass before transitioning to 'implementing'
        if (newStatus === 'implementing') {
            const dorResult = validateDoR(spec);
            if (!dorResult.isValid) {
                // SPEC-012: Record failed DoR items for auto-improvement loop
                void dispatchFeedbackEvent(projectId, {
                    type: 'checklist',
                    specId,
                    input: { gate: 'dor', specType: spec.type },
                    outcome: { passed: false, failedItems: dorResult.blockingItems },
                    delta: { failedCount: dorResult.blockingItems.length },
                    timestamp: new Date().toISOString(),
                });
                return {
                    content: [
                        {
                            type: 'text',
                            text: JSON.stringify({
                                error: 'DoR gate failed',
                                message: dorResult.humanMessage,
                                expertSummary: dorResult.expertSummary,
                                blockingItems: dorResult.blockingItems,
                                warningItems: dorResult.warningItems,
                            }, null, 2),
                        },
                    ],
                    isError: true,
                };
            }
        }
        // Gate: DoD must pass before transitioning to 'done'
        if (newStatus === 'done') {
            const dodResult = validateDoD(spec);
            if (!dodResult.isValid) {
                // SPEC-012: Record failed DoD items for auto-improvement loop
                void dispatchFeedbackEvent(projectId, {
                    type: 'checklist',
                    specId,
                    input: { gate: 'dod', specType: spec.type },
                    outcome: { passed: false, failedItems: dodResult.blockingItems },
                    delta: { failedCount: dodResult.blockingItems.length },
                    timestamp: new Date().toISOString(),
                });
                return {
                    content: [
                        {
                            type: 'text',
                            text: JSON.stringify({
                                error: 'DoD gate failed',
                                message: dodResult.humanMessage,
                                expertSummary: dodResult.expertSummary,
                                blockingItems: dodResult.blockingItems,
                                warningItems: dodResult.warningItems,
                            }, null, 2),
                        },
                    ],
                    isError: true,
                };
            }
        }
        // Auto-create branch when transitioning to 'implementing' if requested
        let autoBranchResult;
        if (newStatus === 'implementing' && autoCreateBranch) {
            const foundSpec = await specStore.getSpec(projectId, specId);
            if (foundSpec && !foundSpec.gitBranch) {
                const branchResult = await handleCreateBranch(projectId, specId);
                if (!branchResult.isError) {
                    try {
                        const branchData = JSON.parse(branchResult.content[0]?.text ?? '{}');
                        autoBranchResult = branchData.branchName;
                    }
                    catch {
                        // ignore parse error
                    }
                }
            }
        }
        // If transitioning to 'done', actuals are required
        if (newStatus === 'done' && !actuals) {
            return {
                content: [{ type: 'text', text: ti('spec.actualsRequired', {}) }],
                isError: true,
            };
        }
        // Build the update
        const updates = {
            status: newStatus,
        };
        // If actuals are provided, save them
        if (actuals) {
            updates.actuals = actuals;
        }
        // Update the spec
        const updatedSpec = await specStore.updateSpec(projectId, specId, updates);
        // If spec is done and has actuals, record metrics
        if (newStatus === 'done' && actuals) {
            const accuracyScore = calculateAccuracy(spec.estimation, actuals.devHours + actuals.reviewHours);
            const metricEntry = {
                specId,
                difficulty: spec.difficulty,
                estimated: spec.estimation,
                actual: actuals,
                accuracyScore,
            };
            await metricsStore.addMetricEntry(projectId, metricEntry);
        }
        // Cascade check: notify downstream specs of the status change
        const allSpecs = await specStore.listSpecs(projectId);
        const cascadeResult = cascadeCheck(specId, allSpecs, newStatus);
        const result = {
            specId,
            projectId,
            previousStatus: currentStatus,
            newStatus,
            actuals: actuals ?? null,
            autoBranch: autoBranchResult ?? null,
            cascade: cascadeResult,
            metrics: newStatus === 'done' && actuals
                ? {
                    accuracyScore: calculateAccuracy(spec.estimation, actuals.devHours + actuals.reviewHours),
                    estimatedHours: spec.estimation.devHours + spec.estimation.reviewHours,
                    actualHours: actuals.devHours + actuals.reviewHours,
                    estimatedCost: spec.estimation.totalCostUsd,
                    actualCost: actuals.totalCostUsd,
                }
                : null,
            updatedAt: updatedSpec.updatedAt,
            message: ti('tools.update_status.success', { specId, status: newStatus }),
        };
        return {
            content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
        };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: 'text', text: ti('errors.internalError', { message }) }],
            isError: true,
        };
    }
}
//# sourceMappingURL=update-status.js.map