// engine/spec-effectiveness/project-report.ts — Aggregate project report (SPEC-611)
import { calculateSpecEffectivenessScore } from './calculator.js';
// ── Helpers ──────────────────────────────────────────────────────────────────
function detectTrend(scores) {
    if (scores.length < 3) {
        return 'stable';
    }
    const halfLen = Math.floor(scores.length / 2);
    const firstHalf = scores.slice(0, halfLen);
    const secondHalf = scores.slice(scores.length - halfLen);
    const avg = (arr) => arr.reduce((a, b) => a + b, 0) / arr.length;
    const diff = avg(secondHalf) - avg(firstHalf);
    if (diff > 5) {
        return 'improving';
    }
    if (diff < -5) {
        return 'declining';
    }
    return 'stable';
}
function buildPatterns(scoredSpecs) {
    const patterns = [];
    const highRework = scoredSpecs.filter((s) => s.score.components.reworkRatio > 40).length;
    if (highRework > 0) {
        patterns.push({
            type: 'high-rework',
            count: highRework,
            recommendation: 'Add more specific GIVEN/WHEN/THEN criteria before implementation to reduce post-validate rework.',
        });
    }
    const lowAdherence = scoredSpecs.filter((s) => s.score.components.adherenceRate < 60).length;
    if (lowAdherence > 0) {
        patterns.push({
            type: 'low-adherence',
            count: lowAdherence,
            recommendation: 'Run `validate` during implementation (not only at the end) to catch criterion mismatches early.',
        });
    }
    const noValidate = scoredSpecs.filter((s) => s.score.warnings.some((w) => w.includes('No validate runs'))).length;
    if (noValidate > 0) {
        patterns.push({
            type: 'no-validate',
            count: noValidate,
            recommendation: 'Always run `validate` before marking a spec as done to capture adherence metrics.',
        });
    }
    const estimationDrift = scoredSpecs.filter((s) => s.score.components.estimationAccuracy < 50).length;
    if (estimationDrift > 0) {
        patterns.push({
            type: 'estimation-drift',
            count: estimationDrift,
            recommendation: 'Use `calibrate_estimates` after each spec to improve future estimation accuracy.',
        });
    }
    return patterns;
}
// ── Main export ──────────────────────────────────────────────────────────────
/**
 * Generate a project-level effectiveness report from a list of specs.
 * Does NOT perform any I/O — all data comes from the spec objects.
 */
export function buildProjectEffectivenessReport(projectId, specs) {
    if (specs.length === 0) {
        return {
            projectId,
            specCount: 0,
            averageScore: 0,
            trend: 'stable',
            topSpecs: [],
            bottomSpecs: [],
            patterns: [],
            generatedAt: new Date().toISOString(),
        };
    }
    const scoredSpecs = specs.map((spec) => ({
        spec,
        score: calculateSpecEffectivenessScore(spec),
    }));
    const scores = scoredSpecs.map((s) => s.score.score);
    const averageScore = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
    const trend = detectTrend(scores);
    const summaries = scoredSpecs.map((s) => ({
        specId: s.spec.id,
        title: s.spec.title,
        score: s.score.score,
    }));
    const sorted = [...summaries].sort((a, b) => b.score - a.score);
    const topSpecs = sorted.slice(0, 5);
    const bottomSpecs = [...sorted].reverse().slice(0, 5);
    const patterns = buildPatterns(scoredSpecs);
    return {
        projectId,
        specCount: specs.length,
        averageScore,
        trend,
        topSpecs,
        bottomSpecs,
        patterns,
        generatedAt: new Date().toISOString(),
    };
}
//# sourceMappingURL=project-report.js.map