import * as vscode from "vscode";
import { readFileSync, readdirSync, mkdirSync, writeFileSync } from "fs";
import * as path from "path";

let extensionTemplatePath = "";
let includeFeature = false; // ✅ boolean flag

// ================= INPUT STRUCTURE =================
interface InputField {
    title: string;
    placeholder: string;
    nextInput: string;
    value: string;
    input?: vscode.InputBox;
}

const InputData: Record<string, InputField> = {
    resourceCode: {
        title: "Resource Code",
        placeholder: "Used for the folder name: GOD, GSR, SELAPI, ...",
        nextInput: "resourceName",
        value: ""
    },
    resourceName: {
        title: "Resource name",
        placeholder: "B_Jobs, Phone, esx_garage, ...",
        nextInput: "description",
        value: ""
    },
    description: {
        title: "Resource description",
        placeholder: "This resource is ...",
        nextInput: "", 
        value: ""
    }
};

const startInput = "resourceCode";

// ================= ENTRY FUNCTION =================
export function registerResourceGenerator(context: vscode.ExtensionContext) {
    extensionTemplatePath = path.join(context.extensionPath, "template");

    const disposable = vscode.commands.registerCommand(
        "kj4lxc.fivem.generate-resource",
        (uri: vscode.Uri) => {
            loadInputs(uri?.fsPath);
        }
    );

    context.subscriptions.push(disposable);
}

// ================= INPUT FLOW =================
function loadInputs(resourcePath?: string) {
    for (const key in InputData) {
        const field = InputData[key];

        field.input = vscode.window.createInputBox();
        field.input.title = field.title;
        field.input.placeholder = field.placeholder;

        field.input.onDidAccept(() => {
            if (field.input!.value.trim().length > 0) {
                field.value = field.input!.value;
                field.input!.hide();

                if (field.nextInput) {
                    InputData[field.nextInput].input!.show();
                } else {
                    askIncludeFeature(resourcePath); // ✅ NEW STEP
                }
            } else {
                vscode.window.showErrorMessage(
                    `You need to complete this input (${field.title}).`
                );
            }
        });

        if (key === startInput) {
            field.input.show();
        }
    }
}

// ================= BOOLEAN PROMPT =================
async function askIncludeFeature(resourcePath?: string) {
    const result = await vscode.window.showQuickPick(
        ["Yes", "No"],
        {
            placeHolder: "Include UI Elements?"
        }
    );

    if (!result) {
        vscode.window.showWarningMessage("Operation cancelled.");
        return;
    }

    includeFeature = result === "Yes";

    startProcessing(resourcePath);
}

// ================= PROCESSING =================
function startProcessing(basePath?: string) {
    if (!basePath) {
        vscode.window.showErrorMessage("No folder selected.");
        return;
    }

    const folder = getGeneratedFolder("");

    const resourcePath = path.join(basePath, InputData.resourceCode.value);

    mkdirSync(resourcePath);
    writeFolder(resourcePath, folder);

    vscode.window.showInformationMessage(
        `You just created a new FiveM Lua Resource named '${InputData.resourceName.value}'.`
    );
}

// ================= FOLDER STRUCT =================
interface FolderType {
    url: string;
    files: Record<string, string>;
    folders: Record<string, FolderType>;
}

function Folder(url: string): FolderType {
    return {
        url,
        files: {},
        folders: {}
    };
}

// ================= TEMPLATE PARSER =================
function getGeneratedFolder(url: string): FolderType {
    const folder = Folder(url);

    // ✅ SWITCH TEMPLATE BASED ON BOOLEAN
    const baseTemplatePath = includeFeature
        ? path.join(extensionTemplatePath, "withFeature")
        : path.join(extensionTemplatePath, "base");

    const files = readdirSync(path.join(baseTemplatePath, url), {
        withFileTypes: true
    });

    for (const file of files) {
        if (file.isDirectory()) {
            folder.folders[file.name] = getGeneratedFolder(
                path.join(url, file.name)
            );
        } else {
            let content = readFileSync(
                path.join(baseTemplatePath, url, file.name),
                "utf-8"
            );

            for (const key in InputData) {
                content = content.replace(
                    new RegExp(`\\$\\{${key}\\}`, "g"),
                    InputData[key].value
                );
            }

            folder.files[file.name] = content;
        }
    }

    return folder;
}

// ================= FILE WRITER =================
function writeFolder(url: string, folder: FolderType) {
    for (const key in folder.files) {
        writeFileSync(path.join(url, key), folder.files[key], "utf-8");
    }

    for (const key in folder.folders) {
        const subFolderPath = path.join(url, key);
        mkdirSync(subFolderPath);

        writeFolder(subFolderPath, folder.folders[key]);
    }
}