"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.PromoteCommand = void 0;
const chalk_1 = __importDefault(require("chalk"));
const path_1 = __importDefault(require("path"));
const fs_1 = require("fs");
const fsExtra = __importStar(require("fs-extra"));
const spinner_1 = require("../utils/spinner");
class PromoteCommand {
    constructor() {
        this.spinner = new spinner_1.EnhancedSpinner("Promoting components...");
    }
    async execute(target, options) {
        const { component, group, all, keepContext = false, addToGitignore = true, } = options;
        console.log(chalk_1.default.blue.bold("🚀 Promoting Components to Production\n"));
        try {
            if (component) {
                await this.promoteComponent(component, keepContext, addToGitignore);
            }
            else if (group) {
                await this.promoteGroup(group, keepContext, addToGitignore);
            }
            else if (all) {
                await this.promoteAll(keepContext, addToGitignore);
            }
            else {
                console.log(chalk_1.default.yellow("Please specify --component, --group, or --all"));
                return;
            }
            console.log(chalk_1.default.green.bold("\n✅ Components promoted successfully!"));
            this.printNextSteps();
        }
        catch (error) {
            this.spinner.fail("Promotion failed");
            throw error;
        }
    }
    async promoteComponent(componentName, keepContext, addToGitignore) {
        this.spinner.start().updateText(`Promoting component: ${componentName}`);
        const componentsDir = path_1.default.join(process.cwd(), "src", "components");
        const componentPath = await this.findComponentPath(componentsDir, componentName);
        if (!componentPath) {
            throw new Error(`Component ${componentName} not found`);
        }
        const mycontextDir = path_1.default.join(componentPath, ".mycontext");
        if (!(await fsExtra.pathExists(mycontextDir))) {
            console.log(chalk_1.default.yellow(`No .mycontext directory found for ${componentName}`));
            return;
        }
        // Move context files to parent directory
        await this.moveContextFiles(mycontextDir, componentPath, keepContext);
        // Update import paths in component files
        await this.updateImportPaths(componentPath, componentName);
        // Add to gitignore if requested
        if (addToGitignore) {
            await this.addToGitignore(componentPath);
        }
        this.spinner.succeed(`Component ${componentName} promoted`);
    }
    async promoteGroup(groupName, keepContext, addToGitignore) {
        this.spinner.start().updateText(`Promoting group: ${groupName}`);
        const groupDir = path_1.default.join(process.cwd(), "src", "components", groupName);
        if (!(await fsExtra.pathExists(groupDir))) {
            throw new Error(`Group ${groupName} not found`);
        }
        const components = await fs_1.promises.readdir(groupDir);
        const componentDirs = components.filter(async (item) => {
            const itemPath = path_1.default.join(groupDir, item);
            const stat = await fs_1.promises.stat(itemPath);
            return stat.isDirectory();
        });
        for (const componentDir of componentDirs) {
            const componentPath = path_1.default.join(groupDir, componentDir);
            const mycontextDir = path_1.default.join(componentPath, ".mycontext");
            if (await fsExtra.pathExists(mycontextDir)) {
                await this.moveContextFiles(mycontextDir, componentPath, keepContext);
                await this.updateImportPaths(componentPath, componentDir);
                if (addToGitignore) {
                    await this.addToGitignore(componentPath);
                }
            }
        }
        this.spinner.succeed(`Group ${groupName} promoted`);
    }
    async promoteAll(keepContext, addToGitignore) {
        this.spinner.start().updateText("Promoting all components");
        const componentsDir = path_1.default.join(process.cwd(), "src", "components");
        if (!(await fsExtra.pathExists(componentsDir))) {
            throw new Error("Components directory not found");
        }
        const groups = await fs_1.promises.readdir(componentsDir);
        for (const group of groups) {
            const groupPath = path_1.default.join(componentsDir, group);
            const stat = await fs_1.promises.stat(groupPath);
            if (stat.isDirectory()) {
                await this.promoteGroup(group, keepContext, addToGitignore);
            }
        }
        this.spinner.succeed("All components promoted");
    }
    async findComponentPath(componentsDir, componentName) {
        const groups = await fs_1.promises.readdir(componentsDir);
        for (const group of groups) {
            const groupPath = path_1.default.join(componentsDir, group);
            const stat = await fs_1.promises.stat(groupPath);
            if (stat.isDirectory()) {
                const componentPath = path_1.default.join(groupPath, componentName);
                if (await fsExtra.pathExists(componentPath)) {
                    return componentPath;
                }
            }
        }
        return null;
    }
    async moveContextFiles(mycontextDir, componentPath, keepContext) {
        const files = await fs_1.promises.readdir(mycontextDir);
        for (const file of files) {
            const sourcePath = path_1.default.join(mycontextDir, file);
            const targetPath = path_1.default.join(componentPath, file);
            // Skip if target already exists
            if (await fsExtra.pathExists(targetPath)) {
                console.log(chalk_1.default.yellow(`Skipping ${file} - already exists`));
                continue;
            }
            await fs_1.promises.rename(sourcePath, targetPath);
        }
        // Remove .mycontext directory if not keeping context
        if (!keepContext) {
            await fs_1.promises.rmdir(mycontextDir);
        }
    }
    async updateImportPaths(componentPath, componentName) {
        const componentFile = path_1.default.join(componentPath, `${componentName}.tsx`);
        if (!(await fsExtra.pathExists(componentFile))) {
            return;
        }
        let content = await fs_1.promises.readFile(componentFile, "utf-8");
        // Update relative imports from .mycontext to current directory
        content = content.replace(/from ['"]\.\/\.mycontext\/([^'"]+)['"]/g, 'from "./$1"');
        // Update relative imports from .mycontext to parent directory
        content = content.replace(/from ['"]\.\.\/\.mycontext\/([^'"]+)['"]/g, 'from "./$1"');
        await fs_1.promises.writeFile(componentFile, content);
    }
    async addToGitignore(componentPath) {
        const gitignorePath = path_1.default.join(process.cwd(), ".gitignore");
        const mycontextIgnore = ".mycontext/";
        if (await fsExtra.pathExists(gitignorePath)) {
            let content = await fs_1.promises.readFile(gitignorePath, "utf-8");
            if (!content.includes(mycontextIgnore)) {
                content += `\n# MyContext development files\n${mycontextIgnore}\n`;
                await fs_1.promises.writeFile(gitignorePath, content);
            }
        }
        else {
            await fs_1.promises.writeFile(gitignorePath, `# MyContext development files\n${mycontextIgnore}\n`);
        }
    }
    printNextSteps() {
        console.log(chalk_1.default.yellow("\n📋 Next Steps:"));
        console.log(chalk_1.default.gray("1. Review the promoted components"));
        console.log(chalk_1.default.gray("2. Implement the server actions and hooks"));
        console.log(chalk_1.default.gray("3. Test the components in your application"));
        console.log(chalk_1.default.gray("4. Commit your changes to version control"));
        console.log(chalk_1.default.gray("\n💡 Tip: Use --keep-context to preserve .mycontext directories"));
    }
}
exports.PromoteCommand = PromoteCommand;
//# sourceMappingURL=promote.js.map