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

const shapes = require('./shapes');
const { SPECS, STATS, crypAvatar } = require('../utils');
const actions = require('../actions');

const addState = connect(
    function receiveState(state) {
        const { ws, instance, player, account, vboxHidden, vboxInfo, activeVar } = state;

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

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

        return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, vboxInfo, activeVar };
    },

    function receiveDispatch(dispatch) {
        function quit() {
            dispatch(actions.setInstance(null));
        }

        function setInfo(item, value) {
            dispatch(actions.setInfo([item, value]));
        }

        function setActiveCryp(value) {
            dispatch(actions.setActiveCryp(value));
        }

        function clearInfo() {
            return dispatch(actions.setInfo([]));
        }

        function setVboxHighlight(v) {
            dispatch(actions.setVboxHighlight(v));
        }

        return { quit, clearInfo, setInfo, setActiveCryp, setVboxHighlight };
    }

);

function Cryp(props) {
    const {
        activeVar,
        cryp,
        player,
        sendVboxApply,
        setInfo,
        setActiveCryp,
        setVboxHighlight,
        vboxInfo,
    } = props;

    function setHighlight(type) {
        if (type === 'skill') return setVboxHighlight(vboxInfo.vars.filter(v => v.skill).map(v => v.v));
        if (type === 'spec') return setVboxHighlight(vboxInfo.vars.filter(v => v.spec).map(v => v.v));
        return false;
    }

    function onClick(e) {
        e.stopPropagation();
        e.preventDefault();
        if (activeVar !== null) return sendVboxApply(cryp.id, activeVar);
        return setActiveCryp(cryp);
    }

    const { vbox } = player;
    const skillList = vboxInfo.vars.filter(v => v.skill).map(v => v.v);
    const specList = vboxInfo.vars.filter(v => v.spec).map(v => v.v);

    const skills = range(0, 3).map(i => {
        const skill = cryp.skills[i];
        const s = skill
            ? skill.skill
            : (<span className="gray">+</span>);

        function skillClick(e) {
            if (!skill && activeVar !== null) return sendVboxApply(cryp.id, activeVar);
            if (!skill) setHighlight('skill');
            else setInfo('skill', { skill: skill.skill, cryp });
            e.stopPropagation();
            return setActiveCryp(cryp);
        }

        const action = skill ? '' : 'action';
        const equip = skillList.includes(vbox.bound[activeVar]) && !skill ? 'equip' : '';
        const classes = `right ${action} ${equip}`;
        return (
            <button key={i} className={classes} onClick={skillClick} >{s}</button>
        );
    });

    const specs = range(0, 6).map(i => {
        const s = cryp.specs[i];

        function blankSpecClick(e) {
            e.stopPropagation();
            if (activeVar !== null) return sendVboxApply(cryp.id, activeVar);
            setHighlight('spec');
            return setActiveCryp(cryp);
        }

        if (!s) {
            const equip = specList.includes(vbox.bound[activeVar]) ? 'equip-spec' : 'gray';
            return (
                <figure key={i} onClick={blankSpecClick} className={equip} >
                    {shapes.diamond(`stat-icon ${equip}`)}
                    <figcaption>+</figcaption>
                </figure>
            );
        }

        function specClick(e) {
            e.stopPropagation();
            setActiveCryp(cryp);
            setInfo('spec', { spec: s, cryp });
        }

        return (
            <figure key={i} onClick={specClick}>
                {SPECS[s].svg(`stat-icon ${SPECS[s].colour}`)}
                <figcaption>{SPECS[s].caption}</figcaption>
            </figure>
        );
    });

    const stats = Object.values(STATS).map(s => (
        <figure key={s.stat} alt={s.stat} className={s.stat}>
            {s.svg(`stat-icon ${s.colour} stat`)}
            <figcaption>{cryp[s.stat].value}</figcaption>
        </figure>
    ));

    // const cTotal = cryp.colours.red + cryp.colours.blue + cryp.colours.green;
    // const colours = mapValues(cryp.colours, c => {
    //     if (cTotal === 0) return 245;
    //     return Math.floor(c / cTotal * 255);
    // });
    // const alpha = cTotal === 0 ? 1 : 0.75;
    // const thickness = total => {
    //     if (total < 3) return 1;
    //     if (total < 6) return 2;
    //     if (total < 9) return 3;
    //     return 4;
    // };
    // const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` };
    return (
        <div key={cryp.id} className="instance-cryp" onClick={onClick} >
            {crypAvatar(cryp.name)}
            <h2 className="name" >{cryp.name}</h2>
            <div className="skills">
                {skills}
            </div>
            <div className="specs">
                {specs}
            </div>
            <div className="stats">
                <div className="damage-label label">
                    Damage
                </div>
                <div className="speed-label label">
                    Speed
                </div>
                <div className="life-label label">
                    Life
                </div>
                <div className="icons">
                    {stats}
                </div>
            </div>
        </div>
    );
}

function InstanceCryps(props) {
    const {
        activeVar,
        player,
        instance,
        // clearInfo,
        setInfo,
        setActiveCryp,

        sendVboxApply,
        vboxHidden,
        vboxInfo,
        setVboxHighlight,
    } = props;

    if (!player) return false;
    if (instance.phase === 'Lobby') return false;

    const cryps = player.cryps.map((c, i) => Cryp({
        activeVar, cryp: c, player, sendVboxApply, setInfo, setActiveCryp, vboxInfo, setVboxHighlight,
    }));

    const classes = `cryp-list ${vboxHidden ? '' : 'hidden'}`;
    return (
        <div className={classes} onClick={() => setActiveCryp(null)}>
            {cryps}
        </div>
    );
}

module.exports = addState(InstanceCryps);
