const preact = require('preact');

const Amplify = require('./anims/amplify');
const Absorb = require('./anims/absorb');
const Bash = require('./anims/bash');
const Blast = require('./anims/blast');
const Block = require('./anims/block');
const Buff = require('./anims/buff');
const Break = require('./anims/break');
const Chaos = require('./anims/chaos');
const Sustain = require('./anims/sustain');
const Counter = require('./anims/counter');
const Curse = require('./anims/curse');
const Debuff = require('./anims/debuff');
const Decay = require('./anims/decay');
const Electrify = require('./anims/electrify');
const Electrocute = require('./anims/electrocute');
const Haste = require('./anims/haste');
const Heal = require('./anims/heal');
const Hybrid = require('./anims/hybrid');
const Intercept = require('./anims/intercept');
const Link = require('./anims/link');
const Purify = require('./anims/purify');
const Purge = require('./anims/purge');
const Recharge = require('./anims/recharge');
const Refl = require('./anims/reflect');
const Restrict = require('./anims/restrict');
const Ruin = require('./anims/ruin');
const Silence = require('./anims/silence');
const Siphon = require('./anims/siphon');
const SiphonTick = require('./anims/siphon.tick');
const Slay = require('./anims/slay');
const Sleep = require('./anims/sleep');
const Strike = require('./anims/strike');
const Stun = require('./anims/stun');
const Triage = require('./anims/triage');
const TriageTick = require('./anims/triage.tick');

// const Test = require('./anims/test');

const { removeTier } = require('../utils');

function animations(props) {
    const { game, account, resolution, player, construct, avatarAnimation, setAvatarAnimation } = props;
    if (!resolution || resolution === 'clear') return false;
    const [, event] = resolution.event;
    if (!event || !event.skill) return false;
    if (!resolution.target) return false;

    // source animation
    const playerTeam = game.players.find(t => t.id === account.id);
    const playerTeamIds = playerTeam.constructs.map(c => c.id);
    const otherTeam = game.players.find(t => t.id !== account.id);
    const otherTeamIds = otherTeam.constructs.map(c => c.id);

    const sourceIsPlayer = playerTeamIds.includes(resolution.source.id);
    const targetIsPlayer = playerTeamIds.includes(resolution.target.id);

    const getDirection = () => {
        const sameTeam = (sourceIsPlayer && targetIsPlayer) || (!sourceIsPlayer && !targetIsPlayer);
        let y = 0;
        if (!sameTeam) y = targetIsPlayer ? 1 : -1;

        const i = sourceIsPlayer
            ? playerTeamIds.findIndex(c => c === resolution.source.id)
            : otherTeamIds.findIndex(c => c === resolution.source.id);

        const j = targetIsPlayer
            ? playerTeamIds.findIndex(c => c === resolution.target.id)
            : otherTeamIds.findIndex(c => c === resolution.target.id);
        const x = j - i;
        return { x, y };
    };

    const skipSource = (resolution.source.id === resolution.target.id
        && ['Invert', 'Banish'].includes(removeTier(event.skill)));

    // Play Source Animation
    if (!skipSource && resolution.source.id === construct.id && resolution.stages.includes('START_SKILL')) {
        if (!avatarAnimation.source) {
            setAvatarAnimation(true, avatarAnimation.target, resolution.id,
                construct.id, 'sourceCast', getDirection());
        }
    }
    const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
    if (!(resolution.target.id === construct.id)
        && !(resolution.event[0] === 'AoeSkill' && targetTeam.includes(construct.id))) return false;

    // Play Target animation
    const anim = text => {
        if (!text || !resolution.sequence[0].includes('END_SKILL')) return false;
        const skill = removeTier(text);
        switch (skill) {
        // Attack base
        case 'Attack': return <Strike colour={'#f5f5f5'} direction={getDirection()}/>;
        case 'Blast': return <Blast direction={getDirection()}/>;
        case 'Siphon': return <Siphon />;
        case 'SiphonTick': return <SiphonTick />;
        case 'Strike': return <Strike colour={'#a52a2a'} direction={getDirection()}/>;
        case 'Chaos': return <Chaos direction={getDirection()}/>;
        case 'Slay': return <Slay direction={getDirection()}/>;
        case 'Heal': return <Heal />;

        // Buff Base
        case 'Buff': return <Buff />;
        case 'Amplify': return <Amplify />;
        case 'Haste': return <Haste />;
        case 'Triage': return <Triage />;
        case 'TriageTick': return <TriageTick />;
        case 'Link': return <Link player={player} />;
        case 'Hybrid': return <Hybrid />;
        case 'Intercept': return <Intercept player={player} />;

        // Debuff base
        case 'Debuff': return <Debuff />;
        case 'Curse': return <Curse />;
        case 'Decay': return <Decay />;
        case 'DecayTick': return <Decay />;
        case 'Invert': {
            if (!avatarAnimation.target) {
                setAvatarAnimation(avatarAnimation.source, true, resolution.id, construct.id, 'invert', null);
            } return false;
        }
        case 'Purge': return <Purge />;
        case 'Silence': return <Silence />;
        case 'Restrict': return <Restrict />;

        // Stun Base
        case 'Stun': return <Stun />;
        case 'Banish': {
            if (!avatarAnimation.target) {
                setAvatarAnimation(avatarAnimation.source, true, resolution.id, construct.id, 'banish', null);
            } return false;
        }
        case 'Bash': return <Bash />;
        case 'Absorb': return <Absorb />;
        case 'Sleep': return <Sleep />;
        case 'Break': return <Break />;
        case 'Ruin': return <Ruin />;

        // Block Base
        case 'Block': return <Block />;
        case 'Sustain': return <Sustain team={player} />;
        case 'Electrify': return <Electrify />;
        case 'Electrocute': return <Electrocute />;
        case 'ElectrocuteTick': return <Electrocute />;
        case 'Counter': return <Counter team={player} />;
        case 'Purify': return <Purify team={player} />;
        case 'Recharge': return <Recharge team={player} />;
        case 'Reflect': return <Refl team={player} />;

        default: return false;
        }
    };

    const combatAnim = anim(event.skill);
    if (!combatAnim) return false;
    return (
        <div class={'combat-anim'}>
            {combatAnim}
        </div>
    );
}

module.exports = animations;
