import * as fs from "fs";
import * as path from "path";
import axios, { AxiosResponse } from "axios";
import * as handlebars from "handlebars";

// region types
type ModuleTab = {
    id: number;
    key: string;
    label: string;
    iconName: string;
    moduleId: number;
};

type Module = {
    id: number;
    label: string;
    description: string;
    tabs: ModuleTab[];
};

type ModulesResponse = {
    items: Module[];
};

type Args = {
    [key: string]: string | boolean;
};
// endregion

// region utils
const getArgs = (): Args =>
    process.argv.slice(2).reduce((args: Args, arg: string) => {
        if (arg.startsWith("--")) {
            // Handle long arguments like --port=8000
            const [key, value] = arg.slice(2).split("=");
            args[key] = value !== undefined ? value : true;
        } else if (arg.startsWith("-") && arg.length > 1) {
            // Handle short arguments like -p=8000
            const [key, value] = arg.slice(1).split("=");
            args[key] = value !== undefined ? value : true;
        }
        return args;
    }, {});
// endregion

const kwargs = getArgs();

// region constants
const HOST = kwargs.host ?? kwargs.h ?? "127.0.0.1";
const PORT = kwargs.port ?? kwargs.p ?? "8000";
const ENDPOINT = `http://${HOST}:${PORT}/api/module/built-in/`;

const TEMPLATE_PATH = path.join(
    __dirname,
    "templates",
    "modulesFileTemplate.hbs"
);
const OUTPUT_PATH = path.join(__dirname, "..", "modules.tsx");
// endregion

const templateSource = fs.readFileSync(TEMPLATE_PATH, "utf8");
const template = handlebars.compile(templateSource);

handlebars.registerHelper("uppercase", text => {
    return text.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
});

function pascalcase(s: string): string {
    return s.replace(/(?:^|_+)([a-zA-Z0-9])/g, (_, c) => c.toUpperCase());
}

handlebars.registerHelper("pascalcase", pascalcase);

const generateRows = (modules: Module[]) => {
    try {
        const iconsToImport = new Set<string>();
        for (const module of modules) {
            for (const tab of module.tabs) {
                iconsToImport.add(tab.iconName);
            }
        }
        const data = {
            modules,
            iconsToImport: Array.from(iconsToImport),
        };
        const tsxContent = template(data);
        fs.writeFileSync(OUTPUT_PATH, tsxContent);
        console.log("File successfully generated.");
    } catch (error) {
        console.error(error);
    }
};

const modulesFileGen = () => {
    console.log("Start file generation...");

    axios
        .get(ENDPOINT)
        .then((response: AxiosResponse<ModulesResponse>) => {
            generateRows(response.data.items);
        })
        .catch(err => console.log(err));
};

modulesFileGen();
