"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.SetupShadcnCommand = void 0;
const child_process_1 = require("child_process");
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const spinner_1 = require("../utils/spinner");
class SetupShadcnCommand {
    constructor() {
        this.spinner = new spinner_1.EnhancedSpinner("Setting up shadcn/ui...");
    }
    async execute(options) {
        const projectRoot = process.cwd();
        console.log(chalk_1.default.blue("🎨 Setting up shadcn/ui components...\n"));
        // Check if we're in a Next.js project
        if (!(await this.isValidProject(projectRoot))) {
            console.log(chalk_1.default.red("❌ Not in a valid Next.js project"));
            console.log("   Please run this command from your Next.js project root");
            process.exit(1);
        }
        // Check if shadcn is already initialized
        if ((await this.isShadcnInitialized(projectRoot)) && !options.force) {
            console.log(chalk_1.default.yellow("⚠️  shadcn/ui is already initialized"));
            console.log("   Use --force to reinitialize");
            return;
        }
        // Initialize shadcn/ui first
        await this.initializeShadcn(projectRoot, options);
        // Install components
        if (options.all) {
            await this.installAllComponents(projectRoot);
        }
        else if (options.components && options.components.length > 0) {
            await this.installSpecificComponents(projectRoot, options.components);
        }
        else {
            // Interactive mode - let user choose
            await this.interactiveComponentInstallation(projectRoot);
        }
        console.log(chalk_1.default.green("\n✅ shadcn/ui setup completed!"));
        console.log(chalk_1.default.gray("   Run: mycontext generate-components all --with-tests"));
    }
    async isValidProject(projectRoot) {
        const packageJsonPath = path.join(projectRoot, "package.json");
        const nextConfigPath = path.join(projectRoot, "next.config.js");
        if (!(await fs.pathExists(packageJsonPath)))
            return false;
        try {
            const packageJson = await fs.readJson(packageJsonPath);
            return !!(packageJson.dependencies?.next || packageJson.devDependencies?.next);
        }
        catch {
            return false;
        }
    }
    async isShadcnInitialized(projectRoot) {
        const componentsPath = path.join(projectRoot, "components.json");
        const uiPath = path.join(projectRoot, "components", "ui");
        return ((await fs.pathExists(componentsPath)) && (await fs.pathExists(uiPath)));
    }
    async initializeShadcn(projectRoot, options) {
        console.log(chalk_1.default.cyan("📦 Initializing shadcn/ui..."));
        // Check package manager
        const packageManager = await this.detectPackageManager(projectRoot);
        let presetId = options.preset;
        if (!presetId && options.presetAgent) {
            try {
                const { ShadcnPresetAgent } = await Promise.resolve().then(() => __importStar(require("../services/ShadcnPresetAgent")));
                const agent = new ShadcnPresetAgent({ projectRoot, verbose: true });
                presetId = await agent.generatePreset();
            }
            catch (err) {
                console.log(chalk_1.default.yellow(`⚠️  Failed to generate preset: ${err.message}. Falling back to default.`));
            }
        }
        if (presetId) {
            console.log(chalk_1.default.blue(`🎨 Initializing shadcn/ui with preset: ${presetId}`));
            await this.runShadcnCommand(projectRoot, packageManager, [
                "init",
                "--preset",
                presetId,
                "--template",
                "next"
            ]);
        }
        else {
            // Run shadcn init
            await this.runShadcnCommand(projectRoot, packageManager, ["init", "--yes"]);
        }
    }
    async installAllComponents(projectRoot) {
        console.log(chalk_1.default.cyan("\n📦 Installing all essential shadcn/ui components..."));
        console.log(chalk_1.default.gray("   This may take a few minutes...\n"));
        const components = [
            "accordion",
            "alert",
            "alert-dialog",
            "aspect-ratio",
            "avatar",
            "badge",
            "breadcrumb",
            "button",
            "calendar",
            "card",
            "carousel",
            "chart",
            "checkbox",
            "collapsible",
            "command",
            "context-menu",
            "dialog",
            "drawer",
            "dropdown-menu",
            "form",
            "hover-card",
            "input",
            "input-otp",
            "label",
            "menubar",
            "navigation-menu",
            "pagination",
            "popover",
            "progress",
            "radio-group",
            "resizable",
            "scroll-area",
            "select",
            "separator",
            "sheet",
            "sidebar",
            "skeleton",
            "slider",
            "sonner",
            "switch",
            "table",
            "tabs",
            "textarea",
            "toggle",
            "toggle-group",
            "tooltip",
            "field",
            "button-group",
            "empty",
            "input-group",
            "spinner",
        ];
        const packageManager = await this.detectPackageManager(projectRoot);
        // Install components in batches to avoid overwhelming the terminal
        const batchSize = 10;
        for (let i = 0; i < components.length; i += batchSize) {
            const batch = components.slice(i, i + batchSize);
            console.log(chalk_1.default.gray(`   Installing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(components.length / batchSize)}: ${batch.join(", ")}`));
            await this.runShadcnCommand(projectRoot, packageManager, [
                "add",
                ...batch,
            ]);
            // Small delay between batches
            if (i + batchSize < components.length) {
                await new Promise((resolve) => setTimeout(resolve, 1000));
            }
        }
    }
    async installSpecificComponents(projectRoot, components) {
        console.log(chalk_1.default.cyan(`\n📦 Installing ${components.length} shadcn/ui components...`));
        const packageManager = await this.detectPackageManager(projectRoot);
        await this.runShadcnCommand(projectRoot, packageManager, [
            "add",
            ...components,
        ]);
    }
    async interactiveComponentInstallation(projectRoot) {
        console.log(chalk_1.default.cyan("\n📦 Interactive shadcn/ui component installation"));
        console.log(chalk_1.default.gray("   You will now interact directly with shadcn/ui CLI\n"));
        const packageManager = await this.detectPackageManager(projectRoot);
        // Provide instructions to user
        console.log(chalk_1.default.yellow("💡 Instructions:"));
        console.log("   • Select the components you need");
        console.log("   • Use spacebar to select/deselect components");
        console.log("   • Press Enter to confirm selection");
        console.log("   • Press Ctrl+C to cancel\n");
        // Let user interact with shadcn directly
        await this.runShadcnCommand(projectRoot, packageManager, ["add"]);
    }
    async runShadcnCommand(projectRoot, packageManager, args) {
        return new Promise((resolve, reject) => {
            const command = packageManager === "npm"
                ? "npx"
                : packageManager === "pnpm"
                    ? "pnpm dlx"
                    : "yarn dlx";
            const fullCommand = [command, "shadcn@latest", ...args];
            console.log(chalk_1.default.gray(`   Running: ${fullCommand.join(" ")}`));
            const child = (0, child_process_1.spawn)(command, ["shadcn@latest", ...args], {
                cwd: projectRoot,
                stdio: "inherit", // Pass all stdio directly to user
                shell: true,
            });
            child.on("close", (code) => {
                if (code === 0) {
                    resolve();
                }
                else {
                    reject(new Error(`shadcn command failed with code ${code}`));
                }
            });
            child.on("error", (error) => {
                reject(error);
            });
        });
    }
    async detectPackageManager(projectRoot) {
        // Check for lock files
        const pnpmLock = path.join(projectRoot, "pnpm-lock.yaml");
        const yarnLock = path.join(projectRoot, "yarn.lock");
        const packageLock = path.join(projectRoot, "package-lock.json");
        if (await fs.pathExists(pnpmLock))
            return "pnpm";
        if (await fs.pathExists(yarnLock))
            return "yarn";
        if (await fs.pathExists(packageLock))
            return "npm";
        // Default to npm if no lock file found
        return "npm";
    }
}
exports.SetupShadcnCommand = SetupShadcnCommand;
//# sourceMappingURL=setup-shadcn.js.map