import { toHref } from "../lib/skeleton/router.js";
import { loadJS } from "../helpers/loader.js";
import { init as setup_translation } from "../locales/index.js";
import { init as setup_config } from "../model/config.js";
import { init as setup_plugin } from "../model/plugin.js";
import { init as setup_cache } from "../pages/filespage/cache.js";
import { report } from "../helpers/log.js";
import { $error } from "./common.js";

export default async function main() {
    try {
        await Promise.all([
            setup_config().then((config) => Promise.all([
                setup_title(config),
                window.self === window.top ? verify_origin(config) : verify_iframe_origin(config),
            ])),
            setup_translation(),
            setup_xdg_open(),
            setup_device(),
            setup_blue_death_screen(),
            setup_history(),
            setup_polyfill(),
            setup_plugin(),
            setup_cache(),
        ]);
        window.dispatchEvent(new window.Event("pagechange"));
    } catch (err) {
        console.error(err);
        const msg = window.navigator.onLine === false ? "OFFLINE" : (err instanceof Error && err.message) || "CAN'T LOAD";
        report(msg, err, location.href);
        $error(msg);
    }
}
await main();

/// /////////////////////////////////////////
async function setup_xdg_open() {
    window.overrides = {};
    return loadJS(import.meta.url, toHref("/overrides/xdg-open.js"));
}

async function setup_device() {
    const className = "ontouchstart" in window ? "touch-yes" : "touch-no";
    document.body.classList.add(className);
    if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
        document.body.classList.add("dark-mode");
    }
    window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function(e) {
        e.matches ? document.body.classList.add("dark-mode") : document.body.classList.remove("dark-mode");
    });
}

async function setup_blue_death_screen() {
    window.onerror = function(msg, url, lineNo, colNo, error) {
        report(msg, error, url, lineNo, colNo);
        $error(msg);
        if ("serviceWorker" in navigator) navigator.serviceWorker
            .getRegistrations()
            .then((registrations) => {
                for (const registration of registrations) {
                    registration.unregister();
                }
            });
    };
}

async function setup_history() {
    window.history.replaceState({}, "");
}

async function setup_title(config) {
    document.title = config["name"] || "Filestash";
}

async function setup_polyfill() {
    if (!("replaceChildren" in document.body)) {
        await loadJS(import.meta.url, "../lib/polyfill.js");
    }
}

async function verify_origin(config) {
    const origin = config["origin"];
    // happy path
    if (!origin) return;
    else if (location.origin === origin) return;
    // non happy path
    const u = new URL(origin);
    if (u.host === location.host) return;
    else if (u.hostname === location.hostname) return;
    setTimeout(() => {
        location.href = origin + location.pathname + location.search;
    }, 1000);
    throw new Error("Redirecting to " + origin);
}

async function verify_iframe_origin(_) {
    // TODO: const origin = document.location.ancestorOrigins[0]
    // should we verify iframe origin client side on top of frame ancestor? Until prooven wrong, no.
}
