const preact = require('preact');
const { Component } = require('preact');
const { connect } = require('preact-redux');

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

const banish = require('./anims/banish');
const idleAnimation = require('./anims/idle');
const invert = require('./anims/invert');
const wiggle = require('./anims/wiggle');
const sourceCast = require('./anims/source.cast');
const { ConstructAnimation } = require('./animations');

const addState = connect(
    function receiveState(state) {
        const { animSource, animTarget, resolution, account } = state;
        return { animSource, animTarget, resolution, account };
    }
);

class ConstructAvatar extends Component {
    constructor() {
        super();
        // The animation ids are a check to ensure that animations are not repeated
        // When a new construct animation is communicated with state it will have a corresponding Id
        // which is a count of how many resoluttions have passed
        this.animations = [];
        this.resetAnimations = this.resetAnimations.bind(this);
    }

    render() {
        const { construct, mouseOver } = this.props;
        return (
            <div
                class="avatar"
                id={construct.id}
                onMouseDown={this.onClick.bind(this)}
                onMouseOver={mouseOver}
                style={{ 'background-image': `url(/imgs/${construct.img}.svg)` }}>
                <ConstructAnimation construct={construct} />
            </div>
        );
    }

    onClick() {
        return this.animations.push(wiggle(this.props.construct.id, this.idle));
    }

    componentDidMount() {
        this.idle = idleAnimation(this.props.construct.id);
        return this.animations.push(this.idle);
    }

    resetAnimations() {
        for (let i = this.animations.length - 1; i >= 0; i--) {
            this.animations[i].reset();
        }
    }

    componentWillUnmount() {
        this.resetAnimations();
    }

    componentDidUpdate(prevProps) {
        const { animSource, animTarget, resolution, construct, account } = this.props;
        // a different text object and text construct
        if (resolution && resolution !== prevProps.resolution && resolution.event[1].construct === construct.id) {
            return wiggle(construct.id, this.idle);
        }

        // different source object and source construct
        if (animSource && animSource !== prevProps.animSource && animSource.event[1].construct === construct.id) {
            const { construct: constructId, player, direction: [x, y] } = animSource.event[1];
            const animY = y && player === account.id ? -1 : y;
            return sourceCast(constructId, { x, y: animY }, this.idle);
        }

        // different target object and target construct
        if (animTarget && animTarget !== prevProps.animTarget && animTarget.event[1].construct.includes(construct.id)) {
            switch (animTarget.skill) {
            case 'Banish': return banish(construct.id, this.idle);
            case 'Invert': return invert(construct.id, this.idle);
            default: return null;
            }
        }
        return true;
    }


    shouldComponentUpdate(newProps) {
        const { animSource, animTarget, resolution, construct, mouseOver } = newProps;
        if (animSource !== this.props.animSource) return true;
        if (animTarget !== this.props.animTarget) return true;
        if (resolution !== this.props.resolution) return true;
        if (construct !== this.props.construct) return true;
        if (mouseOver !== this.props.mouseOver) return true;
        return false;
    }
}

function ConstructName(props) {
    const { construct } = props;
    if (!construct) return false;
    return <h3 class={'name'}><span>{construct.name}</span></h3>;
}

module.exports = {
    ConstructAvatar: addState(ConstructAvatar),
    ConstructName,
};
