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

let graph = null;
const globalFontSize = 20;
const maxTextWidth = 160;

class PreviewTree extends React.Component {

  componentDidMount() {
    const container = document.getElementById('preview-tree');

    const width = container.scrollWidth;
    const height = container.scrollHeight || 300;

    G6.registerNode(
      'tree-node',
      {
        draw(cfg, group) {    
          const rect = group.addShape('rect', {
            attrs: {
              fill: '#fff',
              stroke: '#666',
              radius: 5,
              cursor: 'pointer',
            },
          });
          
          const content = (cfg.label||'').replace(/(.{19})/g, '$1\n');

          const text = group.addShape('text', {
            attrs: {
              x: 0,
              y: 0,
              fill: '#000',
              fontSize: globalFontSize,
              textAlign: 'left',
              textBaseline: 'middle',
              text: content,
            }
          });

          const bbox = text.getBBox();

          rect.attr({
            x: bbox.minX - 10,
            y: bbox.minY - 10,
            width: bbox.width + 20,
            height: bbox.height + 20,
          });
    
          return group;
        },
        update: undefined,
      },
      'single-node'
    );   

    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;
      },
    });

    graph = new G6.TreeGraph({
      container: 'preview-tree',
      width,
      height,
      maxZoom: 1,
      plugins: [tooltip],
      modes: {
        default: [
          {
            type: 'zoom-canvas',
            enableOptimize: true,
          },
          'drag-canvas',
          'drag-node',
        ],
      },
      defaultNode: {
        type: 'tree-node',
        anchorPoints: [
          [0, 0.5],
          [1, 0.5],
        ],
      },
      defaultEdge: {
        type: 'line',
        size: 2,
        color: '#e2e2e2',
        style: {
          endArrow: true
        }
      },
      layout: {
        type: 'compactBox',
        direction: 'LR', // H / V / LR / RL / TB / BT
        getId: function getId(d) {
          return d.id;
        },
        getVGap: function getVGap() {
          return 20;
        },
        getHGap: function getHGap() {
          return 100;
        },
      },
    });

    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 {
        label: fittingString(node.text||'', maxTextWidth, globalFontSize),
      };
    });

    this.layoutGraph();

    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);
      };
    }
  }

  layoutGraph = () => {
    const { data } = this.props;

    if(graph && data){
      graph.data(data);
      graph.render();
      graph.fitView();
    }
  }

  componentDidUpdate(prevProps, prevState) {
    this.layoutGraph();
  }

  render() {
    return (
      <div id='preview-tree' style={{ width: '100%', height: '100%' }} />
    );
  }
}

export default PreviewTree;  