"use strict";
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;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnifiedDesignContextLoader = void 0;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const contextEnricher_1 = require("./contextEnricher");
const DesignPipelineAgent_1 = require("../agents/implementations/DesignPipelineAgent");
const designPipelineStateManager_1 = require("./designPipelineStateManager");
const ProjectScanner_1 = require("../services/ProjectScanner");
const core_1 = require("@myycontext/core");
const chalk_1 = __importDefault(require("chalk"));
/**
 * Unified Design Context Loader
 *
 * Treats ALL context files (PRD + Types + Brand + Component List + Architecture)
 * as a unified design system foundation for component generation.
 *
 * This is the key insight from V0: context files ARE the design system.
 */
class UnifiedDesignContextLoader {
    constructor(projectPath = process.cwd()) {
        this.projectPath = projectPath;
        this.manifestManager = new core_1.DesignManifestManager(projectPath);
        this.contextEnricher = new contextEnricher_1.ContextEnricher(projectPath);
        this.designPipeline = new DesignPipelineAgent_1.DesignPipelineAgent(projectPath);
        this.stateManager = new designPipelineStateManager_1.DesignPipelineStateManager(projectPath);
    }
    getContextEnricher() {
        return this.contextEnricher;
    }
    /**
     * Load and unify ALL context files as design system foundation
     */
    async loadUnifiedDesignContext(resumeFromState = false) {
        console.log(chalk_1.default.blue("🔄 Loading unified design context..."));
        try {
            // 0. BRAIN-FIRST CHECK: If context.json exists, it's our SSOT.
            // We skip the DesignPipelineAgent because context.json ALREADY contains the FSR.
            const brainPath = path.join(this.projectPath, ".mycontext", "context.json");
            if (await fs.pathExists(brainPath)) {
                const brain = await fs.readJson(brainPath);
                const contextFiles = await this.loadAllContextFiles();
                // Use the brain to enrich context (we still need the Enricher to prepare it for agents)
                const enrichedContext = await this.contextEnricher.enrichWithBrain(contextFiles, brain);
                return {
                    enrichedContext,
                    hasDesignManifest: true,
                    shouldGenerateManifest: false,
                };
            }
            // 1. Load all context files
            const contextFiles = await this.loadAllContextFiles();
            console.log(chalk_1.default.gray(`   Loaded ${Object.keys(contextFiles).length} context files`));
            // New: Run Project Scanner for real-world signal
            console.log(chalk_1.default.gray("   Scanning project for technical context..."));
            const scanner = new ProjectScanner_1.ProjectScanner(this.projectPath);
            const projectSnapshot = await scanner.scan();
            // 2. Check if design manifest exists and is valid
            const hasDesignManifest = await this.manifestManager.hasValidManifest();
            const shouldGenerateManifest = !hasDesignManifest ||
                (await this.manifestManager.shouldRegenerateManifest(24));
            let enrichedContext;
            if (hasDesignManifest && !shouldGenerateManifest) {
                // 3a. Use existing design manifest
                console.log(chalk_1.default.gray("   Using existing design manifest"));
                enrichedContext = await this.contextEnricher.mergeAllContext(contextFiles.prd, contextFiles.types, contextFiles.brand, contextFiles.componentList);
            }
            else {
                // 3b. Generate new design manifest from all context files
                console.log(chalk_1.default.gray("   Generating design manifest from context files"));
                const designInput = {
                    prd: contextFiles.prd,
                    types: contextFiles.types,
                    branding: contextFiles.brand,
                    readme: contextFiles.readme,
                    project_snapshot: projectSnapshot,
                    component_list: contextFiles.componentList,
                    project_path: this.projectPath,
                    force_regenerate: shouldGenerateManifest,
                };
                try {
                    const designOutput = await this.designPipeline.run(designInput, resumeFromState);
                    if (designOutput.success) {
                        await this.manifestManager.saveDesignManifest(designOutput.manifest);
                        console.log(chalk_1.default.green("✅ Design manifest generated and saved"));
                    }
                    else {
                        console.warn(chalk_1.default.yellow("⚠️  Design pipeline failed, using fallback context"));
                    }
                }
                catch (error) {
                    // Pipeline failed at a specific phase - error already logged with recovery guidance
                    // Re-throw to stop component generation
                    throw error;
                }
                // Load enriched context
                enrichedContext = await this.contextEnricher.mergeAllContext(contextFiles.prd, contextFiles.types, contextFiles.brand, contextFiles.componentList);
            }
            console.log(chalk_1.default.green("✅ Unified design context loaded"));
            console.log(chalk_1.default.gray(`   Design system: ${enrichedContext.design_system.colors.primary} primary`));
            console.log(chalk_1.default.gray(`   Components: ${enrichedContext.component_architecture.components.length} defined`));
            console.log(chalk_1.default.gray(`   Design anchors: ${enrichedContext.design_intent.design_anchors.join(", ")}`));
            return {
                enrichedContext,
                hasDesignManifest,
                shouldGenerateManifest,
            };
        }
        catch (error) {
            console.error(chalk_1.default.red("❌ Failed to load unified design context:"), error);
            throw error;
        }
    }
    /**
     * Load all context files as a unified design foundation
     */
    async loadAllContextFiles() {
        const contextFiles = {
            prd: "",
            types: "",
            brand: "",
            readme: "",
            componentList: "",
            architecture: "",
            globals: "",
        };
        // Load README (root)
        contextFiles.readme = await this.loadContextFile([
            "./README.md",
            "../README.md", // if in a subdirectory
        ]);
        // Load PRD
        contextFiles.prd = await this.loadContextFile([
            "./.mycontext/01-prd.md",
            "./.mycontext/prd.md",
            "./context/01-prd.md",
            "./context/prd.md",
        ]);
        // Load Types
        contextFiles.types = await this.loadContextFile([
            "./.mycontext/02-types.ts",
            "./.mycontext/types.ts",
            "./context/types.ts",
        ]);
        // Load Brand (CSS + Markdown)
        contextFiles.brand = await this.loadBrandContext();
        // Load Component List
        contextFiles.componentList = await this.loadContextFile([
            "./.mycontext/04-component-list.json",
            "./.mycontext/component-list.json",
            "./context/component-list.json",
        ]);
        // Load Architecture
        contextFiles.architecture = await this.loadContextFile([
            "./.mycontext/05-architecture.md",
            "./.mycontext/architecture.md",
            "./context/architecture.md",
        ]);
        // Load Globals CSS
        contextFiles.globals = await this.loadContextFile([
            "./.mycontext/brand/globals.css",
            "./.mycontext/globals.css",
            "./context/globals.css",
            "./app/globals.css",
        ]);
        return contextFiles;
    }
    /**
     * Load brand context (CSS + Markdown combined)
     */
    async loadBrandContext() {
        const brandParts = [];
        // Load CSS files
        const cssFiles = [
            "./.mycontext/brand/globals.css",
            "./.mycontext/globals.css",
            "./context/globals.css",
            "./app/globals.css",
        ];
        for (const file of cssFiles) {
            const content = await this.loadContextFile([file]);
            if (content) {
                brandParts.push(`=== CSS DESIGN TOKENS ===\n${content}`);
            }
        }
        // Load brand markdown
        const brandMd = await this.loadContextFile([
            "./.mycontext/03-branding.md",
            "./.mycontext/branding.md",
            "./context/branding.md",
        ]);
        if (brandMd) {
            brandParts.push(`=== BRAND GUIDELINES ===\n${brandMd}`);
        }
        // Load brand directory files
        const brandDirs = ["./.mycontext/brand/", "./context/brand/"];
        for (const dir of brandDirs) {
            if (await fs.pathExists(dir)) {
                const files = await fs.readdir(dir);
                for (const file of files) {
                    if (file.endsWith(".css") || file.endsWith(".md")) {
                        const filePath = path.join(dir, file);
                        const content = await fs.readFile(filePath, "utf8");
                        brandParts.push(`=== ${file.toUpperCase()} ===\n${content}`);
                    }
                }
            }
        }
        return brandParts.join("\n\n");
    }
    /**
     * Load a single context file from multiple candidates
     */
    async loadContextFile(candidates) {
        for (const candidate of candidates) {
            try {
                if (await fs.pathExists(candidate)) {
                    return await fs.readFile(candidate, "utf8");
                }
            }
            catch (error) {
                // Continue to next candidate
            }
        }
        return "";
    }
    /**
     * Get context summary for display
     */
    async getContextSummary() {
        try {
            const { enrichedContext } = await this.loadUnifiedDesignContext();
            return this.contextEnricher.getContextSummary(enrichedContext);
        }
        catch (error) {
            return "Failed to load context summary";
        }
    }
    /**
     * Check if all required context files exist
     */
    async validateContextFiles() {
        const missing = [];
        const warnings = [];
        // Check for PRD
        const prdExists = await this.loadContextFile([
            "./.mycontext/01-prd.md",
            "./.mycontext/prd.md",
            "./context/01-prd.md",
            "./context/prd.md",
        ]);
        if (!prdExists) {
            missing.push("PRD (Product Requirements Document)");
        }
        // Check for Component List
        const compListExists = await this.loadContextFile([
            "./.mycontext/04-component-list.json",
            "./.mycontext/component-list.json",
            "./context/component-list.json",
        ]);
        if (!compListExists) {
            missing.push("Component List");
        }
        // Check for Types (optional but recommended)
        const typesExists = await this.loadContextFile([
            "./.mycontext/02-types.ts",
            "./.mycontext/types.ts",
            "./context/types.ts",
        ]);
        if (!typesExists) {
            warnings.push("Types file not found (recommended for better component generation)");
        }
        // Check for Brand (optional but recommended)
        const brandExists = await this.loadBrandContext();
        if (!brandExists) {
            warnings.push("Brand context not found (recommended for consistent design)");
        }
        return {
            valid: missing.length === 0,
            missing,
            warnings,
        };
    }
    /**
     * Get design manifest summary
     */
    async getDesignManifestSummary() {
        return await this.manifestManager.getManifestSummary();
    }
    /**
     * Force regenerate design manifest
     */
    async regenerateDesignManifest() {
        console.log(chalk_1.default.blue("🔄 Regenerating design manifest..."));
        const contextFiles = await this.loadAllContextFiles();
        const designInput = {
            prd: contextFiles.prd,
            types: contextFiles.types,
            branding: contextFiles.brand,
            readme: contextFiles.readme,
            project_snapshot: await new ProjectScanner_1.ProjectScanner(this.projectPath).scan(),
            component_list: contextFiles.componentList,
            project_path: this.projectPath,
            force_regenerate: true,
        };
        try {
            const designOutput = await this.designPipeline.run(designInput, false);
            if (designOutput.success) {
                await this.manifestManager.saveDesignManifest(designOutput.manifest);
                console.log(chalk_1.default.green("✅ Design manifest regenerated"));
            }
            else {
                throw new Error("Failed to regenerate design manifest");
            }
        }
        catch (error) {
            // Pipeline failed - error already logged with recovery guidance
            throw error;
        }
    }
    // ============================================================================
    // STATE MANAGEMENT METHODS
    // ============================================================================
    /**
     * Check if there's a resumable state
     */
    async canResume() {
        return await this.stateManager.canResume();
    }
    /**
     * Load existing pipeline state
     */
    async loadState() {
        return await this.stateManager.loadState();
    }
    /**
     * Check if state is stale
     */
    async isStateStale() {
        return await this.stateManager.isStateStale();
    }
    /**
     * Get state summary
     */
    async getStateSummary() {
        return await this.stateManager.getStateSummary();
    }
}
exports.UnifiedDesignContextLoader = UnifiedDesignContextLoader;
//# sourceMappingURL=unifiedDesignContextLoader.js.map