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

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

function match(value, patterns) {
    for (let i = 0; i < patterns.length; i++) {
        if (value === patterns[i][0]) {
            return patterns[i][1]();
        }
    }

    console.warn('default match - return null', value, patterns);
    return null;
}

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,
    },
    SpeedStat: {
        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,
    },
};

const COLOURS = [
    '#a52a2a',
    '#1FF01F',
    '#3050f8',
];

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

function randomPoints(numPoints, radius, dimensions) {
    const {
        x,
        y,
        width,
        height,
    } = dimensions;
    const points = [];
    let infCheck = 0;
    while (points.length < numPoints) {
        const c = [
            Math.floor(Math.random() * (x + width - 2 * radius) + x + radius),
            Math.floor(Math.random() * (y + height - 2 * radius) + y + radius),
        ];
        let overlapping = false;
        for (let j = 0; j < points.length; j += 1) {
            const o = points[j];
            const dx = c[0] - o[0];
            const dy = c[1] - o[1];
            const d = Math.floor(Math.sqrt(dx * dx + dy * dy));
            if (d < radius) {
                overlapping = true;
            }
        }
        if (!overlapping) {
            points.push(c);
            infCheck = 0;
        } else {
            infCheck += 1;
            if (infCheck > 100) {
                break;
            }
        }
    }
    return points;
}

const removeTier = skill => {
    if (skill.includes('SiphonTick')) return 'SiphonTick';
    if (skill.includes('TriageTick')) return 'TriageTick';
    if (skill.includes('DecayTick')) return 'DecayTick';
    if (skill.includes('ElectrocuteTick')) return 'ElectrocuteTick';

    if (skill.includes('Strike')) return 'Strike';
    if (skill.includes('Heal')) return 'Heal';
    if (skill.includes('Blast')) return 'Blast';
    if (skill.includes('Chaos')) return 'Chaos';
    if (skill.includes('Slay')) return 'Slay';
    if (skill.includes('Siphon')) return 'Siphon';

    if (skill.includes('Restrict')) return 'Restrict';
    if (skill.includes('Purge')) return 'Purge';
    if (skill.includes('Silence')) return 'Silence';
    if (skill.includes('Curse')) return 'Curse';
    if (skill.includes('Decay')) return 'Decay';
    if (skill.includes('Invert')) return 'Invert';

    if (skill.includes('Intercept')) return 'Intercept';
    if (skill.includes('Triage')) return 'Triage';
    if (skill.includes('Link')) return 'Link';
    if (skill.includes('Haste')) return 'Haste';
    if (skill.includes('Hybrid')) return 'Hybrid';
    if (skill.includes('Amplify')) return 'Amplify';

    if (skill.includes('Counter')) return 'Counter';
    if (skill.includes('Purify')) return 'Purify';
    if (skill.includes('Electrify')) return 'Electrify';
    if (skill.includes('Electrocute')) return 'Electrocute';
    if (skill.includes('Sustain')) return 'Sustain';
    if (skill.includes('Reflect')) return 'Reflect';
    if (skill.includes('Recharge')) return 'Recharge';

    if (skill.includes('Bash')) return 'Bash';
    if (skill.includes('Sleep')) return 'Sleep';
    if (skill.includes('Ruin')) return 'Ruin';
    if (skill.includes('Break')) return 'Break';
    if (skill.includes('Hex')) return 'Hex';
    if (skill.includes('Absorb')) return 'Absorb';
    if (skill.includes('Banish')) return 'Banish';

    return skill;
};

function itemSpeed(item) {
    switch (item) {
    case 'Attack': return 1;
    case 'Stun': return 2;
    case 'Block': return 3;
    case 'Buff': return 4;
    case 'Debuff': return 4;
    case 'Red': return 3;
    case 'Green': return 2;
    case 'Blue': return 1;
    default: return 0;
    }
}

function postData(url = '/', data = {}) {
    // Default options are marked with *
    return fetch(`/api${url}`, {
        method: 'POST', // *GET, POST, PUT, DELETE, etc.
        // mode: 'no-cors', // no-cors, cors, *same-origin
        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
        credentials: 'include', // include, same-origin, *omit
        headers: {
            Accept: 'application/json',
            'content-type': 'application/json',
        },
        redirect: 'error', // manual, *follow, error
        // referrer: ', // no-referrer, *client
        body: JSON.stringify(data), // body data type must match "Content-Type" header
    });
}

function errorToast(message) {
    toast.error({
        position: 'topRight',
        drag: false,
        close: false,
        message,
    });
}

function infoToast(message) {
    toast.info({
        position: 'topRight',
        drag: false,
        close: false,
        message,
    });
}

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

module.exports = {
    stringSort,
    numSort,
    postData,
    convertItem,
    errorToast,
    infoToast,
    NULL_UUID,
    STATS,
    COLOURS,
    TARGET_COLOURS,
    randomPoints,
    removeTier,
    itemSpeed,
    match,
};
