import chalk from 'chalk';
import inquirer from 'inquirer';
import fs from 'fs';
import path from 'path';
import { writeFile, mkdir } from 'node:fs/promises';
import { WIDGET_TEMPLATE, COMPONENT_TEMPLATE, NAVIGATOR_TEMPLATE } from './templates.mjs';
export async function createAction(options) {
    try {
        // Check if we're in a valid apptile project directory
        const currentDir = process.cwd();
        const configPath = path.resolve(currentDir, "apptile.config.mjson");
        if (!fs.existsSync(configPath)) {
            console.log(chalk.red("Error: apptile.config.mjson not found in current directory."));
            console.log(chalk.red("Please run this command in a valid apptile project directory."));
            process.exit(1);
        }
        // Read the config to get APP_ID
        let config;
        try {
            const configRaw = fs.readFileSync(configPath, { encoding: "utf8" });
            config = JSON.parse(configRaw);
        }
        catch (err) {
            console.log(chalk.red("Error: Could not read apptile.config.mjson"));
            process.exit(1);
        }
        if (!config.APP_ID) {
            console.log(chalk.red("Error: APP_ID not found in apptile.config.mjson"));
            process.exit(1);
        }
        const appId = config.APP_ID;
        // Determine the type if not provided
        let type = options.type;
        if (!type) {
            const typeAnswer = await inquirer.prompt([{
                    type: 'list',
                    name: 'type',
                    message: 'What would you like to create?',
                    choices: ['plugin', 'navigator']
                }]);
            type = typeAnswer.type;
        }
        // Validate type
        if (type !== 'plugin' && type !== 'navigator') {
            console.log(chalk.red("Error: --type must be either 'plugin' or 'navigator'"));
            process.exit(1);
        }
        if (type === 'plugin') {
            await createPlugin(appId, currentDir);
        }
        else if (type === 'navigator') {
            await createNavigator(appId, currentDir);
        }
    }
    catch (err) {
        console.error(chalk.red("Error during creation:"), err);
        process.exit(1);
    }
}
async function createPlugin(appId, projectRoot) {
    console.log(chalk.blue("Creating a new plugin..."));
    // Get plugin data from user using inquirer
    const pluginData = await getPluginDataFromUser();
    // Create plugin directory structure
    const pluginRoot = path.resolve(projectRoot, `remoteCode/plugins`, pluginData.pluginRegistryName.toLowerCase());
    try {
        await mkdir(path.resolve(pluginRoot, "source"), { recursive: true });
        await mkdir(path.resolve(pluginRoot, "dist"), { recursive: true });
    }
    catch (err) {
        if (err?.code !== "EEXIST") {
            console.error("Error creating plugin directories:", err);
            throw err;
        }
    }
    // Template replacement data
    const templateData = {
        __LABEL_PREFIX__: pluginData.labelPrefix,
        __LISTING_NAME__: pluginData.listingName,
        __DISPLAY_DESCRIPTION__: pluginData.displayDescription,
        __LISTING_ICON__: pluginData.listingIcon,
        __PLUGIN_REGISTRY_NAME__: pluginData.pluginRegistryName,
        __PLUGIN_NAME__: appId + "/" + pluginData.listingName,
    };
    // Create widget.mjsx file using embedded template
    let widgetContent = WIDGET_TEMPLATE;
    // Replace all template variables
    Object.entries(templateData).forEach(([key, value]) => {
        widgetContent = widgetContent.replace(new RegExp(key, 'g'), value);
    });
    await writeFile(path.resolve(pluginRoot, `source/${pluginData.entry}`), widgetContent);
    // Create component.mjsx file using embedded template
    let componentContent = COMPONENT_TEMPLATE;
    // Replace all template variables
    Object.entries(templateData).forEach(([key, value]) => {
        componentContent = componentContent.replace(new RegExp(key, 'g'), value);
    });
    await writeFile(path.resolve(pluginRoot, `source/${pluginData.editableFilePath}`), componentContent);
    // Create metadata.mjson file
    const metadata = {
        editableFilePath: `source/${pluginData.editableFilePath}`,
        entry: `source/${pluginData.entry}`
    };
    await writeFile(path.resolve(pluginRoot, "source/metadata.mjson"), JSON.stringify(metadata, null, 2));
    console.log(chalk.green(`Successfully created plugin: ${pluginData.listingName}`));
    console.log(chalk.blue(`Plugin location: ${pluginRoot}`));
    console.log(chalk.blue(`Editable file: ${pluginData.editableFilePath}`));
    console.log(chalk.blue(`Entry file: ${pluginData.entry}`));
}
async function createNavigator(_appId, projectRoot) {
    console.log(chalk.blue("Creating a new navigator..."));
    // Get navigator data from user
    const navigatorData = await getNavigatorDataFromUser();
    // Create navigator directory structure
    const navigatorRoot = path.resolve(projectRoot, `remoteCode/navigators`, navigatorData.name.toLowerCase());
    try {
        await mkdir(path.resolve(navigatorRoot, "source"), { recursive: true });
        await mkdir(path.resolve(navigatorRoot, "dist"), { recursive: true });
    }
    catch (err) {
        if (err?.code !== "EEXIST") {
            console.error("Error creating navigator directories:", err);
            throw err;
        }
    }
    // Create navigator file using embedded template
    await writeFile(path.resolve(navigatorRoot, "source/navigator.mjsx"), NAVIGATOR_TEMPLATE);
    // Create metadata.mjson file for navigator
    const metadata = {
        editableFilePath: "source/navigator.mjsx",
        entry: "source/navigator.mjsx"
    };
    await writeFile(path.resolve(navigatorRoot, "source/metadata.mjson"), JSON.stringify(metadata, null, 2));
    console.log(chalk.green(`Successfully created navigator: ${navigatorData.name}`));
    console.log(chalk.blue(`Navigator location: ${navigatorRoot}`));
}
async function getPluginDataFromUser() {
    const questions = [
        {
            type: 'input',
            name: 'listingName',
            message: 'Enter the plugin listing name:',
            validate: (input) => input.trim() ? true : 'Plugin name cannot be empty'
        },
        {
            type: 'input',
            name: 'pluginRegistryName',
            message: 'Enter the plugin registry name (used for directory and internal naming):',
            validate: (input) => {
                if (!input.trim())
                    return 'Registry name cannot be empty';
                if (!/^[a-zA-Z0-9_-]+$/.test(input))
                    return 'Registry name can only contain letters, numbers, hyphens, and underscores';
                return true;
            }
        },
        {
            type: 'input',
            name: 'displayDescription',
            message: 'Enter the plugin description:',
            validate: (input) => input.trim() ? true : 'Description cannot be empty'
        },
        {
            type: 'input',
            name: 'labelPrefix',
            message: 'Enter the label prefix:',
            default: 'SDK'
        },
        {
            type: 'input',
            name: 'listingIcon',
            message: 'Enter the listing icon (icon name or URL):',
            default: 'widget'
        }
    ];
    const answers = await inquirer.prompt(questions);
    // Ask about file naming
    const fileQuestions = [
        {
            type: 'confirm',
            name: 'useCustomFiles',
            message: 'Would you like to customize the default file names? (default: component.mjsx for editable, widget.mjsx for entry)',
            default: false
        }
    ];
    const fileAnswers = await inquirer.prompt(fileQuestions);
    let editableFilePath = 'component.mjsx';
    let entry = 'widget.mjsx';
    if (fileAnswers['useCustomFiles']) {
        const customFileQuestions = [
            {
                type: 'input',
                name: 'editableFilePath',
                message: 'Enter the editable file name:',
                default: 'component.mjsx',
                validate: (input) => {
                    if (!input.trim())
                        return 'File name cannot be empty';
                    if (!input.endsWith('.mjsx') && !input.endsWith('.mjs'))
                        return 'File must have .mjsx or .mjs extension';
                    return true;
                }
            },
            {
                type: 'input',
                name: 'entry',
                message: 'Enter the entry file name:',
                default: 'widget.mjsx',
                validate: (input) => {
                    if (!input.trim())
                        return 'File name cannot be empty';
                    if (!input.endsWith('.mjsx') && !input.endsWith('.mjs'))
                        return 'File must have .mjsx or .mjs extension';
                    return true;
                }
            }
        ];
        const customFileAnswers = await inquirer.prompt(customFileQuestions);
        editableFilePath = customFileAnswers['editableFilePath'];
        entry = customFileAnswers['entry'];
    }
    return {
        listingName: answers.listingName,
        pluginRegistryName: answers.pluginRegistryName,
        displayDescription: answers.displayDescription,
        labelPrefix: answers.labelPrefix,
        listingIcon: answers.listingIcon,
        editableFilePath,
        entry
    };
}
async function getNavigatorDataFromUser() {
    const questions = [
        {
            type: 'input',
            name: 'name',
            message: 'Enter the navigator name:',
            validate: (input) => {
                if (!input.trim())
                    return 'Navigator name cannot be empty';
                if (!/^[a-zA-Z0-9_-]+$/.test(input))
                    return 'Navigator name can only contain letters, numbers, hyphens, and underscores';
                return true;
            }
        }
    ];
    const answers = await inquirer.prompt(questions);
    return {
        name: answers.name
    };
}
