import React from 'react';
import propTypes from 'prop-types';

export default Component => class Poster extends React.Component{
    static props = {
        defaultImgUrl: '/static/dist/' + require('./images/no-image.svg'),
        waitImage: false,
        src: null,
        width: 0,
        height: 0,
        alt: ''
    }
    static propTypes = {
        defaultImgUrl: propTypes.string,
        src: propTypes.oneOfType([propTypes.func, propTypes.string, propTypes.instanceOf(Promise)]),
        width: propTypes.number,
        height: propTypes.number,
        alt: propTypes.string,
        onClick: propTypes.func
    }

    constructor(props){
        super(props);
        this.state = {
            loaded: false,
            width: props.width,
            height: props.height,
            src: ''
        };
    }
    getSrc(props) {
        props = props || this.props;
        const {waitImage, src, defaultImgUrl} = props;
        if(waitImage) {
            return new Promise((resolve, reject) => {
                this.resolveWait = resolve;
                this.rejectWait = reject;
            });
        } else if (src instanceof Promise) {
            return src.then(result => result || defaultImgUrl);
        } else {
            return Promise.resolve(src || defaultImgUrl);
        }
    }
    loadImage() {
        return this.getSrc()
            .then(src => {
                const img = new Image();
                img.addEventListener('load', e => this.setState({
                    src,
                    loaded: true,
                    imgWidth: img.width,
                    imgHeight: img.height
                }));
                img.src = src;
            });
    }
    componentDidMount() {
        this.loadImage();
    }
    componentWillUnmount() {
        this.rejectWait = null;
        this.resolveWait = null;
    }
    componentWillReceiveProps(nProps) {
        if (this.props.waitImage && !nProps.waitImage) {
            this.resolveWait && this.rejectWait(nProps.src || nProps.defaultImgUrl);
        }
    }
    render() {
        const {loaded, src, imgWidth, imgHeight} = this.state;
        return (<Component
            {...this.props}
            imgWidth={imgWidth}
            imgHeight={imgHeight}
            loaded={loaded}
            src={src}
        />);
    }
}
