//@ts-check

let jadefinInit = /** @type {HTMLScriptElement} */ (document.currentScript);

function jadefinInitExtremelyEarly() {
    // Required for mods to be able to replace some things.
    // Might or might not horribly wreck everything.
    const defineProperty = this._Object_defineProperty = Object.defineProperty.bind(Object);
    const defineProperties = this._Object_defineProperties = Object.defineProperties.bind(Object);

    Object.defineProperty = (obj, prop, descriptor) => {
        if (descriptor && prop != "prototype") {
            descriptor.configurable = true;
        }

        return defineProperty(obj, prop, descriptor);
    };

    Object.defineProperties = (obj, props) => {
        if (props) {
            for (const prop of Object.keys(props)) {
                const descriptor = props[prop];

                if (descriptor && prop != "prototype") {
                    descriptor.configurable = true;
                }
            }
        }

        return defineProperties(obj, props);
    };
}

jadefinInitExtremelyEarly();

(() => {
    let loadedJellyfin = false;
    let initedJadefin = false;

    function loadJadefin() {
        return new Promise((resolve, reject) => {
            console.log("[jadefin-init] loadJadefin");

            const loader = document.createElement("script");
            document.head.appendChild(loader);

            window["_JadefinLoaded"] = () => resolve(true);
            window["_JadefinErrored"] = (e) => reject(e);

            const modUrl = jadefinInit.src;
            console.log("[jadefin-init] loadJadefin src", modUrl);

            const rootAuto = modUrl.substring(0, modUrl.lastIndexOf("/"));
            console.log("[jadefin-init] loadJadefin root auto", rootAuto);

            // Set to https://jellyfin.0x0a.de/jadefin/dev to use the dev branch.
            const rootManual = localStorage.getItem("jadefin-root");
            if (rootManual) {
                console.log("[jadefin-init] loadJadefin root manual", rootManual);
            }

            window["_JadefinRoot"] = rootManual || rootAuto;

            loader.type = "module";
            loader.innerHTML = `
                try {
                    import(window["_JadefinRoot"] + "/Jadefin.js");
                } catch (e) {
                    console.error(e);
                    window["_JadefinErrored"]();
                }

                delete window["_JadefinErrored"];
                delete window["_JadefinRoot"];
            `;
        });
    }

    function loadJellyfin() {
        return new Promise((resolve, reject) => {
            console.log("[jadefin-init] loadJellyfin");

            if (loadedJellyfin) {
                resolve(false);
                return;
            }

            loadedJellyfin = true;

            const self = document.querySelector("[data-main-jellyfin-bundle]");
            if (!self) {
                console.error("[jadefin-init] loadJellyfin couldn't find data-main-jellyfin-bundle")
                resolve(false);
                return;
            }

            const loader = document.createElement("script");
            document.head.appendChild(loader);

            loader.addEventListener("load", () => resolve(true));
            loader.addEventListener("error", (e) => reject(e));

            loader.defer = true;
            loader.src = self.getAttribute("data-main-jellyfin-bundle") || "main.jellyfin.bundle.js";
        });
    }

    function initJadefin() {
        return new Promise((resolve, reject) => {
            console.log("[jadefin-init] initJadefin");

            const cb = () => {
                if (initedJadefin) {
                    return;
                }

                initedJadefin = true;

                try {
                    window["Jadefin"].init();
                    resolve(true);
                } catch (e) {
                    console.error(e);
                    reject(e);
                }
            };

            window.addEventListener("load", cb);
            if (document.readyState == "complete") {
                cb();
            }
        })
    }

    loadJadefin().then(loadJellyfin).then(initJadefin).finally(loadJellyfin);
})();