/*
 * @Author: your name
 * @Date: 2022-04-11 17:24:29
 * @Description:
 * @FilePath: /zl-large-screen/src/components/LargeScreenBoard/index.tsx
 */

import React from 'react';
import LargeScreenBoardTitle from '../LargeScreenBoardTitle/index';
import LargeScreenBoardContent from '../LargeScreenBoardContent/index';

import {
  ILargeScreenBoardProps,
  ILargeScreenBoardState,
  IBoardTitleIcon,
  IDropItem,
  IBoardItem,
  IContent
} from '../../type/LargeScreenBoard';

import './style.scss';

let timer: any = null;
let fill = false; //填充状态

export const Board = React.createContext(null);

class LargeScreenBoard extends React.Component<
  ILargeScreenBoardProps,
  ILargeScreenBoardState
> {
  constructor(props) {
    super(props);
    const {
      layerList,
      contextMenus,
      leftIcons,
      rightIcons,
      fitBoard,
      operationMenus,
      zoomValue,
      zoomList,
      guidesData,
      groupMenus,
      mainBackgroundStyle,
      pageBackgroundStyle,
      uiBackgroundStyle,
      pageList,
      uiList,
      theme,
      isPreviewShow,
      isScreening,
      backgroundSize,
      uiStateOn,
      uiLayerList,
      scenceModelSrc,
      qiyong3D,
      pointEvent,
      ZLG,
      Line,
      Polygon,
      add3DType,
      add3DTypeList,
      layerDateTime,
      PointLayer,
      PopupLayer,
      Popup,
      changeSettingData,
      contextMenuId
    } = props;

    this.state = {
      leftIcons: leftIcons, //左侧按钮
      rightIcons: rightIcons, //右侧按钮
      fitBoard: fitBoard, //适应屏幕
      zoomList: zoomList, // 缩放列表
      guidesData: guidesData, // 参考线数据
      layerList: layerList, //图层数据
      operationMenus: operationMenus, //悬浮菜单数据
      boardList: [], // 元件数据
      UIBoardLists: [], // 系统ui元件数据
      boardMoveableList: [], // moveable框的数据（这一个主要是为了组的框选和点击）
      targetList: [], // moveable框的dom
      zoomValue: zoomValue, //缩放比例
      contextMenus: contextMenus, //右键菜单
      updateKey: true, // 更新moveable的key,
      groupMenus: groupMenus, //成组的右键菜单
      mainBackgroundStyle: mainBackgroundStyle, //背景颜色
      pageBackgroundStyle: pageBackgroundStyle, //背景颜色
      uiBackgroundStyle: uiBackgroundStyle, //背景颜色
      pageList: pageList, //页面数据
      uiList: uiList, //系统UI数据
      theme: theme, //当前事主题颜色
      isPreviewShow: isPreviewShow, //当前是否预览
      isScreening: isScreening, //当前是否截图
      backgroundSize: backgroundSize, //背景图的宽高
      uiStateOn: uiStateOn, //背景图的宽高
      uiLayerList: uiLayerList, //ui的图层数据
      scenceModelSrc: scenceModelSrc, //场景模型的地址
      qiyong3D: qiyong3D, //是否启用3D
      pointEvent: pointEvent, //3D页面的点击事件是否禁用
      ZLG: ZLG, //地图实例
      Line: Line, //线图层
      Polygon: Polygon, //面图层
      add3DType, // 当前3D编辑状态
      add3DTypeList, // 3D编辑状态列表
      layerDateTime: layerDateTime, // 日期时间
      changeSettingData: changeSettingData, // 修改样式方法
      PointLayer: PointLayer, //点图层
      PopupLayer: PopupLayer, //气泡图层
      Popup: Popup,
      contextMenuId: contextMenuId
    };
  }

  componentDidMount(): void {
    // 转换图层的数据给元件
    this.transAllData(this.props.layerList, false);
    this.transAllData(this.props.uiLayerList, true);

    this.resizeChange();
    window.addEventListener('resize', this.resizeChange);
  }

  // 图层数据变化时
  componentDidUpdate(prevProps, prevState) {
    if (this.props.layerList !== prevState.layerList) {
      // 转换图层的数据给元件
      this.transAllData(this.props.layerList, false);
    }
    if (this.props.mainBackgroundStyle !== prevState.mainBackgroundStyle) {
      this.setState({ mainBackgroundStyle: this.props.mainBackgroundStyle });
      // 重新计算缩放比例
      this.resizeChange();
    }
    if (this.props.pageBackgroundStyle !== prevState.pageBackgroundStyle) {
      this.setState({ pageBackgroundStyle: this.props.pageBackgroundStyle });
    }
    if (this.props.uiBackgroundStyle !== prevState.uiBackgroundStyle) {
      this.setState({ uiBackgroundStyle: this.props.uiBackgroundStyle });
    }
    if (this.props.uiList !== prevState.uiList) {
      this.setState({ uiList: this.props.uiList });
    }
    if (this.props.uiStateOn !== prevState.uiStateOn) {
      this.setState({ uiStateOn: this.props.uiStateOn });
      // 重新计算缩放比例
      this.resizeChange();
    }
    if (this.props.pageList !== prevState.pageList) {
      this.setState({ pageList: this.props.pageList });
    }
    if (this.props.isPreviewShow !== prevState.isPreviewShow) {
      this.setState({ isPreviewShow: this.props.isPreviewShow });
    }
    if (this.props.isScreening !== prevState.isScreening) {
      this.setState({ isScreening: this.props.isScreening });
    }
    if (this.props.backgroundSize !== prevState.backgroundSize) {
      this.resizeChange();
      this.setState({ backgroundSize: this.props.backgroundSize });
    }
    if (this.props.uiLayerList !== prevState.uiLayerList) {
      // 转换图层的数据给元件
      this.transAllData(this.props.uiLayerList, true);
    }
    if (this.props.scenceModelSrc !== prevState.scenceModelSrc) {
      this.setState({ scenceModelSrc: this.props.scenceModelSrc });
    }
    if (this.props.pointEvent !== prevState.pointEvent) {
      this.setState({ pointEvent: this.props.pointEvent });
    }
    if (this.props.qiyong3D !== prevState.qiyong3D) {
      this.setState({ qiyong3D: this.props.qiyong3D });
    }

    if (this.props.add3DType !== prevState.add3DType) {
      this.setState({ add3DType: this.props.add3DType });
    }
    if (this.props.add3DTypeList !== prevState.add3DTypeList) {
      this.setState({ add3DTypeList: this.props.add3DTypeList });
    }
    if (this.props.layerDateTime !== prevState.layerDateTime) {
      this.setState({ layerDateTime: this.props.layerDateTime });
    }
    if (this.props.changeSettingData !== prevState.changeSettingData) {
      this.setState({ changeSettingData: this.props.changeSettingData });
    }
    if (this.props.hoverElement !== prevState.hoverElement) {
      this.setState({ hoverElement: this.props.hoverElement });
    }
    if (this.props.contextMenus !== prevState.contextMenus) {
      this.setState({ contextMenus: this.props.contextMenus });
    }
    if (this.props.fitBoard !== prevState.fitBoard) {
      this.resizeChange();
      this.setState({ fitBoard: this.props.fitBoard });
    }
    if (this.props.contextMenuId !== prevState.contextMenuId) {
      this.setState({ contextMenuId: this.props.contextMenuId });
    }
  }

  componentWillUnmount(): void {
    window.removeEventListener('resize', this.resizeChange);
  }

  // 转换图层数据到元件列表和moveable列表
  transAllData = (list: IContent[], isUI: boolean) => {
    // 转换图层的数据给元件
    let oldData = [];
    oldData = this.transData(list, oldData);
    // if(isUI){
    //     this.setState({ UIBoardLists: oldData, uiLayerList: list });
    // }else{
    //   this.setState({ boardList: oldData, layerList: list });
    // }
    // 转换图层的数据给moveable
    let boardArr = []; // 可拖动的数组
    let keysList = []; // 可拖动的数组的 key
    // 如果是单个元件，直接push。如果是组，不管嵌套几层，扁平化成为一个数组
    Array.isArray(list) &&
      list?.length > 0 &&
      list.forEach((element) => {
        if (element?.elementInfo) {
          boardArr.push({
            key: element?.key,
            selected: element?.selected,
            status: element?.status,
            layerIndex: element?.layerIndex,
            elementIndex: element?.elementIndex,
            ...element,
            ...element.elementInfo
          });
          keysList.push(element?.key);
        } else if (element?.children?.length > 0) {
          let boardChildren = [];
          let keyChildren = [];
          boardChildren = this.transData(element?.children, boardChildren);
          if (boardChildren.length > 0) {
            boardChildren.forEach((item) => {
              keyChildren.push(item?.key);
            });
          }

          keysList.push(keyChildren);

          boardArr.push({
            key: element?.key,
            selected: element?.selected,
            status: element?.status,
            layerIndex: element?.layerIndex,
            elementIndex: element?.elementIndex,
            children: boardChildren,
            ...element,
            ...element.elementInfo
          });
        }
      });
    if (isUI) {
      this.setState({
        UIBoardLists: oldData,
        uiLayerList: list,
        boardMoveableList: this.props.uiStateOn
          ? boardArr
          : this.state.boardMoveableList,
        targetList: this.props.uiStateOn ? keysList : this.state.targetList
      });
    } else {
      this.setState({
        boardList: oldData,
        boardMoveableList: boardArr,
        layerList: list,
        targetList: keysList
      });
    }
  };

  // 转换图层的数据给元件
  transData = (layerList: IContent[], oldData: IContent[]) => {
    if (Array.isArray(layerList)) {
      layerList.forEach((element) => {
        if (element?.elementInfo) {
          oldData.push({
            key: element?.key,
            selected: element?.selected,
            status: element?.status,
            layerIndex: element?.layerIndex,
            elementIndex: element?.elementIndex,
            ...element,
            ...element.elementInfo
          });
        } else if (element?.children?.length > 0) {
          this.transData(element?.children, oldData);
        }
      });
    }
    return oldData;
  };

  // 窗口变化画布适应-适应
  resizeChange = () => {
    let dom: any = document.getElementById('contentBox') || null;
    // TODO 需要改成传入
    let realW: number = this.state.mainBackgroundStyle?.backgroundData
      ?.width as number;
    let realH: number = this.state.mainBackgroundStyle?.backgroundData
      ?.height as number;
    // 间距误差0-(向下取整舍去1% + 可能出现的滚动条8px)
    let visualW: number = dom?.clientWidth - 8 || realW;
    let visualH: number = dom?.clientHeight - 8 || realH;
    let scaleX: number = visualW / realW;
    let scaleY: number = visualH / realH;

    let finalScale: number;
    let rate: number;
    let scale: number;

    // finalScale = Math.min(scaleX, scaleY);
    if (fill) {
      finalScale = realW / realH / (visualW / visualH) < 1 ? scaleX : scaleY;
      fill = false;
    } else {
      finalScale = realW / realH / (visualW / visualH) > 1 ? scaleX : scaleY;
    }

    rate = Math.floor(finalScale * 100);
    scale = parseFloat(Number(rate * 0.01).toFixed(2));
    if (rate > 300) {
      rate = 300;
      scale = 3;
    }

    if (rate < 10) {
      rate = 10;
      scale = 0.1;
    }

    this.setState({ zoomValue: scale });
    this.props.boardEvent('zoomChange', { zoomValue: scale });
  };

  // title icon click
  iconClick = (item: IBoardTitleIcon) => {
    this.setState({ updateKey: true }); // 对齐需要刷新moveable
    this.props.boardEvent('boardIconClick', { item });
  };

  // 缩放调整
  zoomChange = (value: number | string) => {
    // 适应屏幕
    if (value === 'fit') {
      this.resizeChange();
    } else if (value === 'fill') {
      fill = true;
      this.resizeChange();
    } else {
      this.setState({ zoomValue: value as number });
      this.props.boardEvent('zoomChange', { zoomValue: value });
    }
  };

  // 预览
  preview = () => {
    this.props.boardEvent('preview', {});
  };

  // 放置
  dragEnd = (item: IDropItem, xY: { x: number; y: number }) => {
    this.props.boardEvent('addElement', { item, xY });
  };

  // 当前选中
  changeCurrent = (type, items: IBoardItem[]) => {
    this.props.boardEvent(type, { items });
  };

  // 点击画板
  boardClick = (e) => {
    this.props.boardEvent('boardClick', e);
  };

  // 画板鼠标按下
  boardMouseDown = (e) => {
    this.props.boardEvent('boardMouseDown', e);
  };

  // 当前选中元素或组
  elementClick = ({ type, e, item }) => {
    this.props.boardEvent('elementClick', { type, e, item });
  };

  // 右键菜单事件
  contextMenusEvent = (key, valueInfo) => {
    this.props.boardEvent('contextMenusEvent', key, valueInfo);
  };

  // 恢复updatekey的值
  changeUpdateKey = () => {
    this.setState({ updateKey: false });
  };

  // 参考线事件
  guidesChange = (props) => {
    this.props.boardEvent('guidesChange', props);
  };

  render() {
    return (
      <Board.Provider
        value={{
          leftIcons: this.state.leftIcons,
          rightIcons: this.state.rightIcons,
          fitBoard: this.state.fitBoard,
          operationMenus: this.state.operationMenus,
          boardList: this.state.boardList,
          UIBoardLists: this.state.UIBoardLists, // UI的元素
          boardMoveableList: this.state.boardMoveableList,
          targetList: this.state.targetList,
          zoomValue: this.state.zoomValue,
          zoomList: this.state.zoomList,
          zoomChange: this.zoomChange,
          guidesData: this.state.guidesData,
          guidesChange: this.guidesChange,
          preview: this.preview,
          dragEnd: this.dragEnd,
          changeCurrent: this.changeCurrent,
          boardClick: this.boardClick,
          boardMouseDown: this.boardMouseDown,
          elementClick: this.elementClick,
          contextMenus: this.state.contextMenus,
          contextMenusEvent: this.contextMenusEvent,
          boardEvent: this.props.boardEvent,
          updateKey: this.state.updateKey,
          changeUpdateKey: this.changeUpdateKey,
          groupMenus: this.state.groupMenus,
          mainBackgroundStyle: this.state.mainBackgroundStyle,
          pageBackgroundStyle: this.state.pageBackgroundStyle,
          uiBackgroundStyle: this.state.uiBackgroundStyle,
          pageList: this.state.pageList,
          uiList: this.state.uiList, // UI的页元素
          theme: this.state.theme,
          isPreviewShow: this.state.isPreviewShow,
          isScreening: this.state.isScreening,
          backgroundSize: this.state.backgroundSize,
          uiStateOn: this.state.uiStateOn,
          uiLayerList: this.state.uiLayerList,
          scenceModelSrc: this.state.scenceModelSrc,
          pointEvent: this.state.pointEvent,
          qiyong3D: this.state.qiyong3D,
          ZLG: this.state.ZLG,
          Line: this.state.Line,
          Polygon: this.state.Polygon,
          add3DType: this.state.add3DType,
          add3DTypeList: this.state.add3DTypeList,
          layerDateTime: this.state.layerDateTime,
          changeSettingData: this.state.changeSettingData,
          hoverElement: this.state.hoverElement,
          PointLayer: this.state.PointLayer,
          PopupLayer: this.state.PopupLayer,
          Popup: this.state.Popup,
          contextMenuId: this.state.contextMenuId
        }}
      >
        <div className="zl-ls-board">
          {(Array.isArray(this.state.leftIcons) &&
            this.state.leftIcons?.length > 0) ||
          (Array.isArray(this.state.rightIcons) &&
            this.state.rightIcons?.length > 0) ? (
            <LargeScreenBoardTitle click={this.iconClick} />
          ) : null}
          <LargeScreenBoardContent />
        </div>
      </Board.Provider>
    );
  }
}

export default LargeScreenBoard;
