const preact = require('preact');
const countBy = require('lodash/countBy');
const forEach = require('lodash/forEach');
const reactStringReplace = require('react-string-replace');

const actions = require('../actions');
const specThresholds = require('./vbox.info.thresholds');
const { INFO } = require('./../constants');
const { removeTier } = require('../utils');
const shapes = require('./shapes');

function setVboxState(dispatch, vboxSelected, state) {
    const {
        itemInfo,
        itemUnequip,
        vbox,
    } = state;
    const { storeSelect, stashSelect } = vboxSelected;

    // default returns
    let vboxCombiner = false;
    let vboxHighlight = false;

    if (storeSelect.length || stashSelect.length) {
        vboxHighlight = [];
        const stashItems = stashSelect.map(j => vbox.stash[j]);
        const shopItems = storeSelect.map(j => vbox.store[j[0]][j[1]]);

        const selectedItems = stashItems.concat(shopItems);
        const itemCount = countBy(selectedItems, co => co);

        itemInfo.combos.forEach(combo => {
            const comboCount = countBy(combo.components, co => co);
            const buyCount = countBy(combo.components, co => co);
            const valid = selectedItems.every(c => {
                if (!combo.components.includes(c)) return false;
                if (itemCount[c] > comboCount[c]) return false;
                buyCount[c] -= 1;
                return true;
            });
            if (valid) {
                const fullCombo = combo.components.every(c => itemCount[c] === comboCount[c]);
                if (fullCombo) vboxCombiner = combo.item;

                forEach(buyCount, (value, key) => {
                    if (value > 0 && !vboxHighlight.includes(key)) {
                        vboxHighlight.push(key);
                    }
                });
            }
        });
    }


    const vboxInfo = () => {
        if (vboxCombiner) return vboxCombiner;
        if (itemUnequip.length) return itemUnequip[1];
        const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.stash[i])));
        if (stashBase > -1) return vbox.stash[stashBase];
        const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.store[j[0]][j[1]])));
        if (storeBase) return vbox.store[storeBase[0]][storeBase[1]];
        if (stashSelect.length > 0) return vbox.stash[stashSelect[0]];
        if (storeSelect.length > 0) return vbox.store[storeSelect[0][0]][storeSelect[0][1]];
        return false;
    };

    dispatch(actions.setVboxInfo(vboxInfo()));
    dispatch(actions.setVboxCombiner(vboxCombiner));
    dispatch(actions.setVboxHighlight(vboxHighlight));
}

function genItemInfo(item, itemInfo, player) {
    const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item];
    const isSkill = fullInfo.skill;
    const isSpec = fullInfo.spec;
    const itemDescription = () => {
        const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/;
        const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]());
        return <div>{reactStringReplace(infoDescription, '\n', () => <br />)}</div>;
    };
    if (isSkill || isSpec) {
        let infoName = fullInfo.item;
        while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+');

        const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item));

        let itemSourceInfo = itemSource.length && !isSpec
            ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
            : false;

        let header = null;
        if (!itemSource.length) header = isSkill ? <h3> SKILL </h3> : <h3> SPEC </h3>;
        if (itemSourceInfo) {
            while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+');
            const itemRegEx = /(Red|Blue|Green)/;
            itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
        }

        const cooldown = isSkill && fullInfo.cooldown ? <div>{fullInfo.cooldown} Turn delay</div> : null;

        const speed =  isSkill
            ? <div> Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}% </div>
            : null;

        const thresholds = isSpec ? specThresholds(player, fullInfo, item) : null;

        return (
            <div class="info info-item">
                <h2>{infoName}</h2>
                {header}
                {itemSourceInfo}
                {cooldown}
                {itemDescription()}
                {speed}
                {thresholds}
            </div>
        );
    }
    return (
        <div class="info info-item">
            <h2>{fullInfo.item}</h2>
            {itemDescription()}
        </div>
    );
}

function cost(group) {
    if (group === 'Colours') return 1;
    if (group  === 'Skills') return 2;
    if (group  === 'Specs') return 3;
};

module.exports = { setVboxState, genItemInfo, cost };
