import { ti } from '../../i18n/index.js';
import { hashProjectPath, knowledgeStore, globalStore, licenseStore, specStore, } from '../../storage/index.js';
import { getCurrentTier } from '../license-gate.js';
import { checkLimits } from '../../engine/license-validator.js';
import { analyzeProject, checkProjectCompleteness } from '../../engine/analyzer.js';
import { parseProjectQualityRules } from '../../engine/auditor-claude-md.js';
import { detectModernPatterns, detectDdd } from '../../engine/architecture-pattern-detector.js';
import { detectAgileProcess } from '../../engine/agile-config-builder.js';
import { detectMissingAreas, buildRequestPrompt } from '../../engine/context-merger.js';
import { detectProjectPrivacyConfig, maybeGenerateEnvExample, buildBeginnerEnvGuide, detectOrchestratorInfo, detectComposeMultiplatform, } from './helpers.js';
import { buildInitProjectResult } from './result-builder.js';
import { fetchRecommendedSkills } from '../suggest-tooling/skills-fetcher.js';
import { generateRules, detectAgentPlatformFromFiles } from '../../engine/skill-generator.js';
import { createPlanuConfig, serializePlanuConfig } from '../../engine/planu-config-writer.js';
import { filterLegacySpecs, migrateSpecs, filterUnprefixedSpecs, migrateSpecFolderNames, discoverAndFlattenSpecs, reconcileSpecPaths, } from '../../engine/spec-migrator.js';
import { readFile, writeFile, access, mkdir } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { handleSetupHooks } from '../git/hook-ops.js';
import { detectGitFlowType } from '../git/git-helpers.js';
import { handleInitConstitution } from '../init-constitution/handler.js';
export async function handleInitProject(params) {
    const { projectPath, locale, hourlyRate, experienceLevel, userProfile } = params;
    try {
        const projectId = hashProjectPath(projectPath);
        // Check if project is already initialized
        const existing = await knowledgeStore.getKnowledge(projectId);
        const isUpdate = existing !== null;
        // License: check project limit only for new projects
        if (!isUpdate) {
            const tier = await getCurrentTier();
            const projectCount = await licenseStore.countActiveProjects();
            const limitCheck = checkLimits(tier, projectCount, 'maxProjects');
            if (!limitCheck.allowed) {
                return { content: [{ type: 'text', text: limitCheck.message }], isError: true };
            }
        }
        // Get global config for defaults
        const globalConfig = await globalStore.getGlobalConfig();
        const effectiveLocale = locale ?? existing?.locale ?? globalConfig.defaultLocale;
        const effectiveExperience = experienceLevel ?? existing?.experienceLevel ?? globalConfig.defaultExperienceLevel;
        // Run full project analysis
        const knowledge = await analyzeProject(projectPath, projectId, effectiveLocale, effectiveExperience);
        // Apply overrides
        if (userProfile) {
            knowledge.userProfile = userProfile;
        }
        // SPEC-026a: Compute project completeness score
        const completeness = await checkProjectCompleteness(projectPath);
        // Auto-configure qualityProfile from CLAUDE.md / .cursorrules (SPEC-010)
        const claudeMdRules = await parseProjectQualityRules(projectPath);
        if (claudeMdRules.length > 0) {
            knowledge.qualityProfile.customRules = [
                ...knowledge.qualityProfile.customRules,
                ...claudeMdRules,
            ];
        }
        // If hourly rate provided, update global config too
        if (hourlyRate !== undefined) {
            await globalStore.updateGlobalConfig({ hourlyRate });
        }
        // SPEC-033: Detect modern architecture patterns and agile process
        // SPEC-033 TD-P14-01+02: K3s/Nomad orchestrator + SPEC-013 TD-P14-01: Compose Multiplatform
        const [modernPatterns, dddConfig, agileDetection, orchestratorInfo, composeMultiplatform] = await Promise.all([
            detectModernPatterns(projectPath),
            detectDdd(projectPath),
            detectAgileProcess(projectPath),
            detectOrchestratorInfo(projectPath),
            detectComposeMultiplatform(projectPath),
        ]);
        // Save project knowledge
        await knowledgeStore.saveKnowledge(projectId, knowledge);
        // Generate planu.json if it doesn't exist yet
        const planuConfigPath = join(projectPath, 'planu.json');
        let planuConfigGenerated = false;
        try {
            await access(planuConfigPath);
        }
        catch {
            const planuConfig = createPlanuConfig();
            await writeFile(planuConfigPath, serializePlanuConfig(planuConfig), 'utf-8');
            planuConfigGenerated = true;
        }
        // Auto-discover and flatten specs in subcategory folders (v0.30 → v0.40 migration)
        let discoveryResult = null;
        try {
            discoveryResult = await discoverAndFlattenSpecs(projectPath);
        }
        catch {
            /* best-effort — don't fail init */
        }
        // Auto-migrate legacy specs if detected (docs/sdd/specs/ → planu/specs/)
        const allSpecs = await specStore.listSpecs(projectId);
        const legacySpecs = filterLegacySpecs(allSpecs);
        let migrationResult = null;
        if (legacySpecs.length > 0) {
            migrationResult = await migrateSpecs(projectPath, legacySpecs, {
                listSpecs: specStore.listSpecs,
                updateSpec: specStore.updateSpec,
            });
            // Update knowledge specLocation after migration
            knowledge.specLocation = 'planu/specs';
            await knowledgeStore.saveKnowledge(projectId, knowledge);
        }
        // Reconcile specs.json paths with actual filesystem (fixes stale paths after rename/flatten)
        try {
            await reconcileSpecPaths(projectPath, {
                listSpecs: specStore.listSpecs,
                updateSpec: specStore.updateSpec,
            }, projectId);
        }
        catch {
            /* best-effort */
        }
        // Auto-migrate spec folders without SPEC-XXX- prefix
        const unprefixedSpecs = filterUnprefixedSpecs(await specStore.listSpecs(projectId));
        let folderMigrationResult = null;
        if (unprefixedSpecs.length > 0) {
            folderMigrationResult = await migrateSpecFolderNames(projectPath, unprefixedSpecs, {
                listSpecs: specStore.listSpecs,
                updateSpec: specStore.updateSpec,
            });
        }
        // Auto-fetch recommended skills based on detected stack
        const recommendedSkills = await fetchRecommendedSkills(knowledge);
        // Auto-detect AI platform and generate rules with skills — zero user intervention
        const agentDetection = await detectAgentPlatformFromFiles(projectPath);
        const platform = agentDetection.platform;
        const constitution = await knowledgeStore.getConstitution(projectId);
        const generatedRules = await generateRules(platform, knowledge, constitution ?? undefined, {
            recommendedSkills,
        });
        // Auto-write rules file to disk (only if it doesn't exist — never overwrite user's custom rules)
        const rulesFilePath = join(projectPath, generatedRules.rulesFile.path);
        let rulesWritten = false;
        try {
            await access(rulesFilePath);
        }
        catch {
            await mkdir(dirname(rulesFilePath), { recursive: true });
            await writeFile(rulesFilePath, generatedRules.rulesFile.content, 'utf-8');
            rulesWritten = true;
        }
        // Auto-write additional rules files (e.g., sdd-workflow.md skill)
        const additionalFilesWritten = [];
        for (const file of generatedRules.additionalFiles) {
            const filePath = join(projectPath, file.path);
            try {
                await access(filePath);
            }
            catch {
                await mkdir(dirname(filePath), { recursive: true });
                await writeFile(filePath, file.content, 'utf-8');
                additionalFilesWritten.push(file.path);
            }
        }
        // SPEC-001: Auto-install git hooks (best-effort)
        let hooksInstalled = [];
        try {
            const hookResult = await handleSetupHooks(projectId);
            if (!hookResult.isError) {
                const hookData = JSON.parse(hookResult.content[0]?.text ?? '{}');
                hooksInstalled = hookData.hooksInstalled ?? [];
            }
        }
        catch {
            // Hooks setup is best-effort — don't fail init_project
        }
        // SPEC-001: Auto-detect branching model (best-effort)
        let gitFlowType = 'unknown';
        try {
            gitFlowType = await detectGitFlowType(projectPath);
        }
        catch {
            // Not a git repo — skip
        }
        // SPEC-001: Auto-configure .gitignore (best-effort)
        const gitignorePath = join(projectPath, '.gitignore');
        let gitignoreUpdated = false;
        try {
            let gitignoreContent = '';
            try {
                gitignoreContent = await readFile(gitignorePath, 'utf-8');
            }
            catch {
                /* file doesn't exist */
            }
            const linesToAdd = [];
            if (!gitignoreContent.includes('data/')) {
                linesToAdd.push('data/');
            }
            if (!gitignoreContent.includes('.claude/')) {
                linesToAdd.push('.claude/');
            }
            if (linesToAdd.length > 0) {
                const separator = gitignoreContent.endsWith('\n') || gitignoreContent === '' ? '' : '\n';
                const addition = `${separator}# Planu data (auto-generated)\n${linesToAdd.join('\n')}\n`;
                await writeFile(gitignorePath, gitignoreContent + addition, 'utf-8');
                gitignoreUpdated = true;
            }
        }
        catch {
            /* best-effort */
        }
        // SPEC-001: Auto-initialize constitution (best-effort)
        let constitutionInitialized = false;
        const existingConstitution = await knowledgeStore.getConstitution(projectId);
        if (!existingConstitution) {
            try {
                const constResult = await handleInitConstitution({
                    projectId,
                    autoDetect: true,
                });
                constitutionInitialized = !constResult.isError;
            }
            catch {
                /* best-effort */
            }
        }
        // SPEC-036: Request context when knowledge is incomplete
        const missingAreas = detectMissingAreas(knowledge);
        let contextRequestPrompt = null;
        const needsContext = missingAreas.length > 0 && knowledge.contextRequested !== true;
        if (needsContext) {
            contextRequestPrompt = buildRequestPrompt(missingAreas, knowledge);
            // Persist the contextRequested flag without overwriting anything else
            await knowledgeStore.saveKnowledge(projectId, {
                ...knowledge,
                contextRequested: true,
            });
        }
        // SPEC-025 tech-debt: Auto-generate .env.example from detected env vars
        const envVars = knowledge.envSetup.variables;
        const envExampleGenerated = await maybeGenerateEnvExample(projectPath, envVars);
        // SPEC-025 tech-debt: Beginner env guide
        const beginnerEnvGuide = effectiveExperience === 'beginner' && envVars.length > 0
            ? buildBeginnerEnvGuide(envVars)
            : null;
        // SPEC-030: Detect legal framework and third-party data processors
        const privacyConfig = await detectProjectPrivacyConfig(projectPath);
        return buildInitProjectResult({
            projectId,
            projectPath,
            isUpdate,
            knowledge,
            claudeMdRules,
            completeness,
            modernPatterns,
            dddConfig,
            agileDetection,
            orchestratorInfo,
            composeMultiplatform,
            privacyConfig,
            envExampleGenerated,
            beginnerEnvGuide,
            contextRequestPrompt,
            missingAreas,
            recommendedSkills,
            platform,
            generatedRules,
            rulesWritten,
            additionalFilesWritten,
            planuConfigGenerated,
            planuConfigPath,
            migrationResult,
            discoveryResult,
            folderMigrationResult,
            hooksInstalled,
            gitFlowType,
            gitignoreUpdated,
            constitutionInitialized,
        });
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: 'text', text: ti('errors.internalError', { message }) }],
            isError: true,
        };
    }
}
//# sourceMappingURL=handler.js.map