import { MODULE_ID, ORIGINAL_SYSTEM_CONFIG } from "../main.js";
import { setSetting, getSetting } from "../settings.js";

async function importJSONEditor() {
    if (!globalThis.JSONEditor) {
        await import(/* webpackIgnore: true */ "./esm/jsoneditor.js");
        //import style
        const style = document.createElement("link");
        style.rel = "stylesheet";
        style.href = "https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/10.0.1/jsoneditor.css";
        document.head.appendChild(style);
    }
}

export class JsonEditorApp extends FormApplication {
    constructor() {
        super();
    }

    static get APP_ID() {
        return this.name
            .split(/(?=[A-Z])/)
            .join("-")
            .toLowerCase();
    }

    get APP_ID() {
        return this.constructor.APP_ID;
    }

    static get defaultOptions() {
        return foundry.utils.mergeObject(super.defaultOptions, {
            id: this.APP_ID,
            template: `modules/${MODULE_ID}/templates/${this.APP_ID}.hbs`,
            popOut: true,
            resizable: true,
            minimizable: true,
            width: window.innerWidth * 0.6,
            height: window.innerHeight * 0.8,
            title: game.i18n.localize(`${MODULE_ID}.${this.APP_ID}.title`),
        });
    }

    async getData() {
        await importJSONEditor();
        const data = {};
        return { data };
    }

    activateListeners(html) {
        super.activateListeners(html);
        html = html[0] ?? html;
        const container = html.querySelector(".json-editor");
        const editor = new window.JSONEditor(container, {});
        this.JSONEditor = editor;
        const customizations = getSetting("customizationJson");
        const cloned = foundry.utils.mergeObject(foundry.utils.deepClone(ORIGINAL_SYSTEM_CONFIG), foundry.utils.deepClone(customizations));
        editor.set(cloned);
        html.querySelector("#reset").addEventListener("click", this._onReset.bind(this));
    }

    async _updateObject(event, formData) {
        const diff = this.getDiff();
        return await setSetting("customizationJson", diff);
    }

    getDiff() {
        const configData = this.JSONEditor.get();
        const diff = foundry.utils.diffObject(foundry.utils.deepClone(ORIGINAL_SYSTEM_CONFIG), configData);
        console.log("Logging diff", diff);
        deleteEmptyObjectKeysRecursive(diff);
        deleteEmptyObjectKeysRecursive(diff);
        deleteEmptyObjectKeysRecursive(diff);
        deleteEmptyObjectKeysRecursive(diff);
        deleteEmptyObjectKeysRecursive(diff);
        return diff;
    }

    async _onReset(event) {
        event.preventDefault();
        const confirmed = await Dialog.confirm({
            title: game.i18n.localize(`${MODULE_ID}.${this.APP_ID}.resetTitle`),
            content: game.i18n.localize(`${MODULE_ID}.${this.APP_ID}.resetContent`),
            yes: () => true,
            no: () => false,
            defaultYes: false,
        });
        if (!confirmed) return;
        await setSetting("customizationJson", {});
        this.close();
    }

    async close(...args) {
        super.close(...args);
        if (this.JSONEditor) {
            this.JSONEditor.destroy();
        }
    }

    async ExportToJson() {
        const diff = getSetting("customizationJson");
        saveDataToFile(JSON.stringify(diff, null, 2), "text/json", `customization.json`);
    }

    async importFromJson(event) {
        new Dialog(
            {
                title: `Import Data`,
                content: await renderTemplate("templates/apps/import-data.html", {
                    hint1: game.i18n.format("DOCUMENT.ImportDataHint1", { document: "customization" }),
                    hint2: game.i18n.format("DOCUMENT.ImportDataHint2", { name: "customization" }),
                }),
                buttons: {
                    import: {
                        icon: '<i class="fas fa-file-import"></i>',
                        label: "Import",
                        callback: (html) => {
                            const form = html.find("form")[0];
                            if (!form.data.files.length) return ui.notifications.error("You did not upload a data file!");
                            readTextFromFile(form.data.files[0]).then((json) => {
                                json = JSON.parse(json);
                                setSetting("customizationJson", json);
                                this.close();
                            });
                        },
                    },
                    no: {
                        icon: '<i class="fas fa-times"></i>',
                        label: "Cancel",
                    },
                },
                default: "import",
            },
            {
                width: 400,
            },
        ).render(true);
    }

    _getHeaderButtons() {
        let buttons = super._getHeaderButtons();
        buttons = [
            {
                label: "Export",
                class: "export",
                icon: "fas fa-file-export",
                onclick: this.ExportToJson.bind(this),
            },
            {
                label: "Import",
                class: "import",
                icon: "fas fa-file-import",
                onclick: this.importFromJson.bind(this),
            },
            ...buttons,
        ];
        return buttons;
    }
}

function deleteEmptyObjectKeysRecursive(obj) {
    for (const key in obj) {
        if(!obj[key]) continue;
        if (obj[key] && typeof obj[key] === "object" && Object.keys(obj[key]).length && !Array.isArray(obj[key])) {
            deleteEmptyObjectKeysRecursive(obj[key]);
        } else if (obj[key] && typeof obj[key] === "object" && Object.keys(obj[key]).length === 0 && !Array.isArray(obj[key])) {
            delete obj[key];
        }
    }
}
