import React from 'react';
import { Row, Col, Breadcrumb, Select, Typography, List } from 'antd';
import { HomeOutlined } from '@ant-design/icons';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
import VList from 'react-virtualized/dist/commonjs/List';
import InfiniteLoader from 'react-virtualized/dist/commonjs/InfiniteLoader';

import SquareItem from './Component/SquareItem';
import Org from './Component/Org';
import Tree from './Component/Tree';
import Relation from './Component/Relation';
import { dispatch, dispatchLatest } from '../../../model';

const column = 4;
const defaultLoadCount = 10;

class MapContent extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      curTableModelData: null,
      orgModelData: null,
      orgChildData: null,
      treeModelData: null,
      treeChildData: null,
      relationModelData: null,
      relationChildData: null,
      parentNodeId: null,
      breadcrumbContents: null,
      currentLevel: -1,
      totalLevel: 1,
      haveMoreData: false,
    };
  }

  loadedRowsMap = {};

  componentDidMount() {
    this.getTreeTotalLevelThenQueryAllDirectoryAsTreeByDirLevel();
  }

  componentDidUpdate(prevProps, prevState) {
    const { type, topic } = this.props;
    const { currentLevel } = this.state;

    if (topic !== prevProps.topic) {
      this.setState({ curTableModelData: [], parentNodeId: null, orgModelData: null, treeModelData: null, relationModelData: null }, () => {
        this.getTreeTotalLevelThenQueryAllDirectoryAsTreeByDirLevel();
      })
    } else if (type !== prevProps.type) {
      this.setState({ parentNodeId: null, orgModelData: null, treeModelData: null, relationModelData: null }, () => {
        if (type !== 'square') {
          this.getTreeTotalLevelThenQueryAllDirectoryAsTreeByDirLevel(false, currentLevel);
        }
      });
    }
  }

  getTreeTotalLevelThenQueryAllDirectoryAsTreeByDirLevel = (first=true, defaultCurrentLevel=-1) => {
    const { topic } = this.props;

    dispatch({
      type: 'map.getTreeTotalLevel',
      payload: { dirId: topic.id },
      callback: data => {

        const _totalLevel = Number(data);
        const _currentLevel = (defaultCurrentLevel===-1) ? (_totalLevel < 3 ? _totalLevel : 3) : defaultCurrentLevel;

        this.setState({ totalLevel: _totalLevel, currentLevel: _currentLevel }, () => {
          this.queryAllDirectoryAsTreeByDirLevel(first, _currentLevel - 1);
        });
      }
    })
  }

  queryAllDirectoryAsTreeByDirLevel = (first, level) => {
    const { topic } = this.props;

    dispatchLatest({
      type: 'map.queryAllDirectoryAsTreeByDirLevel',
      payload: { 
        dirId: topic.id, 
        dirLevel: level,
        topNum: defaultLoadCount 
      },
      callback: data => {

        const _treeData = {
          text: topic.name || '',
          name: topic.name || '',
          dirId: topic.id,
          id: `d${topic.id}`,
          dbType: 'Dir',
          children: (data||[]).length===0 ? null : data
        };

        this.convertRemoteData(_treeData.children||[], _treeData.id, _treeData.dirId);

        const _curTableModelData = (_treeData.children||[]).filter(item => item.dbType!=='More');

        if (first) {
          this.loadedRowsMap = {};

          this.setState({
            curTableModelData: _curTableModelData,
            breadcrumbContents: [{ data: _treeData }],
            haveMoreData: (_curTableModelData||[]).length===defaultLoadCount,
            //深拷贝 
            orgModelData: JSON.parse(JSON.stringify(_treeData)),
            treeModelData: JSON.parse(JSON.stringify(_treeData)),
            relationModelData: JSON.parse(JSON.stringify(_treeData))
          });
        } else {
          this.setState({
            orgModelData: JSON.parse(JSON.stringify(_treeData)),
            treeModelData: JSON.parse(JSON.stringify(_treeData)),
            relationModelData: JSON.parse(JSON.stringify(_treeData))
          });
        }
      }
    })
  }

  convertRemoteData = (data, pid, pDirId, start=0) => {
    data.forEach((item, index) => {

      item.pid = pid||'';
      item.pDirId = pDirId||'';
      item.index = (index+start);

      if (item.dbType === 'Dir') {
        item.text = item.name = item.dirName || '';
        item.id = `d${pDirId}${item.dirId || ''}${index}`;
      } else if (item.dbType === 'Table') {
        item.text = item.name = item.cnName || '';
        item.tid = item.id||'';
        item.id = `t${pDirId}${item.id || ''}${index}`;
      }

      if (index === defaultLoadCount) {
        item.text = item.name = '点击加载更多';
        item.dbType = 'More';
      }

      if (item.children) {
        this.convertRemoteData(item.children, item.id, item.dirId);
      }
    })
  }

  handleInfiniteOnLoad = ({ startIndex, stopIndex }) => {
    const { haveMoreData, curTableModelData } = this.state;
    
    for (let i = startIndex; i <= stopIndex; i++) {
      this.loadedRowsMap[i] = 1;
    }

    if (haveMoreData) {

      const lastItem = curTableModelData[curTableModelData.length-1];

      dispatchLatest({
        type: 'map.getTableModelInfoByDirIdAndBeginIndex',
        payload: { 
          dirId: lastItem.pDirId,
          beginIndex: Number(lastItem.index)+2,
          topNum: defaultLoadCount 
        },
        callback: data => {
          this.convertRemoteData(data||[], '', lastItem.pDirId, Number(lastItem.index)+1);
          const _data = (data||[]).filter(item => item.dbType!=='More');

          this.setState({ 
            curTableModelData: [...curTableModelData, ...(_data||[])],
            haveMoreData: (_data||[]).length===defaultLoadCount,
          });
        }
      })
    }
  };

  isRowLoaded = ({ index }) => !!this.loadedRowsMap[index];

  onSquareItemClick = (item) => {
    const { breadcrumbContents } = this.state;

    dispatchLatest({
      type: 'map.getTableModelByDirIid',
      payload: { 
        dirId: item.dirId,
        topNum: defaultLoadCount 
      },
      callback: data => {

        this.loadedRowsMap = {};
        this.convertRemoteData(data || [], item.id, item.dirId);
        item.children = (data || []).filter(item => item.dbType!=='More');
        this.setState({ curTableModelData: [] }, () => {
          this.setState({
            breadcrumbContents: [...breadcrumbContents, { name: item.dirName || '', data: item }],
            curTableModelData: item.children || [],
            haveMoreData: (item.children||[]).length===defaultLoadCount,
          });
        })
      }
    })
  }

  onBreadcrumbItemClick = (content, index) => {
    const { breadcrumbContents } = this.state;

    this.loadedRowsMap = {};

    this.setState({
      breadcrumbContents: breadcrumbContents.splice(0, index === 0 ? 1 : (index + 1)),
      curTableModelData: []
    }, () => {
      const item = content.data;
      dispatchLatest({
        type: 'map.getTableModelByDirIid',
        payload: { 
          dirId: item.dirId,
          topNum: defaultLoadCount 
        },
        callback: data => {
  
          this.convertRemoteData(data || [], item.id, item.dirId);
          item.children = (data || []).filter(item => item.dbType!=='More');
          this.setState({
            curTableModelData: item.children || [],
            haveMoreData: (item.children||[]).length===defaultLoadCount,
          });
        }
      })
    })
  }

  loadSubLeafData = (dirId, nodeId) => {
    this.setState({ parentNodeId: '' }, () => {
      dispatchLatest({
        type: 'map.getTableModelByDirIid',
        payload: { 
          dirId,
          topNum: defaultLoadCount  
        },
        callback: data => {
          this.convertRemoteData(data||[], nodeId, dirId);
          this.setState({
            parentNodeId: nodeId,
            orgChildData: JSON.parse(JSON.stringify(data || [])),
            treeChildData: JSON.parse(JSON.stringify(data || [])),
            relationChildData: JSON.parse(JSON.stringify(data)),
          });
        }
      })
    })
  }

  loadMoreLeafData = (dirId, nodeId, start) => {
    this.setState({ parentNodeId: '' }, () => {
      dispatchLatest({
        type: 'map.getTableModelInfoByDirIdAndBeginIndex',
        payload: { 
          dirId,
          beginIndex: Number(start)+1,
          topNum: defaultLoadCount 
        },
        callback: data => {
          this.convertRemoteData(data||[], nodeId, dirId, start);
          this.setState({
            parentNodeId: nodeId,
            orgChildData: JSON.parse(JSON.stringify(data || [])),
            treeChildData: JSON.parse(JSON.stringify(data || [])),
            relationChildData: JSON.parse(JSON.stringify(data)),
          });
        }
      })
    })
  }

  onLevelChange = (value) => {
    this.setState({ currentLevel: value, parentNodeId: null, orgModelData: null, treeModelData: null, relationModelData: null }, () => {
      this.queryAllDirectoryAsTreeByDirLevel(false, value - 1);
    });
  }

  onAssetClick = (id) => {

  }

  renderItem = ({ index, key, style }) => {
    const { curTableModelData } = this.state;
    const group = curTableModelData.slice(index*column, index*column+column);
    return (
      <List.Item key={key} style={style}>
        <div style={{ width: '100%' }}>
        <Row gutter={30} style={{ padding: '0 2px' }}>
          {
            group && group.map((item, index) => {
              return (
                <Col key={index} span={24 / column}
                >
                  <SquareItem item={item} onClick={this.onSquareItemClick} {...this.props} />
                </Col>
              )
            })
          }
        </Row>
        </div>
      </List.Item>
    );
  };

  render() {
    const { type, switchMode } = this.props;
    const { curTableModelData, breadcrumbContents, orgModelData, treeModelData, relationModelData, orgChildData, treeChildData, relationChildData, parentNodeId, currentLevel, totalLevel } = this.state;

    let groups = [];
    if (curTableModelData) {
      for (var i = 0; i < curTableModelData.length; i += column) {
        groups.push(curTableModelData.slice(i, i + column));
      }
    }

    if (type === 'square') {
      return (
        <div className='p-3' style={{ height: '100%', backgroundColor: '#fff' }}>
          {
            type === 'square' && <>
              <div className="flex mb-3">
                <div className='flex-auto'>
                  {
                    breadcrumbContents && breadcrumbContents.length > 0 && <Breadcrumb >
                      {
                        breadcrumbContents.map((content, index) => {
                          return (
                            <Breadcrumb.Item key={index}>
                              {
                                index === 0 ? <HomeOutlined onClick={() => { this.onBreadcrumbItemClick(content, index); }} /> : ((index === breadcrumbContents.length - 1) ? <span>{content.name || ''}</span> : <span className='pointer' onClick={() => { this.onBreadcrumbItemClick(content, index); }}>
                                  {content.name || ''}
                                </span>)
                              }
                            </Breadcrumb.Item>
                          )
                        })
                      }
                    </Breadcrumb>
                  }
                </div>
                <div className="flex">
                  {switchMode}
                </div>
              </div>
              {
                (curTableModelData||[]).length>0 && <InfiniteLoader
                  isRowLoaded={this.isRowLoaded}
                  loadMoreRows={this.handleInfiniteOnLoad}
                  rowCount={groups.length}>
                  {({onRowsRendered, registerChild}) => (
                    <AutoSizer>
                      {({width, height}) => (
                        <VList
                          ref={registerChild}
                          height={height - 34}
                          onRowsRendered={onRowsRendered}
                          rowCount={groups.length}
                          rowHeight={134}
                          rowRenderer={this.renderItem}
                          width={width}
                        />
                      )}
                    </AutoSizer>
                  )}
                </InfiniteLoader>
              }
            </>
          }
        </div>
      );
    } else {
      return (
        <div className='position-relative' style={{ height: '100%', overflow: 'hidden', backgroundColor: '#fff'
        //backgroundImage: 'linear-gradient(to bottom left,#2e3b4e,#0d0d13 52%,#0d0d13)' 
        }}>
          {
            type === 'org' && <Org
              data={orgModelData}
              parentNodeId={parentNodeId}
              childData={orgChildData}
              loadMoreLeafData={this.loadMoreLeafData}
              loadSubLeafData={this.loadSubLeafData}
              onAssetClick={this.onAssetClick}
              styles={{ width: '100%', height: '100%' }}
            />
          }
          {
            type === 'tree' && <Tree
              data={treeModelData}
              parentNodeId={parentNodeId}
              childData={treeChildData}
              loadMoreLeafData={this.loadMoreLeafData}
              loadSubLeafData={this.loadSubLeafData}
              onAssetClick={this.onAssetClick}
              styles={{ width: '100%', height: '100%' }}
            />
          }
          {
            type === 'relation' && <Relation
              data={relationModelData}
              parentNodeId={parentNodeId}
              childData={relationChildData}
              loadMoreLeafData={this.loadMoreLeafData}
              loadSubLeafData={this.loadSubLeafData}
              onAssetClick={this.onAssetClick}
              styles={{ width: '100%', height: '100%' }}
            />
          }
          <div
            className='position-absolute text-right p-3'
            style={{
              display: 'block',
              right: 0,
              top: 0
            }}
          >
            {switchMode}
            <div className="mt-3">
              <Typography.Text className="mr-2" style={{ color: '#000' }}>层数</Typography.Text>
              {/* <Slider vertical min={1} max={totalLevel} value={currentLevel} onChange={this.onLevelChange} /> */}
              <Select value={currentLevel} onChange={this.onLevelChange} size="small">
                {Array.from(new Array(totalLevel)).map((_, i) => <Select.Option key={(i+1)} value={(i+1)}>{(i+1)}</Select.Option>)}
              </Select>
            </div>
          </div>


          {/* <div id="left-control-container"></div>
          <div id="right-control-container"></div>
          <div id="bottom-bg-container"></div> */}
        </div>
      )
    }


  }
}

export default MapContent;