/* eslint-disable import/default */
import { Command, Flags, ux } from "@oclif/core";
import log4js from "log4js";
import { newAppArg } from "../../args/new-app.js";
import locatorService from "../../services/locator.service.js";
import { CLIENT_TEMPLATE, PLATFORM_TEMPLATE } from "../../shared/constants.js";
export class New extends Command {
    static args = {
        newApp: newAppArg({
            description: "The type of new app to create: browser-platform | browser-client",
            required: true,
            supportedApps: ["browser-platform", "browser-client"]
        })
    };
    static description = "Bootstraps a new io.Connect app.";
    static examples = [
        `<%= config.bin %> <%= command.id %> browser-platform`,
        `<%= config.bin %> <%= command.id %> browser-platform@3.1`,
        `<%= config.bin %> <%= command.id %> browser-client`,
        `<%= config.bin %> <%= command.id %> browser-client@3.2`,
    ];
    static flags = {
        name: Flags.string({
            char: "n",
            description: "The name of your IO.Connect Browser app.",
            multiple: false,
            required: false,
        }),
        template: Flags.string({
            char: "t",
            description: "The IO.Connect Browser app template.",
            multiple: false,
            options: [...Object.values(PLATFORM_TEMPLATE), ...Object.values(CLIENT_TEMPLATE)],
            required: false,
        }),
        yes: Flags.boolean({ char: "y", default: false, description: "Skip prompts and use default values for all options" }),
    };
    static usage = "new <NEWAPP>";
    async run() {
        const logger = log4js.getLogger("Command: New");
        const { args, flags } = await this.parse(New);
        logger.info(`Creating new app with args: ${JSON.stringify(args)} and flags: ${JSON.stringify(flags)}.`);
        ux.info(`Building new ${args.newApp} app`);
        const appType = args.newApp.split("@")[0];
        const appVersion = args.newApp.split("@")[1] || "latest";
        if (flags.template) {
            locatorService.validationService.validateAppTypeAndTemplate(appType, flags.template);
        }
        if (appType === "browser-platform") {
            await this.createBrowserPlatformApp(logger, appVersion, flags);
            return;
        }
        if (appType === "browser-client") {
            await this.createBrowserClient(logger, appVersion, flags);
            return;
        }
        throw new Error(`Invalid input. Supported options are: browser-platform | browser-client`);
    }
    async createBrowserClient(logger, appVersion, flags) {
        const template = flags.yes ? "vanilla-js" : (flags.template || await locatorService.promptingService.select({
            choices: [
                {
                    description: "[Default] Will bootstrap a bare-bones vanilla JS app as a IO.Connect Browser Client",
                    name: CLIENT_TEMPLATE.VANILLA_JS,
                    value: CLIENT_TEMPLATE.VANILLA_JS,
                },
                {
                    description: "Will bootstrap a React app as a IO.Connect Browser Client",
                    name: CLIENT_TEMPLATE.REACT,
                    value: CLIENT_TEMPLATE.REACT
                }
            ],
            message: "Select a client template"
        }));
        const appName = flags.yes ? "io-cb-client" : (flags.name || await locatorService.promptingService.input({ message: "Please enter a name for your app" }));
        if (!appName || appName.length === 0) {
            ux.error("Please enter a valid app name.");
        }
        logger.info(`Creating new browser-client app with version ${appVersion} and template ${template} and name ${appName}.`);
        await locatorService.validationService.validateAppName(appName);
        try {
            await locatorService.browserClientService.build({ appName, template, version: appVersion });
            logger.info(`New browser-client app creation complete.`);
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
        }
        catch (error) {
            await locatorService.browserClientService.clean({ appName, template, version: appVersion });
            logger.error(`New browser-client app creation failed with error:`);
            logger.error(error);
            ux.error(error);
        }
    }
    async createBrowserPlatformApp(logger, appVersion, flags) {
        const template = flags.yes ? PLATFORM_TEMPLATE.VANILLA_JS : (flags.template || await locatorService.promptingService.select({
            choices: [
                {
                    description: "[Default] Will bootstrap a bare-bones vanilla JS app as a IO.Connect Browser Platform",
                    name: PLATFORM_TEMPLATE.VANILLA_JS,
                    value: PLATFORM_TEMPLATE.VANILLA_JS,
                },
                {
                    description: "Will bootstrap a full-featured IO.Connect Browser Home app.",
                    name: PLATFORM_TEMPLATE.HOME_REACT_WSP,
                    value: PLATFORM_TEMPLATE.HOME_REACT_WSP,
                },
                {
                    description: "Will bootstrap a IO.Connect Browser Seed project.",
                    name: PLATFORM_TEMPLATE.DEV_REACT_SEED,
                    value: PLATFORM_TEMPLATE.DEV_REACT_SEED
                }
            ],
            message: "Select a platform template."
        }));
        const appName = flags.yes ? "io-cb-platform" : (flags.name || await locatorService.promptingService.input({ message: "Please enter a name for your app" }));
        if (!appName || appName.length === 0) {
            ux.error("Please enter a valid app name.");
        }
        logger.info(`Creating new browser-platform app with version ${appVersion} and template ${template} and name ${appName}.`);
        await locatorService.validationService.validateAppName(appName);
        try {
            await locatorService.browserPlatformService.build({ appName, template, version: appVersion });
            logger.info(`New browser-platform app creation complete.`);
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
        }
        catch (error) {
            await locatorService.browserPlatformService.clean({ appName, template, version: appVersion });
            logger.error(`New browser-platform app creation failed with error:`);
            logger.error(error);
            ux.error(error);
        }
    }
}
