import styles from './index.less';
import React, { useEffect, useState, useRef } from 'react';
import { OrgChartComponent } from '@/components/orgChart';
import * as d3 from 'd3';
import { TopBar } from '../components/topBar';
import ToolBar from '../components/toolBar';
import TimeLine from '../components/timeline';
import DrawerComponents from '../components/drawer';
import OperateDialog from '../components/dialog';
import jsPDF from 'jspdf';
import moment from 'moment';
import qs from 'qs';
import { message, Spin, notification } from 'antd';
import { SmileOutlined } from '@ant-design/icons';
import { getLabel } from '../util/i18n.js';

let active = 'top';
let drawerCom = null;
let operateCom = null;
let timeLine = null;
let orgChart = null;
let topbar = null;

export default function companyPage() {
  const [data, setData] = useState(null);
  let compact = 0;
  let expandAll = 0;

  const [sliderProgress, setSliderProgress] = useState(50);
  let addNodeChildFunc = null;
  let topBarSearchRequest = null;
  const [hasRight, setHasRight] = useState('');
  const [timelineId, setTimelineId] = useState(0);
  const infoRef = useRef();

  const [labelData, setLabelData] = useState({});
  const [lebelCompleted, setLabelCompleted] = useState(false);

  useEffect(() => {
    infoRef.current = timelineId;
  }, [timelineId]);

  const [spinning, setSpinning] = useState(false);

  // 点击节点
  const onNodeClick = (node) => {
    if (node.ftype == '2') {
      const params = {
        rootId: node.id,
        fclass: topbar.state.requestData.fclass,
        id: infoRef.current,
      };
      drawerCom.showDrawer(params);
    }
  };

  // 扩展按钮点击
  const onButtonClick = (event, d) => {
    if (d.children) {
      let idsList = [];
      d.children.forEach((item) => {
        if (item.data.hasChildren && !item._children) {
          idsList.push(item.data.id);
        }
      });

      if (idsList.length == 0) {
        return;
      }

      let idsStr = idsList.join(',');
      let api = '';
      if (topBarSearchRequest) {
        let request = { ...topBarSearchRequest, ids: idsStr };
        api =
          '/api/bs/hrmorganization/orgchart/asyncCompanyData' +
          qs.stringify(request, { addQueryPrefix: true });
      } else {
        let request = { ...topbar.state.requestData, ids: idsStr };
        api =
          '/api/bs/hrmorganization/orgchart/asyncCompanyData' +
          qs.stringify(request, { addQueryPrefix: true });
      }
      fetch(api)
        .then((res) => res.json())
        .then((data) => {
          if (data.data) {
            data.data.forEach((item) => {
              // window.chart.addNode(item);
              orgChart.addNode(item);
            });
          }
        });
    }
  };

  // 获取部门图片
  function getDepartmentImage(fisvitual) {
    return fisvitual == '0' ? `./img/back/level4.png` : `./img/back/level8.png`;
  }

  // 获取分部图片
  function getSubcompanyImage(fisvitual) {
    return fisvitual == '0' ? `./img/back/level1.png` : `./img/back/level5.png`;
  }

  // 多语言获取
  useEffect(() => {
    d3.json('/api/bs/hrmorganization/orgchart/i18n').then((res) => {
      setLabelData(res.data);
      setLabelCompleted(true);
      notification.open({
        message: `${getLabel(547283, res.data)}`,
        description: `${getLabel(547292, res.data)}`,
        icon: <SmileOutlined style={{ color: '#108ee9' }} />,
      });
    });
  }, []);

  // 获取数据
  useEffect(() => {
    if (lebelCompleted) {
      d3.json(
        '/api/bs/hrmorganization/orgchart/companyData?fclass=0&fisvitual=0&hidedept=0&root=0&level=2&id=0',
      ).then((data) => {
        setData(data.data);
        setHasRight(data?.hasRight);
      });
    }
  }, [lebelCompleted]);

  // ButtonContent渲染
  const buttonContentRender = ({ node, state }) => {
    if (node.children) {
      return `<div style="border-radius:3px;padding:3px;font-size:10px;margin:auto auto;background-color:#66BAF5"> <div style="margin-top:0px;line-height:1.35;height:11px;font-size:25px; color: #fff;">ˆ</div>  </div>`;
    } else {
      return `<div style="border-radius:3px;padding:3px;font-size:10px;margin:auto auto;background-color:#66BAF5"> <div style="margin-top:0px;line-height:1.35;height:11px;font-size:25px; color: #fff;transform:rotate(180deg)">ˆ</div>  </div>`;
    }
  };

  // 节点宽度渲染
  const nodeWidthRender = (d) => {
    if (d.data.ftype == 0) {
      return 220;
    } else if (d.data.ftype == 1) {
      return 144;
    } else if (d.data.ftype == 2) {
      return 144;
    }
    return 200;
  };

  const nodeHeightRender = (d) => {
    if (d.data.ftype == 0) {
      return 100;
    } else if (d.data.ftype == 1) {
      return 106;
    } else if (d.data.ftype == 2) {
      return 106;
    }
    return 120;
  };

  const nodeContentRender = (d, i, arr, state) => {
    let fclass = topbar.state.requestData.fclass;
    let statisticsStyle = fclass == 0 ? 'block' : 'none';
    if (d.data.ftype == 0) {
      return `<div style="text-align: center;">
          <div style="display: inline-block;  margin-left: 5px;">
            <div style="
              font-size: 24px;
              font-family: Microsoft YaHei-Bold, Microsoft YaHei;
              font-weight: bold;
              color: #000000;
              line-height: 28px;
              letter-spacing: 1px;
              margin-top: 10px;
            ">${d.data.fname}</div>
          </div>
        </div>`;
    } else if (d.data.ftype == 1) {
      return `<div style='position:absolute;height:100%'>
            <img style='width:144px;height:106px' src="${getSubcompanyImage(
              d.data.fisvitual,
            )}"/>
          </div>
          <div style="width: 144px;height: 80px;top: 35px;position: relative;font-weight: 400;font-size: 14px;
            font-family: Microsoft YaHei-Regular, Microsoft YaHei;color: #333333;text-align: center;"> 
             <div class="tooltip">
                <div class="tooltitle"> ${d.data.fname} </div>
                <div class="tooltiptext">${d.data.fname}</div>
            </div>

            <div style="display: ${statisticsStyle}">
                <span style="color:red">${d.data.staffNum}</span> /
                <span style="color:green">${d.data.onJobNum}</span>
            </div>
          </div>
        </div>
          `;
    } else if (d.data.ftype == 2) {
      return `
        <div style="width: 100%; height: 100%; background-size: 100% 100%;">
          <div style='position:absolute;height:100%'>
            <img style='width:144px;height:106px' src="${getDepartmentImage(
              d.data.fisvitual,
            )}"/>
          </div>
          <div style="width: 144px;height: 80px;top: 35px;position: relative;font-weight: 400;font-size: 14px;
            font-family: Microsoft YaHei-Regular, Microsoft YaHei;color: #333333;text-align: center;"> 
            <div class="tooltip">
                <div class="tooltitle"> ${d.data.fname} </div>
                <div class="tooltiptext">${d.data.fname}</div>
            </div>
            
            <div style="display: ${statisticsStyle}">
              <span style="color:red">${d.data.staffNum}</span> /
              <span style="color:green">${d.data.onJobNum}</span>
            </div>
          </div>
        </div>
        `;
    }
    return `<div>${d.data.fname}</div>`;
  };

  const handleTopLayoutClick = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    orgChart &&
      orgChart
        .layout('top')
        .setCentered(orgChart.getChartState().root.id)
        .render();
    active = 'top';
  };

  const handleLeftLayoutClick = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    orgChart &&
      orgChart
        .layout('left')
        .setCentered(orgChart.getChartState().root.id)
        .render();
    active = 'left';
  };

  const handleFullscreen = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    orgChart && orgChart.fullscreen('body');
  };

  const handleFit = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    orgChart && orgChart.fit();
  };

  const handleFolderAddNode = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    operateCom &&
      operateCom.showOperate(topbar.state.requestData.root, '新增节点', 1);
  };

  const addFolderNode = (id) => {
    orgChart &&
      orgChart.addNode({
        id: 'd_10091',
        fname: '测试增加节点',
        parentId: 's_10',
        ftype: '2',
      });
  };

  const handleDeleteNode = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    operateCom &&
      operateCom.showOperate(topbar.state.requestData.root, '删除节点', 2);
  };

  const deleteNode = (id) => {
    orgChart && orgChart.removeNode('d_10091');
  };

  const handleCompact = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    orgChart &&
      orgChart
        .compact(!!(compact++ % 2))
        .render()
        .fit();
  };

  const handleExpandAll = (progressBtn) => {
    progressBtn.current.style.top = 50 + 'px';
    orgChart && expandAll++ % 2 ? orgChart.collapseAll() : orgChart.expandAll();
  };

  const handleZoomIn = (progressBtn) => {
    if (progressBtn) {
      let top = parseInt(progressBtn.current.style.top) - 10;
      if (top >= 0) {
        progressBtn.current.style.top = top + 'px';
      } else {
        return;
      }
    }
    orgChart && orgChart.zoomIn();
  };

  const handleZoomOut = (progressBtn) => {
    if (progressBtn) {
      let top = parseInt(progressBtn.current.style.top) + 10;
      if (top <= 100) {
        progressBtn.current.style.top = top + 'px';
      } else {
        return;
      }
    }
    orgChart && orgChart.zoomOut();
  };

  const handleZoomBehavior = (value) => {
    orgChart && orgChart.zoomBehavior(value - 50);
  };

  function downloadPdf(chart) {
    chart.exportImg({
      save: false,
      full: true,
      onLoad: (base64) => {
        var pdf = new jsPDF();
        var img = new Image();
        img.src = base64;
        img.onload = function () {
          pdf.addImage(
            img,
            'JPEG',
            5,
            5,
            595 / 3,
            ((img.height / img.width) * 595) / 3,
          );
          pdf.save('chart.pdf');
        };
      },
    });
  }

  /**
   * 导出
   * @param {*} type
   */
  const handleExport = (type) => {
    if (type == 'png') {
      const hiddenElements = document.querySelectorAll('.tooltitle');
      const hiddenElementsArray = Array.from(hiddenElements);
      // 从 DOM 中移除隐藏内容
      hiddenElementsArray.forEach((el) => (el.style.display = 'none'));
      orgChart && orgChart.exportImg({ full: true });
    } else {
      orgChart && downloadPdf(orgChart);
    }
  };

  /**
   * 时间轴点击
   * @param {*} timeline
   */
  const timeLineSearch = (timeline) => {
    setTimelineId(timeline.id);
    const fclass = topbar.state.requestData.fclass;
    const resetParams = {
      root: undefined,
      level: '2',
      fisvitual: '0',
      hidedept: '0',
    };
    topbar.handleFormChange({ ...resetParams });
    topbar.getNodeTreeNode(
      `/api/bs/hrmorganization/orgchart/getSubCompanyTree?fclass=${fclass}&id=${timeline.id}`,
      false,
    );
    let requestData = { fclass: fclass, id: timeline.id, ...resetParams };
    handleSearch(requestData, false);
  };

  /**
   * 查询
   * @param {*} requestData
   */
  const handleSearch = (requestData, cache = true) => {
    setSpinning(true);
    if (cache) {
      requestData = { ...requestData, id: infoRef.current };
    }
    topBarSearchRequest = requestData;
    let api =
      '/api/bs/hrmorganization/orgchart/companyData' +
      qs.stringify(requestData, { addQueryPrefix: true });
    fetch(api)
      .then((res) => res.json())
      .then((data) => {
        if (data.data) {
          if (!data.data.length) {
            setData([{}]);
            message.warning(`${getLabel(547516, labelData)}`);
          } else {
            setData(data?.data);
          }
        }
        setTimeout(function () {
          setSpinning(false);
        }, 200);
      });
  };

  /**
   * 切换维度
   * @param {*} requestData
   */
  const handleChange = (requestData) => {
    setTimelineId(0);
    timeLine.searchTimeLines(
      `/api/bs/hrmorganization/orgchart/timeLines?fclass=${requestData.fclass}`,
    );
    requestData = { ...requestData, id: 0 };
    handleSearch(requestData, false);
  };

  useEffect(() => {
    if (active == 'left') {
      orgChart &&
        orgChart
          .setCentered(orgChart.getChartState().root?.id)
          .layout('left')
          .render();
    } else {
      orgChart &&
        orgChart
          .setCentered(orgChart.getChartState().root?.id)
          .layout('top')
          .render();
    }
  }, [data]);

  if (hasRight === false) {
    return (
      <div style={{ width: '100%', top: '40%', position: 'absolute' }}>
        <img
          style={{ display: 'block', margin: '0 auto' }}
          src="./img/permission.png"
        />
        <p style={{ textAlign: 'center' }}>{getLabel(547515, labelData)}</p>
      </div>
    );
  }

  return (
    hasRight &&
    Object.keys(labelData).length != 0 && (
      <div className={styles.contentWrapper}>
        <TopBar
          ref={(r) => (topbar = r)}
          onExport={(type) => {
            handleExport(type);
          }}
          onSearch={(requestData) => {
            handleSearch(requestData);
          }}
          changeFclass={(requestData) => {
            handleChange(requestData);
          }}
          type="company"
          url="/api/bs/hrmorganization/orgchart/getCondition?fclass=0&type=company&id=0"
          labelData={labelData}
        />
        <ToolBar
          onTopLayoutClick={(progressBtn) => handleTopLayoutClick(progressBtn)}
          onLeftLayoutClick={(progressBtn) =>
            handleLeftLayoutClick(progressBtn)
          }
          onFullscreen={(progressBtn) => handleFullscreen(progressBtn)}
          onFit={(progressBtn) => handleFit(progressBtn)}
          onFolderAddNode={(progressBtn) => handleFolderAddNode(progressBtn)}
          onDeleteNode={(progressBtn) => handleDeleteNode(progressBtn)}
          onCompact={(progressBtn) => handleCompact(progressBtn)}
          onExpandAll={(progressBtn) => handleExpandAll(progressBtn)}
          onZoomOut={(progressBtn) => handleZoomOut(progressBtn)}
          onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
          onZoomBehavior={(value) => handleZoomBehavior(value)}
        />
        <TimeLine
          ref={(r) => (timeLine = r)}
          onClick={(timeline) => {
            timeLineSearch(timeline);
          }}
          url={'/api/bs/hrmorganization/orgchart/timeLines?fclass=0'}
          labelData={labelData}
        />
        <Spin size="large" spinning={spinning}>
          <OrgChartComponent
            setChart={(chart) => (orgChart = chart)}
            setClick={(click) => (addNodeChildFunc = click)}
            onNodeClick={onNodeClick}
            data={data}
            onButtonClick={onButtonClick}
            buttonContent={buttonContentRender}
            nodeWidth={nodeWidthRender}
            nodeHeight={nodeHeightRender}
            nodeContent={nodeContentRender}
          />
        </Spin>
        <DrawerComponents ref={(r) => (drawerCom = r)} labelData={labelData} />
        <OperateDialog
          ref={(r) => (operateCom = r)}
          addFolderNode={addFolderNode}
          deleteNode={deleteNode}
          labelData={labelData}
        />
      </div>
    )
  );
}
