#include msgbox.jsx
#include comments/api.js
#include comments/form.jsx
#include comments/listing.jsx
#include comments/options.jsx

const MszCommentsSection = function(args) {
    let { category: catName } = args ?? {};

    const options = new MszCommentsOptions;
    const listing = new MszCommentsListing({ root: true });
    const element = <div class="comments">
        {options}
        {listing}
    </div>;

    let form;
    let retryAct;

    const clearForm = () => {
        if(form) {
            element.removeChild(form.element);
            form = undefined;
        }
    };
    const setForm = elem => {
        clearForm();
        form = elem;
        $insertBefore(element.firstChild, form.element);
    };
    const initForm = (userInfo, catInfo) => {
        if(!userInfo)
            setForm(new MszCommentsFormNotice({ body: 'You must be logged in to post comments.' }));
        else if(!userInfo.can_create)
            setForm(new MszCommentsFormNotice({ body: 'You are not allowed to comment.' }));
        else if(catInfo.locked)
            setForm(new MszCommentsFormNotice({ body: 'This comment section is closed.' }));
        else
            setForm(new MszCommentsForm({ userInfo, catInfo, listing }));
    };

    const pub = {
        get element() { return element; },

        async reload() {
            clearForm();
            listing.reset();

            try {
                const { user, category, posts } = await MszCommentsApi.getCategory(catName);

                retryAct = undefined;
                options.reset();

                initForm(user, category);

                if(user?.can_lock)
                    options.appendAction(new MszCommentsOptionsLockAction(
                        category,
                        () => {
                            initForm(user, category);
                            listing.updateLocked();
                        }
                    ));

                listing.addPosts(category, user, posts);
            } catch(ex) {
                console.error(ex);
                listing.removeLoading();

                form = new MszCommentsFormNotice({ body: 'Failed to load comments.' });
                $insertBefore(element.firstChild, form.element);

                if(!retryAct)
                    options.appendAction(retryAct = new MszCommentsOptionsRetryAction(pub));
            }
        },
    };

    pub.reload();

    return pub;
};
