import React, { Component } from 'react';
import PropTypes from 'prop-types';

/**
 * A stateful component which renders a callout.
 */
class Callout extends Component {

    componentWillMount() {
        if(window){
            this.windowWidth = window.innerWidth;
        }
        if(document.getElementById(this.props.calloutFor) !== null){
        let ElemRect = document.getElementById(this.props.calloutFor).getBoundingClientRect();

        if(window) {
            if(window.innerHeight-ElemRect.top <= 180) {
                this.setState({position: 'up'});
            }
            else {
                this.setState({position: 'bottom'});
            }
        }
    }
}

    componentDidMount(){

        if(document.getElementById(this.props.calloutFor) !== null){
        this.setState({callOutHeight: this.nameCallout.current.getBoundingClientRect().height});
        window.addEventListener('scroll', this.handleScroll);
        let ElemRect = document.getElementById(this.props.calloutFor).getBoundingClientRect();


        if(this.windowWidth){
            if(this.windowWidth < this.nameCallout.current.getBoundingClientRect().right){
                this.setState({position:'bottom'});
            }
        }
        if(this.nameCallout.current.clientWidth < 200){
            this.setState({position:'bottom'});
        }


        if(this.nameCallout.current.getBoundingClientRect().width<ElemRect.width) {
            let forCenter=ElemRect.width-this.nameCallout.current.getBoundingClientRect().width;
            forCenter=(forCenter/2);
            this.setState({forCenter: forCenter});
        }
    }
}



    componentWillUnmount() {
        window.removeEventListener('scroll', this.handleScroll);
    }

    handleScroll=() => {
        if(document.getElementById(this.props.calloutFor) !== null){
        let ElemRect = document.getElementById(this.props.calloutFor).getBoundingClientRect();

        if(window) {
            if(window.innerHeight-ElemRect.top <= 180) {
                this.setState({position: 'up'});
            }
            else {
                this.setState({position: 'bottom'});
            }
        }
    }
}

    nameCallout = React.createRef();
    windowWidth = null;


    state = {
        position: this.props.position,
        callOutHeight: 0,
        forCenter: 0
    };


    render() {


        let style = {}, calloutProps = {...this.props};
        delete calloutProps.calloutFor;
        delete calloutProps.type;
        delete calloutProps.position;
        delete calloutProps.children;
        delete calloutProps.parentClassName;
        delete calloutProps.style;

        if(document.getElementById(this.props.calloutFor)){
            let bodyRect = document.body.getBoundingClientRect(),
                ElemRect = document.getElementById(this.props.calloutFor).getBoundingClientRect();
            if(this.state.position === 'right'){
                style = {
                    ...this.props.style,
                    top: ElemRect.top - bodyRect.top + ElemRect.height / 2,
                    left: ElemRect.right + 10
                };
            } else if(this.state.position === 'bottom'){
                style = {
                    ...this.props.style,
                    top: ElemRect.top - bodyRect.top + ElemRect.height+10,
                    left: ElemRect.left+this.state.forCenter,
                    maxWidth: ElemRect.width
                };
            }
            else if(this.state.position === 'up') {
                style = {
                    ...this.props.style,
                    top: ElemRect.top - bodyRect.top-10-this.state.callOutHeight,
                    left: ElemRect.left+this.state.forCenter,
                    maxWidth: ElemRect.width
                };
            }

        }

        let classes = ['jp-callout-container',
            this.props.type,
            this.state.position,
            this.props.parentClassName ? this.props.parentClassName : null
        ];

        return (
            <div className={classes.join(' ')}
                style={style}
                ref={this.nameCallout}
                {...calloutProps} >
                <div className="jp-callout-tooltip">
                    <div className="jp-callout-content">
                        {this.props.children}
                    </div>
                </div>
            </div>
        );
    }
}

export default Callout;

Callout.propTypes = {
    /** ID of the element for which the callout should open */
    calloutFor: PropTypes.string.isRequired,
    /** Type of callout */
    type: PropTypes.oneOf(['darkBlue', 'lightBlue', 'white', 'whiteBorder']),
    /** Position of callout */
    position: PropTypes.oneOf(['right', 'bottom']),
    /** Class applied to parent container for additional styling  */
    parentClassName: PropTypes.string,
    /** Inline style for element */
    style: PropTypes.object,
    /** All elements inside the callout */
    children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.node),
        PropTypes.node
    ])
};

Callout.defaultProps = {
    type: 'darkBlue',
    position: 'bottom',
    style: {}
};
