import React, { Component } from 'react';
import { createPortal } from 'react-dom';
import Mousetrap from 'mousetrap';
import style from './SearchModal.less';
import EasyvSpin from 'components/EasyvSpin';
import classname from 'classnames';
import defaultImg from 'images/default.png';
import { withRouter } from 'react-router-dom';
import Thumb from 'components/Thumb';
import message from 'components/message';
import { getAssetsUrl } from 'utils/utils';

const imgFullPath = (path) => (path ? getAssetsUrl(`${path}`) : defaultImg);

class Portal extends Component<{ top: string; root?: HTMLElement; onClose: () => void }> {
  div: HTMLDivElement;
  container: HTMLDivElement;
  root: any;
  constructor(props) {
    super(props);
    this.div = document.createElement('div');
    this.div.style.top = 'top' in props ? props.top : '50%';
    this.div.style.left = '50%';
    this.div.style.position = 'absolute';
    this.div.style.transform = `translate(-50%, ${'top' in props ? 0 : '-50%'})`;

    this.container = document.createElement('div');
    this.container.style.position = 'fixed';
    this.container.style.width = '100%';
    this.container.style.height = '100%';
    this.container.style.left = '0';
    this.container.style.top = '0';
    this.container.style['z-index'] = 20;
    this.container.appendChild(this.div);
    this.container.addEventListener('click', this.onClick);
    this.root = this.props.root || document.body;
  }
  componentDidMount() {
    document.body.appendChild(this.container);
    window.addEventListener('keydown', this.onEsc);
  }
  componentWillUnmount() {
    this.container.removeEventListener('click', this.onClick);
    document.body.removeChild(this.container);
    window.removeEventListener('keydown', this.onEsc);
  }

  onEsc = (e) => {
    // esc
    if (e.keyCode === 27) {
      const { onClose } = this.props;
      onClose && onClose();
    }
  };

  onClick = (e) => {
    const { onClose } = this.props;
    if (e.target === this.container && onClose) onClose();
  };

  render() {
    const { children } = this.props;
    return createPortal(children, this.div);
  }
}

class SearchModal extends Component<any> {
  state = {
    visible: false,
    text: '',
    loading: false
  };

  componentDidMount() {
    Mousetrap.bind(['command+f', 'ctrl+f'], (e) => {
      if (!this.state.visible) {
        e.preventDefault();
        this.showModal();
      }
    });
  }

  componentDidUpdate() {
    // loading
    // 数据请求完毕
    // 条件满足
    this.state.loading &&
      this.setState({
        loading: false
      });
  }

  componentWillUnmount() {
    Mousetrap.unbind(['command+f', 'ctrl+f']);
  }

  showModal = () => {
    this.setState({
      visible: true
    });
  };

  hideModal = () => {
    this.setState({
      visible: false,
      text: '',
      loading: false
    });
  };

  onClick = ({ data }) => {
    // 新增
    const { canvas, setCurrentNode, nodeScale = 1 } = this.props;
    const node = canvas?.getNode(data.id);
    if (node) {
      const { positionAbsolute, width, height } = node;
      const { x, y } = positionAbsolute;
      canvas?.fitBounds(
        {
          x,
          y,
          width,
          height
        },
        {
          padding: nodeScale,
          duration: 300
        }
      );
      this.props.clearCurrentNode();
      setCurrentNode(data.id);
    } else {
      message.error('未找到节点');
      console.error(`节点ID<${data.id}>，未找到`);
    }
    this.hideModal();
  };

  render() {
    const { children, node = {} } = this.props;
    const { nodes = [] } = node;
    // eslint-disable-next-line prefer-const
    let { visible, text, loading } = this.state;

    const foundResult: any = [];
    text = text.trim().toLowerCase();
    if (text.length) {
      const foundModules = nodes
        .filter((item) => ~item.name.toLowerCase().indexOf(text) || ~item.id.toLowerCase().indexOf(text))
        .map((item) => ({ id: (item.id + '').replace(/(.*)Card-/, ''), name: item.name, image: imgFullPath(item.thumb), data: item }));
      foundModules.length && foundResult.push({ title: '现有节点', list: foundModules });
    }

    return (
      <span>
        <span onClick={this.showModal}>
          <EasyvSpin loading={loading}>{children}</EasyvSpin>
        </span>
        {visible && (
          <Portal onClose={this.hideModal} top="92px">
            <div className={classname(style['search-container'])}>
              <div className={classname(style['search-input'], { [style['search-input--conn']]: text && !foundResult.length })}>
                <i className={classname('icon iconfont icon-a-Search2x', style['search-input__icon'])} />
                <input
                  placeholder="输入名称或ID搜索节点"
                  ref={(el) => setTimeout(() => el && el.focus(), 0)}
                  onChange={(e) => this.setState({ text: e.target.value })}
                />
              </div>
              {text && <SearchList list={foundResult} onClick={this.onClick} />}
            </div>
          </Portal>
        )}
      </span>
    );
  }
}

function SearchList({ list, onClick }) {
  return (
    <div className={classname(style['search-list'], { [style['serach-list--empty']]: !list.length })}>
      {!list.length && '未找到相应元素'}
      {list.reduce((acc, group, index) => {
        acc.push(
          <div className={style['search-list__title']} key={'title_' + index}>
            {group.title}
          </div>
        );
        group.list.forEach((item, x) => {
          acc.push(
            <div key={index + '_' + x} className={style['search-item']} onClick={() => onClick(item)}>
              <Thumb className={style['search-item__pic']} src={item.image} />
              {item.name}
              {item.id && <span>-{item.id}</span>}
            </div>
          );
        });
        return acc;
      }, [])}
    </div>
  );
}

export default withRouter(SearchModal);
