const preact = require('preact');
const get = require('lodash/get');

const shapes = require('./components/shapes');

const stringSort = (k, desc) => {
    if (desc) {
        return (a, b) => {
            if (!get(a, k)) return 1;
            if (!get(b, k)) return -1;
            return get(b, k).localeCompare(get(a, k));
        };
    }
    return (a, b) => {
        if (!get(a, k)) return 1;
        if (!get(b, k)) return -1;
        return get(a, k).localeCompare(get(b, k));
    };
};

const numSort = (k, desc) => {
    if (desc) {
        return (a, b) => {
            if (!get(a, k)) return 1;
            if (!get(b, k)) return -1;
            return get(b, k) - get(a, k);
        };
    }
    return (a, b) => {
        if (!get(a, k)) return 1;
        if (!get(b, k)) return -1;
        return get(a, k) - get(b, k);
    };
};

const NULL_UUID = '00000000-0000-0000-0000-000000000000';

const STATS = {
    RedPower: {
        stat: 'red_power',
        colour: 'red',
        svg: shapes.circle,
    },
    GreenPower: {
        stat: 'green_power',
        colour: 'green',
        svg: shapes.circle,
    },
    BluePower: {
        stat: 'blue_power',
        colour: 'blue',
        svg: shapes.circle,
    },
    Speed: {
        stat: 'speed',
        colour: 'white',
        svg: shapes.triangle,
    },
    RedLife: {
        stat: 'red_life',
        colour: 'red',
        svg: shapes.square,
    },
    GreenLife: {
        stat: 'green_life',
        colour: 'green',
        svg: shapes.square,
    },
    BlueLife: {
        stat: 'blue_life',
        colour: 'blue',
        svg: shapes.square,
    },
};

function eventClasses(resolution, construct) {
    if (!resolution) return '';
    const startSkill = resolution.stage === 'START_SKILL';
    const endSkill = resolution.stage === 'END_SKILL';
    const postSkill = resolution.stage === 'POST_SKILL';
    const source = construct.id === resolution.source.id;
    const target = construct.id === resolution.target.id;
    // not involved at all. blur them
    if (!(source || target)) return 'unfocus';

    // not the target. just ignore for now
    // if (construct.id !== resolution.target.id) return '';

    const [type, event] = resolution.event;

    if (type === 'Ko') {
        if (target) return 'ko';
    }

    if (type === 'Disable') {
        const { skill, disable } = event;
    }

    if (type === 'Immunity') {
        const { skill, immunity } = event;
    }

    if (type === 'TargetKo') {
        const { skill } = event;
    }

    if (type === 'Damage') {
        const { skill, amount, mitigation, colour } = event;
        // Highlight the flow of damage from source -> target
        if (source && startSkill) return 'active-skill';
        if (target && endSkill) return 'active-skill';

        // Deal damage to construct and return effect
        if (target && postSkill) {
            construct.green_life.value = resolution.target.green;
            if (colour === 'Red') {
                construct.red_life.value = resolution.target.red;
                return 'red-damage';
            }
            if (colour === 'Blue') {
                construct.blue_life.value = resolution.target.blue;
                return 'blue-damage';
            }
            if (colour === 'Green') {
                construct.green_life.value = resolution.target.green;
                return 'green-damage';
            }

        }
    }

    if (type === 'Healing') {
        const { skill, amount, overhealing } = event;
        if (source && startSkill) return 'active-skill';
        if (target && endSkill) return 'active-skill';
        if (target && postSkill) {
            construct.green_life.value = resolution.target.green;
            return 'green-damage';

        }
    }

    if (type === 'Inversion') {
        const { skill } = event;
    }

    if (type === 'Reflection') {
        const { skill } = event;
    }

    if (type === 'Effect') {
        const { skill, effect, duration, construct_effects: constructEffects } = event;
        if (source && startSkill) return 'active-skill';
        if (target && endSkill) return 'active-skill';
        if (target && postSkill) construct.effects = constructEffects;
    }

    if (type === 'Skill') {
        const { skill } = event;
        // Highlight the flow of damage from source -> target
        if (source && startSkill) return 'active-skill';
        if (target && endSkill) return 'active-skill';
    }

    if (type === 'Removal') {
        const { effect, construct_effects: constructEffects } = event;
        if (source && startSkill) return 'active-skill';
        if (target && endSkill) return 'active-skill';
        if (target && postSkill) construct.effects = constructEffects;
    }

    if (type === 'Recharge') {
        const { skill, red, blue } = event;
        if (source && startSkill) return 'active-skill';
        if (target && endSkill) return 'active-skill';
        if (target && postSkill) {
            if (red > 0 && blue > 0) {
                construct.red_life.value = resolution.target.red;
                construct.blue_life.value = resolution.target.blue;
                return 'purple-damage';
            }
            if (red > 0) {
                construct.red_life.value = resolution.target.red;
                return 'red-damage';
            }
            if (blue > 0) {
                construct.blue_life.value = resolution.target.blue;
                return 'blue-damage';
            }
        }
    }

    if (type === 'Evasion') {
        const { skill, evasion_rating } = event;
    }

    return '';
}

