import { ti } from '../i18n/index.js';
import { knowledgeStore, specStore } from '../storage/index.js';
import { describeFilters, isExtendedChallenge } from '../engine/scope-filter.js';
import { generateHUContent } from './create-spec-hu.js';
import { buildAgentHuSection } from './create-spec/agent-spec-adapter.js';
import { isMcpSpec, buildMcpHuSection } from './create-spec/mcp-spec-adapter.js';
import { generateFichaTecnicaContent } from './create-spec-tech.js';
import { writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import { detectTeamScale } from '../engine/platform-engineering/idp-detector.js';
import { runPreSpecDepCheck } from '../engine/dep-auditor/pre-spec-check.js';
import { estimateSpec } from '../engine/estimator.js';
import { checkSpecReadiness } from '../engine/readiness-checker.js';
import { generateProgressContent } from '../engine/progress-writer.js';
import { generatePerSpecExecutiveReport, generatePerSpecTechnicalReport, } from '../engine/doc-generator/per-spec-report/index.js';
import { buildSpecContext, buildSplitResult } from './create-spec/spec-builder.js';
import { validateConstitution } from './create-spec/constitution-validator.js';
import { setupGitBranch, checkContradictions, fireSpecCreatedHook, generatePostCreationSuggestions, } from './create-spec/post-creation.js';
import { regenerateSpecSummaryHtml } from '../engine/spec-summary-html.js';
export async function handleCreateSpec(params) {
    const { description, clarificationSessionId } = params;
    try {
        // Build spec context (ID, estimation, diagrams, scope filters)
        const buildResult = await buildSpecContext(params);
        if (!buildResult.ok) {
            return { content: [{ type: 'text', text: buildResult.errorMessage }], isError: true };
        }
        const { spec, specDir, specPath, technicalPath, progressPath, diagrams, estimation, splitSuggestion, scopeFilters, duplicate, projectId, } = buildResult.context;
        // Load project knowledge and clarification session
        const knowledge = await knowledgeStore.getKnowledge(projectId);
        const clarificationSession = clarificationSessionId
            ? await knowledgeStore.getClarification(projectId, clarificationSessionId)
            : null;
        // Validate against Constitution
        const constitutionCheck = await validateConstitution(projectId, spec.title, spec.tags);
        if (constitutionCheck.blocked && constitutionCheck.errorResult) {
            return constitutionCheck.errorResult;
        }
        // Create spec directory and write files
        await mkdir(specDir, { recursive: true });
        const agentSection = spec.type === 'agent'
            ? buildAgentHuSection(spec.title, description, knowledge, knowledge?.experienceLevel === 'beginner' ? 'beginner' : 'expert')
            : '';
        const mcpSection = isMcpSpec(knowledge)
            ? buildMcpHuSection(spec.title, description, knowledge)
            : '';
        const teamScale = knowledge?.projectPath
            ? await detectTeamScale(knowledge.projectPath)
            : undefined;
        const depWarnings = knowledge?.projectPath && knowledge.projectPath.length > 0
            ? await runPreSpecDepCheck(knowledge.projectPath, knowledge)
            : undefined;
        const huContent = generateHUContent(spec, description, knowledge, undefined, teamScale, depWarnings) +
            agentSection +
            mcpSection;
        const fichaTecnicaContent = generateFichaTecnicaContent(spec, description, estimation, knowledge, diagrams, teamScale);
        await writeFile(specPath, huContent, 'utf-8');
        await writeFile(technicalPath, fichaTecnicaContent, 'utf-8');
        // Generate and write progress.md
        const progressContent = generateProgressContent(spec);
        await writeFile(progressPath, progressContent, 'utf-8');
        // Set report paths (reports generated after auto-estimation below)
        const execReportPath = join(specDir, 'executive-report.html');
        const techReportPath = join(specDir, 'technical-report.html');
        spec.executiveReportPath = execReportPath;
        spec.technicalReportPath = techReportPath;
        // Persist spec in storage
        await specStore.createSpec(projectId, spec);
        // Auto-setup git branch (non-blocking)
        const gitSetupResult = await setupGitBranch(projectId, spec.id);
        /* v8 ignore start -- requires real git repo */
        if (gitSetupResult) {
            spec.gitBranch = gitSetupResult.branch;
        }
        /* v8 ignore stop */
        // Brief contradiction check (non-blocking)
        const contradictionHint = await checkContradictions(projectId, spec.id, description);
        // Build result
        const result = {
            specId: spec.id,
            title: spec.title,
            slug: spec.slug,
            type: spec.type,
            scope: spec.scope,
            difficulty: spec.difficulty,
            risk: spec.risk,
            tags: spec.tags,
            target: spec.target,
            status: spec.status,
            gitBranch: spec.gitBranch,
            specPath,
            technicalPath,
            progressPath,
            executiveReportPath: execReportPath,
            technicalReportPath: techReportPath,
            estimation: {
                devHours: estimation.devHours,
                reviewHours: estimation.reviewHours,
                totalCostUsd: estimation.totalCostUsd,
                recommendedModel: estimation.recommendedModel,
                executionMode: estimation.tokenOptimization.mode,
            },
            diagrams: diagrams.map((d) => ({ type: d.type, title: d.title })),
            scopeFilters: {
                filters: scopeFilters.filters,
                description: describeFilters(scopeFilters),
                extendedChallenge: isExtendedChallenge(spec.scope),
            },
            duplicateWarning: duplicate
                ? ti('spec.duplicateTitle', { title: spec.title, slug: spec.slug })
                : undefined,
            ...(constitutionCheck.warnings.length > 0
                ? { constitutionWarnings: constitutionCheck.warnings }
                : {}),
            ...(clarificationSession
                ? {
                    linkedClarificationSession: clarificationSession.id,
                    clarificationTopic: clarificationSession.topic,
                    clarificationAnswersUsed: Object.keys(clarificationSession.answers).length,
                }
                : {
                    clarificationNote: 'Spec created directly from description — Planu inferred requirements from project context.',
                }),
            message: ti('tools.create_spec.success', { id: spec.id, title: spec.title }),
            ...(contradictionHint ? { contradictionHint } : {}),
            /* v8 ignore next -- requires real git repo */
            ...(gitSetupResult ? { gitAutoSetup: gitSetupResult.data } : {}),
        };
        const splitResult = buildSplitResult(splitSuggestion, knowledge?.experienceLevel);
        if (splitResult) {
            result.splitSuggestion = splitResult;
        }
        // Dispatch hook event (fire-and-forget)
        fireSpecCreatedHook(projectId, spec);
        // Auto-estimation (best-effort, fire-and-forget)
        try {
            const autoEstimation = estimateSpec(spec);
            await specStore.updateSpec(projectId, spec.id, { estimation: autoEstimation.estimation });
            result.autoEstimation = {
                confidence: autoEstimation.confidence,
                reasoning: autoEstimation.reasoning,
                similarSpecs: autoEstimation.similarSpecs,
            };
        }
        catch {
            /* best-effort — never block spec creation */
        }
        // Generate per-spec HTML reports (AFTER auto-estimation so data is real)
        const execReport = generatePerSpecExecutiveReport(spec, [], []);
        const techReport = generatePerSpecTechnicalReport(spec, diagrams, [], []);
        await writeFile(execReportPath, execReport.content, 'utf-8');
        await writeFile(techReportPath, techReport.content, 'utf-8');
        // Auto-readiness check (best-effort, fire-and-forget)
        try {
            const readiness = await checkSpecReadiness(spec, 'lenient');
            result.autoReadiness = { score: readiness.score, isReady: readiness.ready };
        }
        catch {
            /* best-effort — never block spec creation */
        }
        // Auto-challenge warning for high risk/difficulty specs
        if (spec.risk === 'high' || spec.difficulty >= 4) {
            result.riskWarning =
                'This spec has high risk/difficulty. Consider running challenge_spec before approval.';
        }
        // Post-creation suggestions (best-effort, non-blocking)
        const nextSteps = await generatePostCreationSuggestions(params.projectPath, description);
        if (nextSteps.length > 0) {
            result.nextSteps = nextSteps;
        }
        // Auto-regenerate planu/index.html (fire-and-forget)
        if (params.projectPath) {
            const allSpecs = await specStore.listSpecs(projectId);
            void regenerateSpecSummaryHtml(params.projectPath, allSpecs);
        }
        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=create-spec.js.map