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 sourceCast = require('./anims/source.cast');

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

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() {
        return (
            <div
                class="avatar"
                id={this.props.construct.id}
                style={{ 'background-image': `url(/imgs/${this.props.construct.img}.svg)` }}
            />
        );
    }

    componentDidMount() {
        const { animSource, animTarget, construct } = this.props;

        // back to idle
        if (!animTarget && !animSource) {
            if (!this.idle) {
                this.idle = idleAnimation(this.props.construct.id);
                this.animations.push(this.idle);
            }

            return this.idle.play();
        }

        const isSource = animSource && animSource.constructId === construct.id;

        const selectAnim = () => {
            if (isSource) {
                console.warn(construct.name, animSource);
                return sourceCast(animSource.constructId, animSource.direction);
            }

            switch (animTarget.skill) {
            case 'banish': return banish(construct.id);
            case 'invert': return invert(construct.id);
            default: return null;
            }
        };

        const anim = selectAnim();
        if (!anim) return false;

        this.idle.pause();
        this.animations.push(anim);
        return true;
    }

    componentDidUpdate(prevProps) {
        const { animSource, animTarget, construct } = this.props;

        // back to idle
        if (!animTarget && !animSource) {
            return this.idle.play();
        }

        const isSource = animSource && animSource.constructId === construct.id;

        const selectAnim = () => {
            if (isSource) {
                return sourceCast(animSource.constructId, animSource.direction);
            }

            switch (animTarget.skill) {
            case 'Banish': return banish(construct.id);
            case 'Invert': return invert(construct.id);
            default: return null;
            }
        };

        const anim = selectAnim();
        if (!anim) return false;

        this.idle.pause();
        this.animations.push(anim);
        return true;
    }

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

    componentWillUnmount() {
        this.resetAnimations();
    }

    shouldComponentUpdate({ animSource, animTarget, construct }) {
        if (construct !== this.props.construct) {
            return true;
        }

        if (animSource === this.props.animSource && animTarget === this.props.animTarget) {
            // console.warn(construct.name, 'thinks its same props')
            return false;
        }

        // something has changed
        // what do?

        // this is the source
        if (animSource && animSource.constructId === construct.id) {
            // console.warn(construct.name, 'should update')
            return true;
        }

        // this is the target
        if (animTarget && animTarget.constructId === construct.id) {
            // console.warn(construct.name, 'should update')
            return true;
        }

        // we were previously doing src anim
        const prevSrc = this.props.animSource && this.props.animSource.constructId === construct.id;
        if (prevSrc && !animSource) return true;

        const prevTarget = this.props.animTarget && this.props.animTarget.constructId === construct.id;
        if (prevTarget && !animTarget) return true;

        // console.warn(construct.name, 'not updating');

        return false;
    }
}


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

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

    const text = animText.constructId === construct.id
        ? animText.text
        : null;

    return <div class={'combat-text'}>{text}</div>;
}

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