const preact = require('preact');
const { Component } = require('preact');
const { connect } = require('preact-redux');
// const anime = require('animejs').default;
const reactStringReplace = require('react-string-replace');
const throttle = require('lodash/throttle');

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

const addState = connect(
    ({ game, account, animating, itemInfo, gameEffectInfo, tutorialGame }) =>
        ({ game, account, animating, itemInfo, gameEffectInfo, tutorialGame })
);

class TargetSvg extends Component {
    constructor() {
        super();
        this.state = { width: 3000, height: 1000 };

        this.onResize = throttle(() => {
            const svg = document.getElementById('targeting');
            if (!svg) return setTimeout(this.onResize, 500);
            const { width, height } = svg.getBoundingClientRect();
            // const path = document.querySelector('#targeting path');
            this.setState({ width, height });
        }, 500);
    }

    shouldComponentUpdate(newProps, newState) {
        if (newProps.game !== this.props.game) return true;
        if (newProps.account !== this.props.account) return true;
        if (newProps.animating !== this.props.animating) return true;
        if (newProps.gameEffectInfo !== this.props.gameEffectInfo) return true;
        if (newProps.tutorialGame !== this.props.tutorialGame) return true;
        if (newState.width !== this.state.width) return true;
        if (newState.height !== this.state.height) return true;
        return false;
    }

    render(props, state) {
        const {
            // Changing State Variables
            account,
            animating,
            game,
            gameEffectInfo,
            tutorialGame,
        } = props;
        const { width, height } = state;

        if (!game) return false; // game will be null when battle ends
        if (game.phase === 'Finished') return false; // Clear everything if its over (in case of abandon)

        // First time joining game phase
        if (tutorialGame) {
            return (
                <div class="resolving-skill">
                    <h2>Select your skills, click on targets and then hit <b>READY</b>.</h2>
                </div>
            );
        }

        // Whenever someones looking at effects throw it up here
        if (gameEffectInfo) {
            const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat)/;
            const infoString = effectInfo(gameEffectInfo);
            const infoDescription = reactStringReplace(infoString, regEx, match => shapes[match]());

            return (
                <div class="resolving-skill">
                    <h1>{gameEffectInfo.effect}</h1>
                    <div>{infoDescription}</div>
                </div>
            );
        }

        // resolutions happening
        // just put skill name up
        if (animating) return false;

        const playerTeam = game.players.find(t => t.id === account.id);
        const otherTeam = game.players.find(t => t.id !== account.id);

        const playerTeamIds = playerTeam.constructs.map(c => c.id);
        const outgoing = game.stack.filter(stack => stack.player === account.id);

        function getPath(cast) {
            const source = playerTeam.constructs.findIndex(c => c.id === cast.source);
            const defensive = playerTeamIds.includes(cast.target);
            const target = defensive
                ? playerTeam.constructs.findIndex(c => c.id === cast.target)
                : otherTeam.constructs.findIndex(c => c.id === cast.target);

            const skillNumber = window.innerWidth <= 800 // mobile styling trigger
                ? playerTeam.constructs[source].skills.findIndex(s => s.skill === cast.skill)
                : 0;
            const sourceY = height;
            const sourceX = (source * width / 3) + width / 18 + skillNumber * (width / 9);
            const targetX = (target * width / 3) + width / 6
                + (defensive ? width / 64 : 0)
                + (source * width / 18);
            const targetY = defensive ? height : 0;
            const bendStart = height * (0.7 - 0.1 * source);
            const bendEnd = height * 0.20;

            if (defensive) {
                const path = `
                    M${sourceX},${sourceY}
                    L${sourceX},${bendStart}
                    L${targetX},${bendStart}
                    L${targetX},${targetY}
                    L${targetX - (width * 0.005)},${height * 0.875}
                    M${targetX},${targetY}
                    L${targetX + (width * 0.005)},${height * 0.875}
                `;

                return <path d={path} />;
            }

            const path = `
                M${sourceX},${sourceY}
                L${sourceX},${bendStart}
                L${targetX},${bendEnd}
                L${targetX},${targetY}
                L${targetX - (width * 0.005)},${height * 0.125}
                M${targetX},${targetY}
                L${targetX + (width * 0.005)},${height * 0.125}

            `;

            return <path d={path} />;
        }

        return (
            <svg id="targeting"
                viewBox={`0 0 ${width} ${height}`}
                preserveAspectRatio="none"
                class="targeting-arrows">
                {outgoing.map(getPath)}
            </svg>
        );
    }

    componentDidMount() {
        window.addEventListener('resize', this.onResize);
        this.onResize();
        setTimeout(this.onResize, 50);
        // anime({
        //     targets: ['#targeting path'],
        //     strokeDashoffset: [anime.setDashoffset, 0],
        //     duration: 1000,
        //     easing: 'linear',
        //     loop: true,
        //     delay: anime.stagger(3000),
        // });
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.onResize);
    }
}

module.exports = addState(TargetSvg);
