#include watcher.js

const MszMessagesActionButton = function(button, stateless) {
    if(!(button instanceof Element))
        throw 'button must be an element';

    const stateful = !stateless;
    const pub = {};

    const icon = button.querySelector('.js-messages-button-icon i');
    const label = button.querySelector('.js-messages-button-label');

    const update = () => {
        if(stateful) {
            icon.className = button.dataset[`${button.dataset.state}Ico`];
            label.textContent = button.dataset[`${button.dataset.state}Str`];
        }
    };
    pub.update = update;

    const stateWatcher = new MszWatcher;
    const getState = () => button.dataset.state !== 'inactive';
    const setState = state => {
        button.dataset.state = state ? 'active' : 'inactive';
        update();
        stateWatcher.call(getState());
    };

    if(stateful) {
        pub.getState = getState;
        pub.setState = setState;
        pub.watchState = handler => { stateWatcher.watch(handler, getState()); };
        pub.unwatchState = handler => { stateWatcher.unwatch(handler); };
    }

    let clickAction;
    const click = async () => {
        if(clickAction !== undefined) {
            if(stateful) {
                const result = await clickAction(getState());
                if(typeof result === 'boolean')
                    setState(result);
            } else
                await clickAction();
        }
    };
    pub.click = click;

    button.addEventListener('click', () => click());

    update();

    pub.setAction = action => {
        if(typeof action !== 'function')
            throw 'action must be a function';
        clickAction = action;
    };

    let preventEnable = false;

    pub.getEnabled = () => !button.disabled;
    pub.setEnabled = state => {
        if(!preventEnable)
            button.disabled = !state;
    };
    pub.disableWith = async callback => {
        if(typeof callback !== 'function')
            throw 'callback must be a function';
        if(preventEnable)
            throw 'preventEnable is true';

        preventEnable = true;
        const wasDisabled = button.disabled;
        button.disabled = true;

        try {
            return await callback();
        } finally {
            button.disabled = wasDisabled;
            preventEnable = false;
        }
    };

    pub.setHidden = state => {
        button.hidden = state;
    };

    return pub;
};
