import React from 'react';
import ReactDOM from 'react-dom';
import MaskLayer from 'react-mask-layer';
import { Icon } from '../../components/mxa';
import { trimStart } from '../utils/StringUtils';
import exclusive from './exclusive';
import { PFetch } from '../system/fetch';
import { longRunExec } from '../system/longRunOpt';
import { PAGE_TYPE_DETAIL, PAGE_TYPE_SUMMARY, PAGE_TYPE_SUMMARY_LIST, PAGE_TYPE_LIST } from '../constant/dictActions';
import { composePage } from './index';
import { addEventToBlurForm, removeEventToBlurForm } from '../utils/EventUtils';

// TODO: delete later
export const closeBar = (cb, title) => (
  <div className="title-bar">
    <span>{title}</span>
    <a onClick={cb}><Icon type="close" /></a>
  </div>
);

const getUrlPath = url => url;

const showModal = (params = {}, domainType, domainLink, callback, extraData) => {
  const maskDiv = document.createElement('div');
  document.body.appendChild(maskDiv);

  const _close = () => {
    const unmountResult = ReactDOM.unmountComponentAtNode(maskDiv);
    if (unmountResult) {
      maskDiv.parentNode.removeChild(maskDiv);
    }
  };

  const _modalCallback = (value, selectType, mainEntityKey) => {
    _close();
    callback && callback(value, selectType, mainEntityKey);
  };

  const self = {};
  const ModalPage = composePage();
  const windowHeight = window.innerHeight;
  // TODO: refactor
  const modalDecorator = Wrapper => {
    class MyMaskLayer extends React.Component {

      constructor(props) {
        super(props);
        this.refStr = 'modal-pop-' + new Date().getTime();
        this.isMoving = false;
        this.clientX = 0;
        this.clientY = 0;
        // 这样 body 只会构建一次
        let Body = null;
        if (this.props.body) {
          Body = this.props.body;
          Body = <Body callback={_modalCallback} createBottomButtons={this._createBottomButtons} />;
        }
        this.state = {
          bottomButtons: null,
          body: Body || (
            <div className="loading">
              <Icon type="loading" />
            </div>
          ),
        };
      }

      _getTag = cssSelector => {
        if (!cssSelector) {
          return document.querySelector('.' + this.refStr);
        }
        return document.querySelector('.' + this.refStr + ' ' + cssSelector);
      };

      _createModal = dataSource => {
        const maskLayerBody = (
          <ModalPage
            target={() => self.container}
            query={params} // query
            dataSource={dataSource}
            isModal={true}
            modalCallback={_modalCallback}
            domainType={domainType}
            domainLink={domainLink}
            onRefresh={params.onRefresh}
            isModalInput={params.isModalInput}
            createModalButtons={(domainType === PAGE_TYPE_DETAIL || domainType === PAGE_TYPE_SUMMARY) ? this._createBottomButtons : null}
            closeModal={_close}
            refStr={this.refStr}
            resetPosition={this._resetPosition}
            initWrapperHeight={this._initWrapperHeight}
            bodyAutoScroll={this._bodyAutoScroll}
            extraData={extraData}
          />
        );
        this.setState({
          body: maskLayerBody,
        });
      };

      componentDidMount() {
        addEventToBlurForm(document.querySelector('.modal-content-detail'));
        this._resetPosition();
        if (domainLink && !exclusive.some(f => f(domainLink))) {
          const url = getUrlPath(trimStart(domainLink, '/'));
          longRunExec(() => PFetch(url, params)
            .then(data => {
              this._createModal(data);
            }));
        }
      }

      componentWillUnmount() {
        removeEventToBlurForm(document.querySelector('.modal-content-detail'));
      }

      _resetPosition = () => {
        const tag = this._getTag();
        /* eslint-disable */
        const modalBody = window.getComputedStyle(tag.childNodes[0]);
        const modalHeight = modalBody.height.substring(0, modalBody.height.length - 2);
        tag.style.top = (window.innerHeight - parseInt(modalHeight))/2 + 'px';
      };

      componentDidUpdate() {
        setTimeout(() => this._resetPosition());
      }

      //TODO: refactor
      _closeBar = (cb, title) => {
        const event = {
          onMouseDown: (e) => {
            this.isMoving = true;
            const tag = window.getComputedStyle(this._getTag());
            this.tagX = tag.left.substring(0, tag.left.length - 2);
            this.tagY = tag.top.substring(0, tag.top.length - 2);
            this.clientX = e.clientX;
            this.clientY = e.clientY;
          },
          onMouseMove: (e) => {
            if (this.isMoving) {
              const tag = this._getTag();
              tag.style.left = Number(this.tagX) + e.clientX - this.clientX + 'px';
              tag.style.top = Number(this.tagY) + e.clientY - this.clientY + 'px';
            }
          }
        };

        event.onMouseUp = event.onMouseOut = (e) => {
          this.isMoving = false;
        };
        return (
          <div className="title-bar" {...event}>
            <span>{title}</span>
            <a onClick={cb}><Icon type="close" /></a>
          </div>
        );
      };

      _createBottomButtons = (data) => {
        this.setState({
          bottomButtons: data
        });
      };

      _initWrapperHeight = (height) => {
        const tag = this._getTag('.modal-content-detail');
        if (height > windowHeight * 0.7) {
          height = windowHeight * 0.7;
        }
        tag && (tag.style.minHeight = height + 'px');
      };

      _bodyAutoScroll = () => {
        const tag = this._getTag(".modal-content-detail");
        tag && (tag.scrollTop = tag.scrollHeight - tag.clientHeight);
      };

      render() {
        let modalMaxHeight;
        let modalContentClassName = 'modal-content-detail';
        if (domainType === PAGE_TYPE_SUMMARY_LIST || domainType === PAGE_TYPE_LIST) {
          modalMaxHeight =  windowHeight * 0.7;
          modalContentClassName = 'modal-content-list';
        }
        return (
          <Wrapper maskTransitionName="" className={this.refStr} prefixCls="mx-mask-self" visible={true} style={{ left: '25%', height: modalMaxHeight }} onCancel={_close} zIndex="999" maskClosable={false}>
            <div style={{ width: '100%', overflow: 'hidden', height: '100%', position: 'relative' }}>
              {this._closeBar(_close, params && params.modalTitle)}
              <div style={{ maxHeight: windowHeight * 0.7, height: '100%' }} className={modalContentClassName} ref={node => { self.container = node; }}>
                <div className="modal-content-body">
                  {this.state.body}
                </div>
                {this.state.bottomButtons && (
                  <div className="pop-bottom-btns" style={{ position: 'absolute', bottom: 0, width: '100%' }}>
                    <div className="pop_up_button">
                      {this.state.bottomButtons}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </Wrapper>
        );
      }
    }
    return MyMaskLayer;
  };

  const MaskModal = modalDecorator(MaskLayer);
  ReactDOM.render(
    <MaskModal body={params.body}/>,
    maskDiv
  );
};

// const showModal = (params, domainType, domainLink, callback) => {
//  if (domainLink && !exclusive.some(f => f(domainLink))) {
//    const url = getUrlPath(trimStart(domainLink, '/'));
//    longRunExec(() => PFetch(url, params)
//      .then(data => {
//        createModal(params, domainType, domainLink, callback, data);
//      }));
//  } else {
//    createModal(params, domainType, domainLink, callback);
//  }
// };

// eslint-disable-next-line import/prefer-default-export
export { showModal };

