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, animText } = state;
        return { animSource, animTarget, animText };
    }
);

class ConstructAvatar extends Component {
    constructor(props) {
        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 ? mouseOver : null}
                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, animText, construct } = this.props;
        // a different text object and text construct
        if (animText && animText !== prevProps.animText && animText.constructId === construct.id) {
            return wiggle(construct.id, this.idle);
        }

        // different source object and source construct
        if (animSource && animSource !== prevProps.animSource && animSource.constructId === construct.id) {
            return sourceCast(animSource.constructId, animSource.direction, this.idle);
        }

        // different target object and target construct
        if (animTarget && animTarget !== prevProps.animTarget && animTarget.constructId.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, animText, construct } = newProps;
        if (animSource !== this.props.animSource) return true;
        if (animTarget !== this.props.animTarget) return true;
        if (animText !== this.props.animText) return true;
        if (construct !== this.props.construct) return true;
        return false;
    }
}


const addStateText = connect(
    function receiveState(state) {
        const { animText } = state;
        return { animText };
    }
);

function constructText(props) {
    const { construct, animText } = props;
    if (!construct) return false;

    const text = animText && animText.constructId === construct.id
        ? animText.text
        : construct.name;

    return <h3 class={'name'}><span>{text}</span></h3>;
}

module.exports = {
    ConstructAvatar: addState(ConstructAvatar),
    ConstructText: addStateText(constructText),
};
