import axios, { AxiosResponse } from "axios";

import * as fs from 'fs';

// region Types
type Module = {
    id: number;
    key: string;
    label: string;
    iconName?: string;
    isDeleted: boolean;
}

type ModulesResponse = {
    modules: Module[];
}
// endregion

const OUTPUT_FILE = "./src/modules/modules.tsx";

function camelToConstCase(camelStr: string): string {
    return camelStr
        .replace(/([a-z])([A-Z])/g, "$1_$2")
        .toUpperCase();
}

const writeToFile = (data: string) => {
    try {
        fs.writeFileSync(OUTPUT_FILE, data.trim());
        console.log("File successfully generated.");
    } catch (error) {
        console.error(error);
    }
};

const getImports = (modules: Module[]): string => {
    const prefix = "import { ";
    const postfix = " } from \"@tabler/icons-react\"\n" +
        "import ModulesType from \"./types.tsx\";\n" +
        "import connectModules from \"./connectModules.tsx\";";

    const filteredModules = modules.filter(module => module.iconName);
    const icons = filteredModules.map((module: Module) => module.iconName).join(", ");

    return prefix + icons + postfix;
};

const getModuleNames = (modules: Module[]) => {
    return modules.map(module => {
        return `${camelToConstCase(module.key)} = "${module.key}"`;
    }).join(",\n\t");
};

const getModules = (modules: Module[]) => {
    return modules.map(module => {
        let iconStr = "null";
        if (module.iconName) {
            iconStr = "<" + module.iconName + " />";
        }
        return `[ModuleNames.${camelToConstCase(module.key)}]: { info: { label: "${module.label}", key: "${module.key}", icon: ${iconStr} } }`;
    }).join(",\n\t");
};

const generateRows = (modules: Module[]) => {
    const imports = getImports(modules);

    const moduleNames = `\n\nexport enum ModuleNames {\n\t${getModuleNames(modules)}\n}\n`;
    const modulesStr = `\nconst modules: ModulesType = {\n\t${getModules(modules)}\n};\n`;
    const connectModules = "\nexport const MODULES = connectModules(modules);";
    const result: string = imports + moduleNames + modulesStr + connectModules;

    writeToFile(result);
};

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

    axios
        .get("http://127.0.0.1:8000/project/modules")
        .then((response: AxiosResponse<ModulesResponse>) => {
            generateRows(response.data.modules);
        })
        .catch(err => console.log(err));
};

modulesFileGen();
