const preact = require('preact');
const { connect } = require('preact-redux');

const actions = require('../actions');

const InfoContainer = require('./vbox.info');
const StashElement = require('./vbox.stash');
const StoreElement = require('./vbox.store');
const Combiner = require('./vbox.combiner');
const Combos = require('./vbox.combos');

const { setVboxState } = require('./vbox.utils');

const addState = connect(
    function receiveState(state) {
        const {
            ws,
            itemUnequip,
            instance,
            player,
            tutorial,
            vboxSelected,
            itemInfo,
        } = state;

        function sendInstance() {
            return ws.sendInstanceState(instance.id);
        }

        function sendVboxRefill() {
            return ws.sendVboxRefill(instance.id);
        }

        function sendVboxBuy(group, index) {
            if (!(vboxSelected.storeSelect.length === 1 && vboxSelected.stashSelect.length === 0)) return false;
            document.activeElement.blur();
            return ws.sendVboxBuy(instance.id, group, index);
        }

        function sendVboxCombine() {
            return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect);
        }

        function sendVboxRefund(i) {
            return ws.sendVboxRefund(instance.id, i);
        }

        function sendItemUnequip([constructId, item]) {
            return ws.sendVboxUnequip(instance.id, constructId, item);
        }

        return {
            itemUnequip,
            instance,
            player,
            tutorial,
            vboxSelected,

            itemInfo,

            sendInstance,
            sendItemUnequip,
            sendVboxBuy,
            sendVboxCombine,
            sendVboxRefill,
            sendVboxRefund,
        };
    },

    function receiveDispatch(dispatch) {
        function setInfo(item) {
            return dispatch(actions.setInfo(item));
        }

        function setTutorial(stage) {
            return dispatch(actions.setTutorial(stage));
        }

        function dispatchVboxSelect(v, state) {
            setVboxState(dispatch, v, state);
            dispatch(actions.setItemUnequip([]));
            return dispatch(actions.setVboxSelected(v));
        }

        return {
            dispatchVboxSelect,
            setInfo,
            setTutorial,
        };
    }
);

class Vbox extends preact.Component {
    shouldComponentUpdate(newProps) {
        if (newProps.itemUnequip !== this.props.itemUnequip) return true;
        if (newProps.instance !== this.props.instance) return true;
        if (newProps.player !== this.props.player) return true;
        if (newProps.tutorial !== this.props.tutorial) return true;
        if (newProps.vboxSelected !== this.props.vboxSelected) return true;
        return false;
    }

    render(args) {
        const {
            // Changing state variables
            itemUnequip,
            instance,
            player,
            tutorial,
            vboxSelected,
            // Static
            itemInfo,
            // Function Calls
            dispatchVboxSelect,
            sendItemUnequip,
            sendInstance,
            sendVboxBuy,
            sendVboxCombine,
            sendVboxRefill,
            sendVboxRefund,
            setInfo,
            setTutorial,
        } = args;

        if (!player) return false;
        const { vbox } = player;
        const { storeSelect, stashSelect } = vboxSelected;

        const setVboxSelected = v => dispatchVboxSelect(v, { itemInfo, itemUnequip, vbox });
        const clearVboxSelected = () => setVboxSelected({ storeSelect: [], stashSelect: [] });
        const vboxBuySelected = () => sendVboxBuy(storeSelect[0][0], storeSelect[0][1]);
        const clearTutorial = () => {
            setTutorial(null);
            sendInstance();
        };
        function vboxHover(e, v) {
            if (v) {
                e.stopPropagation();
                if (stashSelect.length !== 0 || storeSelect.length !== 0) return true;
                setInfo(v);
            }
            return true;
        }

        function storeHdr() {
            return (
                <div class="store-hdr">
                    <h2
                        onTouchStart={e => e.target.scrollIntoView(true)}
                        onMouseOver={e => vboxHover(e, 'store')}> STORE
                    </h2>
                    <h1 class={`bits ${vbox.bits < 3 ? 'red' : false}`} onMouseOver={e => vboxHover(e, 'bits')}>
                        {vbox.bits}b
                    </h1>
                    <button
                        class='vbox-btn'
                        onMouseOver={e => vboxHover(e, 'refill')}
                        disabled={vbox.bits < 2
                            || (tutorial && tutorial < 7
                            && instance.time_control === 'Practice' && instance.rounds.length === 1)
                        }
                        onClick={e => e.stopPropagation()}
                        onMouseDown={() => sendVboxRefill()}>
                        refill <br />
                        2b
                    </button>
                </div>
            );
        }

        function stashHdr() {
            const refund = storeSelect.length === 0 && stashSelect.length === 1
                ? itemInfo.items.find(i => i.item === vbox.stash[stashSelect[0]]).cost
                : 0;
            const tutorialDisabled = tutorial && tutorial < 8
                && instance.time_control === 'Practice' && instance.rounds.length === 1;
            const refundBtn = (
                <button
                    disabled={tutorialDisabled || !refund}
                    class='vbox-btn'
                    onClick={e => e.stopPropagation()}
                    onMouseDown={e => {
                        e.stopPropagation();
                        sendVboxRefund(vboxSelected.stashSelect[0]);
                    }}>
                    refund <br />
                    {refund}b
                </button>
            );

            return (
                <div class='stash-hdr'>
                    <h2 onTouchStart={e => e.target.scrollIntoView(true)}
                        onMouseOver={e => vboxHover(e, 'stash')}> STASH
                    </h2>
                    {refundBtn}
                </div>
            );
        }

        // EVERYTHING
        return (
            <div class='vbox'>
                {storeHdr()}
                {stashHdr()}
                <StoreElement
                    clearVboxSelected={clearVboxSelected}
                    setVboxSelected={setVboxSelected}
                    vbox={vbox}
                    vboxSelected={vboxSelected}
                    vboxHover = {vboxHover}
                />
                <StashElement
                    sendItemUnequip={sendItemUnequip}
                    setInfo={setInfo}
                    setVboxSelected={setVboxSelected}
                    vbox={vbox}
                    vboxBuySelected={vboxBuySelected}
                    vboxHover={vboxHover}
                />
                <div class='info-combiner'>
                    <InfoContainer
                        clearTutorial={clearTutorial}
                    />
                    <Combiner
                        vbox={vbox}
                        vboxSelected={vboxSelected}
                        vboxBuySelected={vboxBuySelected}
                        sendVboxCombine={sendVboxCombine}
                    />
                </div>
                <Combos />
            </div>
        );
    }
}

module.exports = addState(Vbox);
