import React from 'react';
import PropTypes from 'prop-types';
import getDocumentScroll from 'reneco-utils/getDocumentScroll';
import scrollTo from 'reneco-utils/scrollTo';
import getClasses from 'reneco-utils/getClasses';

import RenderInBody from '../RenderInBody';

import './Popup.sass';

export default class Popup extends React.Component{
    static defaultProps = {
        DOMId: 'popup'
    }
    static contextTypes = {
        body: PropTypes.object
    }
    constructor(props){
        super(props);
        this.state = {
            width: props.width || 0,
            height: props.height || 0
        };
    }
    getBody() {
        return this.context.body || this.props.body || document.getElementsByTagName('body')[0];
    }
    calculatePosition(width, height){
        width = width || this.props.width;
        height = height || this.props.height;
        let data =  {};
        if( width > 0) { data.width = width; }
        if( height > 0) { data.height = height; }
        return data;
    }
    recalculatePosition = (width, height)=>{
        const newState = this.calculatePosition(width, height);
        if(Object.keys(newState)
            .findIndex(key => this.state[key] !== newState[key]) > -1
        ) {
            this.setState(newState);
        }
    }
    show(){
        // this.srolltop = this.context.body.scrollTop;
        if(!this.props.parent){
            this._scrollTop = getDocumentScroll().y;
            this.getBody().classList.add('modal-open');
        }
        this.setState({show:true});
    }
    _hide(noCallback){
        this.setState({show:false});
        if(!this.props.parent){
            this.getBody().classList.remove('modal-open');
            scrollTo(this._scrollTop);
        }
        // this.context.body.scrollTop = this.srolltop || 0;
        noCallback!==true && this.props.onHide && this.props.onHide();
    }
    hide = (noCallback, e)=>{
        e = noCallback === true || noCallback === false
            ? e
            : noCallback;
        e && e.stopPropagation && e.stopPropagation();
        e && e.preventDefault && e.preventDefault();
        if(this.props.beforeHide) {
            this.props.beforeHide() && this._hide(noCallback);
        } else {
            this._hide(noCallback);
        }
    }
    onKeyUp = event=>{
        event = event || window.event;
        if(event.which === 27) {
            this.hide();
        }
    }
    componentWillReceiveProps(newProps){
        this.recalculatePosition(newProps.width, newProps.height);
    }
    componentDidMount(){
        if(!this.props.hide){
            this.show();
        }
        window.addEventListener('keyup', this.onKeyUp);
        window.addEventListener('resize', this.recalculatePosition);
        this.recalculatePosition();
    }
    componentWillUnmount() {
        window.removeEventListener('keyup', this.onKeyUp);
        window.removeEventListener('resize', this.recalculatePosition);

        this._hide(true);
    }
    noHide = e=>{
        e.stopPropagation();
    }
    onScroll = event=>{
        let newEvent = new Event('scroll');
        window.dispatchEvent(newEvent);
    }
    render() {
        let props = this.props,
            state = this.state,
            baseClass = 'c-popup',
            className = [
                ['wid', true],
                [baseClass + '__popup', true],
                [props.className, props.className !== undefined],
                [baseClass + '__wide', props.wide !== undefined
                    && props.wide !== null
                    && props.wide !== false
                ]
            ].reduce((list, cur) => {
                list[cur[0]] = cur[1];
                return list;
            }, {}),
            style = {};

        if (state.width > 0) { style.width = state.width; }
        if (state.height > 0) { style.height = state.height; }

        return <RenderInBody
            body={this.getBody()}
            parent={props.parent}
            ix={props.DOMId}
            clsName={'popup-' + props.name}
        >
            {state.show && <div className={baseClass}>
                {props.useOverlay && <div className={baseClass+'__overlay'} />}
                <div
                    onScroll={this.onScroll}
                    className={baseClass+'__wrapper'}
                    onClick={this.hide}
                >
                    <div
                        className={getClasses(className)}
                        style={style}
                        onClick={this.noHide}
                    >
                        <div className={baseClass+'__message'}>{props.children}</div>
                        <span className={baseClass+'__ic-close'} onClick={this.hide} />
                    </div>
                    <div className='clear' />
                </div>
            </div>}
        </RenderInBody>;
    }
}
