import regeneratorRuntime from "babel-runtime/regenerator";
import React from "react";
import ReactDOM from "react-dom";
import lodash from "lodash";
import classNames from "classnames";
import { buildGridClassNames, columnProps } from "./AnterosLayout";
import { AnterosLocalDatasource, AnterosRemoteDatasource, dataSourceEvents } from "./AnterosDatasource";


let base64ImageFile = function (imageFile) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = event => {
            const image = new Image();

            image.onload = () => {
                resolve(image.src);
            };

            image.onerror = reject;

            image.src = event.target.result;
        };

        reader.readAsDataURL(imageFile);
    });
}

export default class AnterosImagePicker extends React.Component {


    constructor(props) {
        super(props);
        this.onSelect = this.onSelect.bind(this);
        this.onRemove = this.onRemove.bind(this);
        this.onDoubleClickImage = this.onDoubleClickImage.bind(this);
        this.idImage = lodash.uniqueId("imagePicker");
        this.state = { value: "" };

        if (this.props.dataSource) {
            let value = this.props.dataSource.fieldByName(this.props.dataField);
            if (!value) {
                value = '';
            }
            this.state = { value: value };
        } else {
            this.state = { value: this.props.value };
        }
        this.onDatasourceEvent = this.onDatasourceEvent.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.dataSource) {
            let value = nextProps.dataSource.fieldByName(nextProps.dataField);
            if (!value) {
                value = '';
            }
            this.state = { value: value };
        } else {
            this.state = { value: nextProps.value };
        }
    }

    componentDidMount() {
        let _this = this;
        if (this.props.dataSource) {
            this.props.dataSource.addEventListener(
                [dataSourceEvents.AFTER_CLOSE,
                dataSourceEvents.AFTER_OPEN,
                dataSourceEvents.AFTER_GOTO_PAGE,
                dataSourceEvents.AFTER_CANCEL,
                dataSourceEvents.AFTER_SCROLL], this.onDatasourceEvent);
            this.props.dataSource.addEventListener(dataSourceEvents.DATA_FIELD_CHANGED, this.onDatasourceEvent, this.props.dataField);
        }
    }

    componentWillUnmount() {
        if ((this.props.dataSource)) {
            this.props.dataSource.removeEventListener(
                [dataSourceEvents.AFTER_CLOSE,
                dataSourceEvents.AFTER_OPEN,
                dataSourceEvents.AFTER_GOTO_PAGE,
                dataSourceEvents.AFTER_CANCEL,
                dataSourceEvents.AFTER_SCROLL], this.onDatasourceEvent);
            this.props.dataSource.removeEventListener(dataSourceEvents.DATA_FIELD_CHANGED, this.onDatasourceEvent, this.props.dataField);
        }
    }

    onDatasourceEvent(event, error) {
        let value = this.props.dataSource.fieldByName(this.props.dataField);
        if (!value) {
            value = '';
        }
        this.setState({ value: value });
    }

    onRemove() {
        ReactDOM.findDOMNode(this.refs.input).value = "";
    }

    onSelect(event) {
        if (!event.target.files.length) {
            this.onRemove();
            return;
        }

        let file = event.target.files[0];
        const { onInvalidImage } = this.props;

        if (!file.type.match(/^image\//)) {
            this.onRemove();
            return onInvalidImage(`${this.props.notImage || "Não é uma imagem válida."}`)
        }
        if (file.size > this.props.maxImageFileSize) { //made changes to use props maxfileSize
            this.onRemove();
            return onInvalidImage(`${this.props.imageTooLarge || "Image muito grande."}`)
        }
        this.selectImage(file);
    }

    onDoubleClickImage(event) {
        let readOnly = this.props.readOnly;
        if (this.props.dataSource && !readOnly) {
            readOnly = (this.props.dataSource.getState() == 'dsBrowse');
        }
        if (!readOnly) {
            $('#'+this.idImage+"_input").click();
        }
    }

    render() {

        return (<div className="fileUpload" style={{ display: "grid" }} id={this.idImage}>
            <img src={this.state.value} style={{ ...this.props.style, border: "1px solid silver", width: this.props.width, height: this.props.height }} onDoubleClick={this.onDoubleClickImage} />
            <input id={this.idImage + "_input"} type="file"
                className="imageUpload"
                onChange={this.onSelect}
                ref="input" style={{ display: "none" }} />
        </div>
        );
    }
    onRemoveImage() {
        this.setState({ image: null });
        this.props.onRemoveImage();
    }

    onErrorImageLoading(error) {
        this.setState({
            original: null,
            cropping: false,
            loading: false,
            urlsReceived: false
        });
        this.onRemoveImage();
    }

    async selectImage(imageFile) {
        if (this.props.minSize) {
            var [minWidth, minHeight] = this.props.minSize; //pass props size
        }
        const { onInvalidImage } = this.props;
        const image = new Image();
        const imageBase = await base64ImageFile(imageFile);
        image.src = imageBase;
        let _this = this;

        image.onload = async () => {
            try {
                if (image.width < (minWidth || 0) * 0.995 || image.height < (minHeight || 0) * 0.995 && onInvalidImage) {
                    return onInvalidImage(`${this.props.imageTooSmall || "Imagem muito pequena."} ${minWidth} x ${minHeight}`); //pass error
                }

                if (_this.props.dataSource && _this.props.dataSource.getState !== 'dsBrowse') {
                    _this.props.dataSource.setFieldByName(_this.props.dataField, imageBase);
                } else {
                    _this.setState({ value: imageBase });
                }
                if (_this.props.onSelect) {
                    _this.props.onSelect(imageBase, imageFile);
                }

            } catch (error) {
                this.onErrorImageLoading(error);
            }
        };

    }

}


AnterosImagePicker.propTypes = {
    dataSource: React.PropTypes.oneOfType([
        React.PropTypes.instanceOf(AnterosLocalDatasource),
        React.PropTypes.instanceOf(AnterosRemoteDatasource)
    ]),
    dataField: React.PropTypes.string,
    value: React.PropTypes.string.isRequired,
    placeHolder: React.PropTypes.string,
    disabled: React.PropTypes.bool,
    onSelect: React.PropTypes.func,
    onError: React.PropTypes.func,
    onInvalidImage: React.PropTypes.func,
    width: React.PropTypes.string.isRequired,
    height: React.PropTypes.string.isRequired,
    readOnly: React.PropTypes.bool.isRequired
}

AnterosImagePicker.defaultProps = {
    width: "150px",
    height: "200px",
    readOnly: false,
    value: ''
}
