"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ShadcnPresetAgent = void 0;
const playwright_1 = require("playwright");
const core_1 = require("@myycontext/core");
const chalk_1 = __importDefault(require("chalk"));
class ShadcnPresetAgent {
    constructor(config) {
        this.projectRoot = config.projectRoot;
        this.verbose = !!config.verbose;
    }
    /**
     * Generates a custom shadcn/ui preset ID from the project's design manifest.
     */
    async generatePreset() {
        console.log(chalk_1.default.cyan("🎨 Analyzing design context for custom shadcn/ui preset..."));
        const manifestManager = new core_1.DesignManifestManager(this.projectRoot);
        const manifest = await manifestManager.loadDesignManifest();
        if (!manifest) {
            console.log(chalk_1.default.yellow("⚠️  No design manifest found at .mycontext/context.json. Using default preset."));
            return "b0"; // Default preset
        }
        const { design_brief, visual_system } = manifest.phases;
        // 1. Map Style (Nova is default)
        const style = design_brief.blended_style?.toLowerCase().includes("default") ? "Default" : "Nova";
        // 2. Map Base Color
        const primaryHex = visual_system?.colors?.primary || design_brief.primary_color || "#737373";
        const baseColor = this.getClosestBaseColor(primaryHex);
        // 3. Map Theme (Neutral/Amber/Cyan etc., standard is Neutral)
        let theme = "Neutral";
        if (design_brief.theme === "dark") {
            theme = "Neutral"; // Shadcn create tool theme is actually the semantic color scheme theme
        }
        // Check if support colors contain other themes
        const supportColors = design_brief.support_colors || [];
        if (supportColors.some(c => c.toLowerCase().includes("amber")))
            theme = "Amber";
        if (supportColors.some(c => c.toLowerCase().includes("cyan")))
            theme = "Cyan";
        // 4. Map Font
        const headingFont = design_brief.typography?.heading || "Inter";
        const bodyFont = design_brief.typography?.body || "Inter";
        // 5. Map Radius
        let radius = "0.5";
        const manifestRadius = visual_system?.radii?.md;
        if (manifestRadius) {
            if (manifestRadius.includes("0"))
                radius = "0";
            else if (manifestRadius.includes("0.3"))
                radius = "0.3";
            else if (manifestRadius.includes("0.5"))
                radius = "0.5";
            else if (manifestRadius.includes("0.75"))
                radius = "0.75";
            else if (manifestRadius.includes("1"))
                radius = "1.0";
        }
        if (this.verbose) {
            console.log(chalk_1.default.gray(`   Mapped Config: Style=${style}, BaseColor=${baseColor}, Theme=${theme}, HeadingFont=${headingFont}, BodyFont=${bodyFont}, Radius=${radius}`));
        }
        return await this.runBrowserAutomation({
            style,
            baseColor,
            theme,
            headingFont,
            bodyFont,
            radius
        });
    }
    async runBrowserAutomation(options) {
        console.log(chalk_1.default.cyan("🌐 Launching headless browser to compile shadcn/ui preset..."));
        const browser = await playwright_1.chromium.launch({ headless: true });
        const context = await browser.newContext({
            userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
            viewport: { width: 1280, height: 800 }
        });
        const page = await context.newPage();
        try {
            if (this.verbose) {
                console.log(chalk_1.default.gray("   Navigating to https://ui.shadcn.com/create..."));
            }
            await page.goto("https://ui.shadcn.com/create", { waitUntil: "load", timeout: 30000 });
            await page.waitForTimeout(3000); // Wait for client hydration
            // Close default onboarding dialog if open
            const getStartedBtn = page.locator("button:has-text('Get Started')");
            if (await getStartedBtn.count() > 0 && await getStartedBtn.isVisible()) {
                if (this.verbose)
                    console.log(chalk_1.default.gray("   Closing 'Get Started' onboarding modal..."));
                await getStartedBtn.click();
                await page.waitForTimeout(1000);
            }
            else {
                await page.keyboard.press("Escape");
                await page.waitForTimeout(1000);
            }
            // Close any other dialogs
            await page.keyboard.press("Escape");
            await page.waitForTimeout(500);
            // --- APPLY CONFIGURATIONS ---
            // 1. Style Selection (Default vs Nova)
            if (options.style !== "Nova") {
                if (this.verbose)
                    console.log(chalk_1.default.gray(`   Selecting Style: ${options.style}`));
                await this.selectSidebarDropdown(page, "Style", options.style);
            }
            // 2. Base Color Selection
            if (this.verbose)
                console.log(chalk_1.default.gray(`   Selecting Base Color: ${options.style === "Nova" ? "Zinc" : options.baseColor}`));
            // Nova base colors are slightly different, but Zinc/Slate/Stone map generally
            await this.selectSidebarDropdown(page, "Base Color", options.baseColor);
            // 3. Theme Selection
            if (options.theme !== "Neutral") {
                if (this.verbose)
                    console.log(chalk_1.default.gray(`   Selecting Theme: ${options.theme}`));
                await this.selectSidebarDropdown(page, "Theme", options.theme);
            }
            // 4. Heading Font
            if (options.headingFont !== "Inter") {
                if (this.verbose)
                    console.log(chalk_1.default.gray(`   Selecting Heading Font: ${options.headingFont}`));
                await this.selectSidebarDropdown(page, "Heading", options.headingFont);
            }
            // 5. Body Font
            if (options.bodyFont !== "Inter") {
                if (this.verbose)
                    console.log(chalk_1.default.gray(`   Selecting Body Font: ${options.bodyFont}`));
                await this.selectSidebarDropdown(page, "Font", options.bodyFont);
            }
            // 6. Radius
            if (options.radius !== "0.5") {
                if (this.verbose)
                    console.log(chalk_1.default.gray(`   Selecting Radius: ${options.radius}`));
                await this.selectSidebarDropdown(page, "Radius", options.radius);
            }
            // --- GET CODE AND EXTRACT PRESET ---
            if (this.verbose)
                console.log(chalk_1.default.gray("   Clicking 'Get Code' button..."));
            const getCodeBtn = page.locator("button:has-text('Get Code')");
            await getCodeBtn.first().click({ force: true });
            await page.waitForTimeout(3000);
            const fullHtml = await page.evaluate(() => document.body.innerHTML);
            const match = fullHtml.match(/preset=([a-zA-Z0-9]+)/) || fullHtml.match(/--preset\s+([a-zA-Z0-9]+)/);
            if (match && match[1]) {
                const presetId = match[1];
                console.log(chalk_1.default.green(`🎉 Success! Generated custom shadcn/ui preset ID: ${presetId}`));
                return presetId;
            }
            console.log(chalk_1.default.yellow("⚠️  Could not extract preset ID from modal code. Falling back to default 'b0'."));
            return "b0";
        }
        catch (error) {
            console.log(chalk_1.default.yellow(`⚠️  Playwright agent failed: ${error.message}. Falling back to default 'b0'.`));
            return "b0";
        }
        finally {
            await browser.close();
        }
    }
    /**
     * Helper to click and select options in the customizer sidebar dropdowns
     */
    async selectSidebarDropdown(page, triggerText, optionText) {
        try {
            // Find trigger button by looking for element that has triggering text in its descendants
            const trigger = page.locator(`button`, { hasText: triggerText }).first();
            if (await trigger.count() > 0) {
                await trigger.click();
                await page.waitForTimeout(500);
                // Find the option in the list/dropdown. Dropdown options might contain exact text or close matching
                const option = page.locator(`[role="option"], [role="menuitem"], button`, { hasText: optionText }).first();
                if (await option.count() > 0) {
                    await option.click();
                    await page.waitForTimeout(500);
                }
                else {
                    // If no specific option found, click escape to close dropdown
                    await page.keyboard.press("Escape");
                }
            }
        }
        catch (err) {
            // Fail silently and keep default option
            await page.keyboard.press("Escape");
        }
    }
    getClosestBaseColor(hex) {
        let cleanHex = hex.trim().replace("#", "");
        if (cleanHex.length === 3) {
            cleanHex = cleanHex.split("").map(c => c + c).join("");
        }
        if (cleanHex.length !== 6)
            return "Neutral";
        const r = parseInt(cleanHex.substring(0, 2), 16);
        const g = parseInt(cleanHex.substring(2, 4), 16);
        const b = parseInt(cleanHex.substring(4, 6), 16);
        const baseColors = [
            { name: "Zinc", rgb: [82, 82, 91] },
            { name: "Slate", rgb: [100, 116, 139] },
            { name: "Stone", rgb: [120, 113, 108] },
            { name: "Gray", rgb: [107, 114, 128] },
            { name: "Neutral", rgb: [115, 115, 115] },
            { name: "Red", rgb: [239, 68, 68] },
            { name: "Orange", rgb: [249, 115, 22] },
            { name: "Amber", rgb: [245, 158, 11] },
            { name: "Yellow", rgb: [234, 179, 8] },
            { name: "Green", rgb: [34, 197, 94] },
            { name: "Blue", rgb: [59, 130, 246] },
            { name: "Rose", rgb: [244, 63, 94] }
        ];
        let closestColor = "Neutral";
        let minDistance = Infinity;
        for (const color of baseColors) {
            const distance = Math.sqrt(Math.pow(r - color.rgb[0], 2) +
                Math.pow(g - color.rgb[1], 2) +
                Math.pow(b - color.rgb[2], 2));
            if (distance < minDistance) {
                minDistance = distance;
                closestColor = color.name;
            }
        }
        return closestColor;
    }
}
exports.ShadcnPresetAgent = ShadcnPresetAgent;
//# sourceMappingURL=ShadcnPresetAgent.js.map