#include comments/api.js

const MszCommentsFormNotice = function(args) {
    const { body } = args ?? {};
    const element = <div class="comments-notice">
        <div class="comments-notice-inner">{body}</div>
    </div>;

    return {
        get element() { return element; },
    };
};

const MszCommentsForm = function(args) {
    const {
        userInfo, catInfo, postInfo,
        listing, repliesToggle, replyToggle,
    } = args ?? {};

    const defaultStatus = () => <>Press <kbd>enter</kbd> to submit, use <kbd>shift</kbd>+<kbd>enter</kbd> to start a new line.</>;
    const status = <div class="comments-form-status-text">{defaultStatus}</div>;

    const element = <form class={{ 'comments-form': true, 'comments-form-root': !postInfo }} style={`--user-colour: ${userInfo.colour}`}>
        <input type="hidden" name="category" value={catInfo.name} />
        {postInfo ? <input type="hidden" name="reply_to" value={postInfo.id} /> : null}
        <div class="comments-form-avatar">
            <img src={userInfo.avatar} alt="" width="40" height="40" class="avatar" />
        </div>
        <div class="comments-form-wrap">
            <div class="comments-form-input">
                <textarea class="input__textarea" name="body" placeholder="Share your extensive insights..." onkeydown={ev => {
                    if(status.classList.contains('comments-form-status-error')) {
                        status.classList.remove('comments-form-status-error');
                        $removeChildren(status);
                        $appendChild(status, defaultStatus);
                    }

                    if(ev.key === 'Enter' && !ev.shiftKey) {
                        ev.preventDefault();
                        element.requestSubmit();
                    }

                    if(ev.key === 'p' && ev.altKey) {
                        ev.preventDefault();
                        if(element.elements.pin)
                            element.elements.pin.checked = !element.elements.pin.checked;
                    }
                }} />
            </div>
            <div class="comments-form-actions">
                <div class="comments-form-status">{status}</div>
                {userInfo.can_pin && !postInfo ? <div class="comments-form-pin"><label><input type="checkbox" name="pin" /> Pin</label></div> : null}
                <div class="comments-form-post"><button class="input__button">Post</button></div>
            </div>
        </div>
    </form>;

    const forAllFields = closure => {
        for(let i = 0; i < element.elements.length; ++i)
            closure(element.elements[i]);
    };

    const setDisabled = state => {
        element.classList.toggle('comments-form-disabled', state);
        forAllFields(field => field.disabled = state);
    };

    element.onsubmit = async ev => {
        ev.preventDefault();

        if(element.classList.contains('comments-form-disabled'))
            return;

        setDisabled(true);

        try {
            const fields = {};
            forAllFields(field => {
                if(!field.name)
                    return;

                if(field.type === 'checkbox') {
                    if(field.checked)
                        fields[field.name] = field.value;
                } else
                    fields[field.name] = field.value;
            });

            listing.addPost(catInfo, userInfo, await MszCommentsApi.createPost(fields));
            listing.reorder();
            listing.visible = true;

            if(repliesToggle) {
                repliesToggle.open = true;
                ++repliesToggle.count;
            }

            if(replyToggle?.active)
                replyToggle.click();

            element.elements.body.value = '';
            if(element.elements.pin)
                element.elements.pin.checked = false;
        } catch(ex) {
            status.classList.add('comments-form-status-error');
            status.textContent = ex;
        } finally {
            setDisabled(false);
        }
    };

    return {
        get element() { return element; },

        focus() {
            element.elements.body.focus();
        },
    };
};
