const { connect } = require('preact-redux');
const preact = require('preact');
const { Fragment } = require('preact');
const actions = require('../actions');

const { saw } = require('./shapes');

const testGame = process.env.NODE_ENV === 'development' && require('./../test.game');
const testInstance = process.env.NODE_ENV === 'development' && require('./../test.instance');

function pingColour(ping) {
    if (ping < 100) return 'forestgreen';
    if (ping < 200) return 'yellow';
    return 'red';
}

const addState = connect(
    function receiveState(state) {
        const {
            ws,
            account,
            instances,
            team,
            ping,

            game,
        } = state;

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

        function sendAccountInstances() {
            return ws.sendAccountInstances();
        }

        function sendInstanceList() {
            return ws.sendInstanceList();
        }

        return {
            account,
            instances,
            team,
            game,
            ping,
            sendInstanceState,
            sendAccountInstances,
            sendInstanceList,
        };
    },
    function receiveDispatch(dispatch) {
        function setTestGame(id) {
            return dispatch(actions.setGame(testGame(id)));
        }

        function setTestInstance(id) {
            return dispatch(actions.setInstance(testInstance(id)));
        }

        function setNav(place) {
            dispatch(actions.setGame(null));
            dispatch(actions.setInstance(null));
            dispatch(actions.setCombiner([null, null, null]));
            dispatch(actions.setReclaiming(false));
            dispatch(actions.setActiveSkill(null));
            dispatch(actions.setActiveConstruct(null));
            dispatch(actions.setInfo(null));
            dispatch(actions.setItemEquip(null));
            dispatch(actions.setItemUnequip(null));
            dispatch(actions.setVboxHighlight([]));

            return dispatch(actions.setNav(place));
        }

        function hideNav() {
            return dispatch(actions.setShowNav(false));
        }

        return {
            setTestGame,
            setTestInstance,
            setNav,
            hideNav,
        };
    }
);

function Nav(args) {
    const {
        account,
        ping,
        team,
        instances,
        game,

        sendInstanceState,
        sendAccountInstances,
        sendInstanceList,

        setTestGame,
        setTestInstance,
        setNav,
        hideNav,
    } = args;

    function navTo(p) {
        if (p === 'list') {
            sendInstanceList();
            sendAccountInstances();
        }
        return setNav(p);
    }

    function joinInstance(i) {
        if (game) navTo(null);
        sendInstanceState(i);
        return true;
    }

    const joined = instances.map(i => (
        <button key={i.id} onClick={() => joinInstance(i)} >{i.name}</button>
    ));

    const haxSection = process.env.NODE_ENV === 'development'
        ? (
            <Fragment>
                <h2>Hax</h2>
                <button onClick={() => setTestGame(account.id)}>Test Game</button>
                <button onClick={() => setTestInstance(account.id)}>Test Instance</button>
            </Fragment>)
        : null;

    const canJoin = team.some(c => !c);

    const accountStatus = account
        ? (<div className="header-status">
            <h2 className="header-username">{account.name}</h2>
            {saw(pingColour(ping))}
            <div className="ping-text">{ping}ms</div>
        </div>)
        : false;

    return (
        <nav onClick={hideNav} >
            <h1 className="header-title">mnml.gg</h1>
            {accountStatus}
            <button onClick={() => navTo('team')}>1. Select Team</button>
            <button disabled={canJoin} onClick={() => navTo('list')}>2. Join</button>
            <hr />
            {joined}
            {haxSection}
        </nav>
    );
}

module.exports = addState(Nav);
