"use strict";

let main, windows;
let defaultLocation = '/welcome';

let token = "";
let domain = "";
let dest = "";

function createWelcomeWindow() {
    let win = document.createElement("div");
    win.id = "welcome-win";

    win.innerHTML = `
        <h1>Welcome to Locutus!</h1>
        <a href="#/login" class="button">Login</a>`;

    while (windows.lastChild) windows.removeChild(windows.lastChild);
    windows.appendChild(win);
}

function createChatWindow() {
    let win = document.createElement("div");
    win.id = "chat-win";

    console.log("Creating chat window");

    win.innerHTML = `
        <div id="message-win">
            <p>Test Message</p>
        </div>
        <form id="message-form">
            <input id="message-input" name="message" placeholder="Very important message..." type="text" required>
        </form>
    `;


    let messageForm = win.getElementsByTagName("form")[0];
    messageForm.addEventListener("submit", (evt) => {
        evt.preventDefault();
        let messageInput = messageForm.elements['message-input'];

        let message = JSON.stringify({
            room_id: "60nc0XXDIYUh6QzX4p0rMpCdzDmxghZLZk8dLuQh628",
            data: {
                message: messageInput.value
            }
        })
        sendEvent(message).then((evt => {
            console.log(evt)
        }));
        let messageAdd = document.createElement("p");
        messageAdd.innerHTML = `You: <strong> ${messageInput.value} </strong>`;
        win.getElementsByTagName("div")[0].appendChild(messageAdd);
        messageInput.value = "";

    });

    while (windows.lastChild) windows.removeChild(windows.lastChild);
    windows.style.visibility = "hidden";
    subscribeEvent();
    main.appendChild(win);
}

async function sendEvent(message) {
    return fetch(`${dest}/_usimp/send_event`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `usimp ${token}`,
            'From-Domain': domain,
            'To-Domain': domain,
        },
        body: message
    });
}

async function subscribeEvent() {
    let response = await fetch(`${dest}/_usimp/subscribe`, {
        method: 'POST',
        headers: {
            'To-Domain': domain,
            'From-Domain': domain
        },
        body: JSON.stringify({})
    });

    if (response.status !== 200) {
        showMessage(response.statusText);
        await new Promise(resolve => setTimeout(resolve, 1000));
        await subscribeEvent();
    } else {
        let message = await response.text();
        addMessage(JSON.parse(message).event.data.message);
        await subscribeEvent();
    }
}

function addMessage(message) {
    let messageContainer = document.getElementById("message-win");
    let messageP = document.createElement("p");
    messageP.innerHTML = `Not You: <strong> ${message} </strong>`;
    messageContainer.appendChild(messageP);
}

function createLoginWindow() {
    let win = document.createElement("div");
    win.id = "login-win";

    win.innerHTML = `
        <h1>Login to USIMP Account</h1>
        <form>
            <input name="account" placeholder="Account name" type="text" required/>
            <input name="domain" placeholder="Domain" type="text" pattern="([a-zA-Z0-9_-]+\\.)+[a-zA-Z]{2,}" required/>
            <input name="password" placeholder="Password" type="password" required/>
            <button type="submit">Login</button>
        </form>`;

    win.getElementsByTagName("form")[0].addEventListener("submit", (evt) => {
        evt.preventDefault();
        let form = evt.target;
        for (let e of form) e.disabled = true;

        for (let d of form.getElementsByTagName("div")) {
            form.removeChild(d);
        }

        function formError(msg) {
            let div = document.createElement("div");
            div.classList.add("error");
            div.innerText = msg;
            form.appendChild(div);
        }

        usimp.lookup(form.domain.value)
            .then(res => {
                if (res.ok) {
                    res.json()
                        .then(data => {
                            console.log(data["domain"]);
                            let domainServer = usimp.chooseDomainServer(data["domain_servers"]);
                            console.log(domainServer);
                            dest = `http://${domainServer.host}:${domainServer.protocols.http}`;
                            domain = form.elements["domain"].value

                            usimp.login(domainServer, data["domain"].id, form.elements["account"].value, form.elements["password"].value)
                                .then(res => res.json())
                                .catch((evt) => {
                                    console.log("Serva ded");
                                    console.log(evt);
                                })
                                .then(data => {
                                    token = data.token;
                                    console.log(data.token);
                                    createChatWindow();
                                });
                        })
                        .catch(reason => {
                            console.error(reason);
                            formError("Could not communicate with USIMP domain");
                        })
                } else {
                    document.getElementsByName("domain")[0].setAttribute("invalid", "invalid");
                    formError("Invalid USIMP domain");
                }
            })
            .catch(reason => {
                document.getElementsByName("domain")[0].setAttribute("invalid", "invalid");
                formError("Invalid USIMP domain");
            })
            .finally(() => {
                for (let e of form) e.disabled = false;
            });
    });

    while (windows.lastChild) windows.removeChild(windows.lastChild);
    windows.appendChild(win);

    document.getElementsByName("domain")[0].addEventListener("input", (evt) => {
        evt.target.removeAttribute("invalid");
    });

    document.getElementsByName("account")[0].focus();
}

function handleHash(hash) {
    if (hash[0] === '#') hash = hash.substr(1);

    switch (hash) {
        case "/welcome": createWelcomeWindow(); break;
        case "/login": createLoginWindow(); break;
        default:
            console.warn(`Invalid url hash #${hash}`);
            history.replaceState(null, null, `#${defaultLocation}`);
            handleHash(defaultLocation)
            return;
    }

    let url = new URL(document.URL);
    url.hash = hash;
    location.href = url.toString();
}

function handleUrl(url) {
    handleHash(new URL(url).hash);
}

window.addEventListener("DOMContentLoaded", (evt) => {
    main = document.getElementsByTagName("main")[0];
    windows = document.getElementById("windows");

    // Remove <noscript> tag
    document.getElementsByTagName("noscript")[0].remove();

    handleUrl(document.URL)
});

window.addEventListener("hashchange", (evt) => {
    handleUrl(evt.newURL);
});