import React from 'react';
import G6 from '@antv/g6';

const globalFontSize = 20;
const maxTextWidth = 160;

class Org extends React.Component {

  componentDidUpdate(prevProps, prevState) {
    const { childData, parentNodeId, data } = this.props;

    if (parentNodeId && parentNodeId!== prevProps.parentNodeId) {

      const parentData = this.graph?.findDataById(parentNodeId);
      if (!parentData.children) {
        parentData.children = [];
      }

      parentData.children = parentData.children.filter(item => item.dbType!=='More');
      parentData.children = [...parentData.children, ...childData];
      this.graph?.changeData();

      this.graph?.updateItem(this.graph?.findById(parentNodeId), {
        collapsed: false,
      });

    } else if (data && data !== prevProps.data && parentNodeId===null) {
      this.graph?.destroy();
      this.graph = init(this)(this.elem, this.props.data);
    }
  }

  graph = undefined
  elem = undefined

  render() {
    const { styles } = this.props;
    return (
      <div ref={ref => this.elem = ref} style={styles} />
    );
  }
}

export default Org;

const init = (ctx) => function (container, data) {
  const width = container.scrollWidth;
  const height = container.scrollHeight;

  const tooltip = new G6.Tooltip({
    offsetX: 10,
    offsetY: 10,
    // the types of items that allow the tooltip show up
    // 允许出现 tooltip 的 item 类型
    itemTypes: ['node'],
    // custom the tooltip's content
    // 自定义 tooltip 内容
    getContent: (e) => {
      const outDiv = document.createElement('div');
      outDiv.style.width = 'fit-content';
      //outDiv.style.padding = '0px 0px 20px 0px';
      outDiv.innerHTML = `
        <h4>${e.item.getModel().text||''}</h4>
        `;
      return outDiv;
    },
  });

  var graph = new G6.TreeGraph({
    container,
    width,
    height,
    linkCenter: true,
    maxZoom: 1,
    plugins: [tooltip],
    modes: {
      default: [
        {
          type: 'collapse-expand',
          onChange: function onChange(item, collapsed) {
            const data = item.get('model');
            graph.updateItem(item, {
              collapsed,
            });
            data.collapsed = collapsed;
            return true;
          },
        },
        'drag-canvas',
        'zoom-canvas',
      ],
    },
    defaultNode: {
      size: 26,
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    defaultEdge: {
      type: 'cubic-vertical',
      size: 2,
      color: '#e2e2e2',
    },
    layout: {
      type: 'compactBox',
      direction: 'TB',
      getId: function getId(d) {
        return d.id;
      },
      getVGap: function getVGap() {
        return 200;
      },
      getHGap: function getHGap() {
        return 40;
      },
    },
  });

  const fittingString = (str, maxWidth, fontSize) => {
    const ellipsis = '...';
    const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
    let currentWidth = 0;
    let res = str;
    const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters
    str.split('').forEach((letter, i) => {
      if (currentWidth > maxWidth - ellipsisLength) return;
      if (pattern.test(letter)) {
        // Chinese charactors
        currentWidth += fontSize;
      } else {
        // get the width of single letter according to the fontSize
        currentWidth += G6.Util.getLetterWidth(letter, fontSize);
      }
      if (currentWidth > maxWidth - ellipsisLength) {
        res = `${str.substr(0, i)}${ellipsis}`;
      }
    });
    return res;
  };

  graph.node(function (node) {

    return {
      style: {
        fill: (node.dbType==='Dir'||node.dbType==='More')?'#0069AC':'#fff',
        stroke: '#096dd9'
      },
      label: fittingString(node.text||'', maxTextWidth, globalFontSize),
      labelCfg: {
        position: 'bottom',
        offset: 5,
        style: {
          rotate: 0,
          textAlign: 'center',
        },
      },
    };
  });

  graph.data(data);
  graph.render();
  graph.fitView();

  graph.on('node:click', function (e) {
    const node = e.item;
    const nodeId = node.get('id');

    const model = node.getModel();

    if (model.dbType==='Dir') {

      const children = model.children;
      if (!children ) {
        ctx.props?.loadSubLeafData(model.dirId||'', nodeId);
      }

    } else if (model.dbType === 'Table') {
      
      ctx.props?.onAssetClick(model.tid);
    
    } else if (model.dbType === 'More') {
    
      ctx.props?.loadMoreLeafData(model.pDirId, model.pid, model.index);
    
    }

  });

  if (typeof window !== 'undefined') {
    window.onresize = () => {
      if (!graph || graph.get('destroyed')) return;
      if (!container || !container.scrollWidth || !container.scrollHeight) return;

      graph.changeSize(container.scrollWidth, container.scrollHeight);
    };
  }

  return graph;
}