function getCombatSequence(resolution) {
    if (!resolution.event) return false;
    if (resolution.event[0] === 'Inversion') return false;
    if (resolution.event[0] === 'Skill') return ['START_SKILL', 'END_SKILL'];
    if (resolution.event[0] === 'Ko') return ['POST_SKILL'];

    switch (resolution.stages) {
        case 1: return ['START_SKILL', 'END_SKILL'];
        case 2: return ['START_SKILL', 'POST_SKILL'];
        case 3: return ['START_SKILL'];
        case 4: return ['END_SKILL', 'POST_SKILL'];
        case 5: return ['END_SKILL'];
        case 6: return ['POST_SKILL'];
        case 7: return false;
        default: return ['START_SKILL', 'END_SKILL', 'POST_SKILL'];
    }
}

function getCombatText(construct, resolution) {
    if (!resolution) return ['', ''];


    const [type, event] = resolution.event;
    const source = construct.id === resolution.source.id;
    const target = construct.id === resolution.target.id;
    const startSkill = resolution.stage === 'START_SKILL';
    const endSkill = resolution.stage === 'END_SKILL';
    const postSkill = resolution.stage === 'POST_SKILL';

    if (type === 'Ko') {
        if (postSkill && target) return ['KO!', ''];
    }

    if (type === 'Disable') {
        const { skill, disable } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return [`${disable}`, ''];
    }

    if (type === 'Immunity') {
        const { skill, immunity } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return ['IMMUNE', ''];
    }

    if (type === 'TargetKo') {
        const { skill } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
    }

    if (type === 'Damage') {
        const { skill, mitigation, colour } = event;
        let { amount } = event;
        if (colour === 'Green') amount *= -1;
        const mitigationText = mitigation
            ? `(${mitigation})`
            : '';
        if (startSkill && source) return [`${skill}`, `${skill.toLowerCase()}-cast`];
        if (endSkill && target) return [`${skill}`, `${skill.toLowerCase()}-hit`];
        if (postSkill && target) return [`${amount} ${mitigationText}`, ''];
    }

    if (type === 'Healing') {
        const { skill, amount, overhealing } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return [`${amount} (${overhealing} OH)`, ''];
    }

    if (type === 'Inversion') {
        const { skill } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return ['INVERT', ''];
    }

    if (type === 'Reflection') {
        const { skill } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return ['REFLECT', ''];
    }

    if (type === 'Effect') {
        const { skill, effect, duration } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return [`+ ${effect} ${duration}T`, ''];
    }

    if (type === 'Recharge') {
        const { skill, red, blue } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
        if (postSkill && target) return [`+${red}R ${blue}B`, ''];
    }

    if (type === 'Skill' || type === 'AoeSkill') {
        const { skill } = event;
        if (startSkill && source) return [`${skill}`, ''];
        if (endSkill && target) return [`${skill}`, ''];
    }

    if (type === 'Removal') {
        const { effect } = event;
        if (postSkill && target) return [`-${effect}`, ''];
    }


    return '';
}

function convertItem(v) {
    if (['Red', 'Green', 'Blue'].includes(v)) {
        return (
            shapes.vboxColour(v.toLowerCase())
        );
    }
    return v || <span>&nbsp;</span>;
    // uncomment for double borders in vbox;
    // if (v) {
    //     return <div>{v}</div>;
    // }
    // return;
}

const COLOURS = [
    '#a52a2a',
    '#1FF01F',
    '#3498db',
];

const TARGET_COLOURS = {
    BLUE: '#004bfe',
    CYAN: '#27e7c0',
    PURPLE: '#61008c',
    YELLOW: '#fdfe02',
    ORANGE: '#ff9215',
    PINK: '#e766b6',
    GRAY: '#9d9ea0',
    LBLUE: '#87c6f2',
    GREEN: '#166c4f',
    BROWN: '#583108',
};

module.exports = {
    stringSort,
    convertItem,
    numSort,
    eventClasses,
    getCombatSequence,
    getCombatText,
    NULL_UUID,
    STATS,
    COLOURS,
    TARGET_COLOURS,
};
