'use strict';

let access_token = "";


function create_redirect_uri() {
    const redirect_uri = new URL(window.location);
    redirect_uri.hash = "";
    redirect_uri.search = "";
    return redirect_uri;
}

function inflate_sign_in_url() {
    const redirect_uri = create_redirect_uri();
    const url = new URL(SIGN_IN_ENTRYPOINT);
    url.search = new URLSearchParams({
        client_id: CLIENT_ID,
        redirect_uri: redirect_uri.href,
        response_type: "token",
        scope: "nomeetings.klyushkin.org/meetings nomeetings.klyushkin.org/accounts"
    }).toString();
    return url;
}

function api_url(resource) {
    return new URL(API_ENTRYPOINT + resource)
}

function ensure_authenticated() {
    // Attempt extracting tokens from fragment
    const hash = new URLSearchParams(window.location.hash.substring(1));
    if (!access_token) {
        if (window.location.hash) {
            console.log("ensure_authenticated: fetching tokens from page URL's fragment");
            access_token = hash.get("access_token");
        } else
            console.log("ensure_authenticated: no page fragment")
    }
    if (!access_token) {
        const auth = inflate_sign_in_url();
        console.log(`ensure_authenticated: Authentication token is missing, redirecting for authentication to ${auth}`);
        window.location = auth
    } else {
        console.log("ensure_authenticated: Authentication token is present.");

        const code = hash.get("code"), provider = hash.get("provider_name");
        if (code && provider) {
            const url = api_url(`/external-accounts/${provider}`);
            fetch(url.href, {
                method: "POST",
                headers: {
                    "Authorization": `Bearer ${access_token}`,
                    "Content-Type": "application/x-www-form-urlencoded",
                },
                body: new URLSearchParams({
                    code: code,
                }),
            }).then(
                (rsp) => {
                    if (rsp.status === 201) {
                        const loc = rsp.headers.get("content-location");
                        console.log(`Successfully linked new Office365 account at ${loc}`);
                        accounts_list_fetch();
                    } else
                        show_error("ensure_authenticated", "Cannot link account: " + rsp.status);
                },
                (err) => {
                    show_error("ensure_authenticated", "Cannot link account: " + err.status);
                }
            )
        }

        window.location.hash = "";
        const link_office_btn = document.getElementById("link_office365");
        if (link_office_btn)
            link_office_btn.disabled = false;

    }
}

function show_error(where, message) {
    console.warn(`${where}: ${message}`);
    alert(message);
}

function link_office365_account() {
    const rq_url = api_url("/external-accounts/Office365/authorize");
    const params = new URLSearchParams({
        "redirect_uri": CLIENT_ENTRYPOINT,
        "state": new URLSearchParams({"access_token": access_token}).toString(),
    });
    fetch(rq_url.href, {
        method: "POST",
        headers: {
            "Authorization": `Bearer ${access_token}`,
            "Content-Type": "application/x-www-form-urlencoded"
        },
        body: params,
    }).then(
        (response) => {
            let dst = null;
            switch (response.status) {
                case 201:
                    dst = response.headers.get("content-location");
                    break;
                case 303:
                    dst = response.headers.get("location");
                    break;
                default:
                    show_error("link_office365_account", `Cannot add account: unexpected response ${response.status}`)
            }
            if (dst)
                window.location.href = dst;
            else
                show_error("link_office365_account", "Cannot add account: no location");
        },
        (error) => {
            show_error("link_office365_account", `Cannot add account: ${error}`);
        }
    );
}

function e(tagName, attrs, ...children) {
    let a = document.createElement(tagName);
    Object.entries(attrs).forEach(attr => {
        if (attr[0].startsWith("on"))
            a[attr[0]] = attr[1];
        else
            a.setAttribute(attr[0], attr[1])
    });
    for (const c of children)
        a.appendChild(c);
    return a;
}

function t(text) {
    return document.createTextNode(text);
}

