#include msgbox.jsx
#include utility.js
#include xhr.js
#include embed/embed.js
#include events/christmas2019.js
#include events/events.js
#include ext/sakuya.js
#include forum/editor.jsx
#include messages/messages.js

(async () => {
    const initLoginPage = async () => {
        const forms = Array.from($qa('.js-login-form'));
        if(forms.length < 1)
            return;

        const updateForm = async (avatar, userName) => {
            if(!(avatar instanceof Element) || !(userName instanceof Element))
                return;

            const { body } = await $x.get(`/auth/login.php?resolve=1&name=${encodeURIComponent(userName.value)}`, { type: 'json' });

            avatar.src = body.avatar;
            if(body.name.length > 0)
                userName.value = body.name;
        };

        for(const form of forms) {
            const avatar = form.querySelector('.js-login-avatar');
            const userName = form.querySelector('.js-login-username');
            let timeOut;

            await updateForm(avatar, userName);

            userName.addEventListener('input', function() {
                if(timeOut !== undefined)
                    return;

                timeOut = setTimeout(() => {
                    updateForm(avatar, userName)
                        .finally(() => {
                            clearTimeout(timeOut);
                            timeOut = undefined;
                        });
                }, 750);
            });
        }
    };

    const initQuickSubmit = () => {
        const elems = Array.from($qa('.js-quick-submit, .js-ctrl-enter-submit'));
        if(elems.length < 1)
            return;

        for(const elem of elems)
            elem.addEventListener('keydown', ev => {
                if((ev.code === 'Enter' || ev.code === 'NumpadEnter') && ev.ctrlKey && !ev.altKey && !ev.shiftKey && !ev.metaKey) {
                    // hack: prevent forum editor from screaming when using this keycombo
                    //       can probably be done in a less stupid manner
                    MszForumEditorAllowClose = true;

                    elem.form.submit();
                    ev.preventDefault();
                }
            });
    };

    const initXhrActions = () => {
        const targets = Array.from($qa('a[data-url], button[data-url]'));
        for(const target of targets) {
            target.onclick = async () => {
                if(target.disabled)
                    return;

                const url = target.dataset.url;
                if(typeof url !== 'string' || url.length < 1)
                    return;

                const disableWithTarget = typeof target.dataset.disableWithTarget === 'string'
                    ? (target.querySelector(target.dataset.disableWithTarget) ?? target)
                    : target;
                const originalText = disableWithTarget.textContent;

                try {
                    target.disabled = true;
                    if(target.dataset.disableWith)
                        disableWithTarget.textContent = target.dataset.disableWith;

                    if(target.dataset.confirm && !await MszShowConfirmBox(target.dataset.confirm, 'Are you sure?'))
                        return;

                    const { status, body } = await $x.send(
                        target.dataset.method ?? 'GET',
                        url,
                        {
                            type: 'json',
                            authed: target.dataset.withAuth,
                            csrf: target.dataset.withCsrf,
                        }
                    )

                    if(status >= 400)
                        await MszShowMessageBox(
                            body?.error?.text ?? `No additional information was provided. (HTTP ${status})`,
                            'Failed to complete action'
                        );
                    else if(status >= 200 && status <= 299) {
                        if(target.dataset.refreshOnSuccess)
                            location.reload();
                        else {
                            const redirectUrl = target.dataset.redirectOnSuccess;
                            if(typeof redirectUrl === 'string' && redirectUrl.startsWith('/') && !redirectUrl.startsWith('//'))
                                location.assign(redirectUrl);
                        }
                    }
                } catch(ex) {
                    console.error(ex);
                    await MszShowMessageBox(ex, 'Failed to complete action');
                } finally {
                    disableWithTarget.textContent = originalText;
                    target.disabled = false;
                }
            };
        }
    };

    try {
        MszSakuya.trackElements($qa('time'));
        hljs.highlightAll();

        MszEmbed.init(`${location.protocol}//uiharu.${location.host}`);

        initXhrActions();

        // only used by the forum posting form
        initQuickSubmit();
        const forumPostingForm = $q('.js-forum-posting');
        if(forumPostingForm !== null)
            MszForumEditor(forumPostingForm);

        const events = new MszSeasonalEvents;
        events.add(new MszChristmas2019EventInfo);
        events.dispatch();

        await initLoginPage();

        MszMessages();

        MszEmbed.handle($qa('.js-msz-embed-media'));
    } catch(ex) {
        console.error(ex);
    }
})();