const TreeList = (data, loadAPiData, setMsg, waterText) => {
  const target = document.getElementById("treeListBox");
  const svgId = 'treeListBox';
  var width = target ? target.clientWidth : '100%';
  const height = target ? target.clientHeight : '100%';
  var guquanTupu;
  var rootData;
  var barHeight = 50;
  var barWidth = width;
  var nodes;
  var _rootD;
  getDataTupu();

  function getDataTupu() {
    rootData = {
      name: data.rootName,
      children: data.children
    };
    addFlag(rootData);
    guquanTupu = new drawGuquanTupu(rootData);
  }

  function drawGuquanTupu(rootData) {
    var i = 0;
    var duration = 400;
    var container;
    var isExtent = false;
    var scale = 1;
	  var diagonal,tree, treeRoot;
    d3.select("#" + svgId).selectAll("*").remove();
    var svg = d3.select("#" + svgId).append("svg").attr("xmlns", "http://www.w3.org/2000/svg");

    initSvg();

    update(rootData);

    function dragmove() {
      var x = parseInt(container.attr("transform").split(',')[0].split('(')[1]);
      var y = parseInt(container.attr("transform").split(',')[1].split(')')[0]);
      var transform = d3.zoomTransform(event.target);
      container.attr("transform", "translate(" + (x + transform.x) + "," + (y + transform.y) + ") scale(" + scale + ")");
    }

    function initSvg() {
      svg.selectAll("*").remove();
      svg.attr("width", width);
      svg.attr("height", height);
      svg.attr("class", "svgBox");

      container = svg.append("g");
      var zoom = d3.drag().on("drag", dragmove);
      svg.call(zoom);
      container.attr("transform", "translate(5,60)");
      container.attr("id", "gbox");
    }

    function update(source) {
      rootData.x0 = 0;
      rootData.y0 = 0;
      tree = d3.tree().nodeSize([0, 20]);

      diagonal = function (d) {
        return "M" + d.source.y + "," + d.source.x
            + "C" + (d.source.y + d.target.y) / 2 + "," + d.source.x
            + " " + (d.source.y + d.target.y) / 2 + "," + d.target.x
            + " " + d.target.y + "," + d.target.x;
      }
		
      treeRoot = d3.hierarchy(rootData);
      tree(treeRoot);
      nodes = treeRoot.descendants();

      var nodeX = 0;
      nodes.forEach(function (n, i) {
        n.x = nodeX;
        nodeX += n.data.height + 5;
      });

      svg.attr("height", Math.max(590, nodeX + 160));
      var height = Math.max(500, nodeX);
      d3.select("svg").transition()
        .duration(duration);

      d3.select(self.frameElement).transition()
        .duration(duration)
        .style("height", height + "px");


      // Update the nodes…
      var node = container.selectAll("g.node")
        .data(nodes, function (d) {
          return d.id || (d.id = ++i);
        });

      var nodeEnter = node.enter().append("g")
        .attr("class", "node")
        .attr("transform", function (d) {
          return "translate(" + source.y0 + "," + source.x0 + ")";
        })
        .style("opacity", 1);

      // Enter any new nodes at the parent's previous position.
      nodeEnter.append("rect")
        .attr("y", function (d) {
          if (d.depth == 0) {
            return -d.data.height / 2
          } else {
            return -15;
          }
        })
        .attr("height", function (d) {
          return d.data.height
        })
        .attr("width", function(d){
          if(d.depth == 0){
            return barWidth-20
          }else{
            return barWidth-30
          }
        })
        .style("stroke", "#999999")
        .attr("fill", "#ffffff")
        .attr('fill-opacity', 0)
        .attr("stroke-width", 0.5)
        .on("click", click);
      nodeEnter.append("rect")
        .attr("y", function (d) {
          if (d.depth == 0) {
            return -d.data.height / 2
          } else {
            return -15;
          }
        })
        .attr("height", function (d) {
          return d.data.height
        })
        .attr("width", 5)
        .style("fill", color)
        .style("fill-opacity", 1)
        .on("click", click);

      nodeEnter.append("text")
        .attr("dy", 3.5)
        .attr("dx", 30.5)
        .text(function (d) {
          if (d.data.name && d.data.name.length > 24) {
            return d.data.name.substr(0, 23) + '…';
          } else {
            return d.data.name;
          }
        })
        .attr("fill", "#333333")
        .style("font-size", "12px")
        .style("font-weight", "bold")
        .on("click", click);

      nodeEnter.each(function (d) {
        if (d.data.sign1) {
          d3.select(this).append("rect")
            .attr("x", 30)
            .attr("y", 13)
            .attr("rx", 2)
            .attr("ry", 2)
            .attr("height", 20)
            .attr("width", 44)
            .attr("fill", "#FE485E")
            .attr('fill-opacity', 0.08)
            .attr("stroke-width", 0.5);

          d3.select(this).append("text")
            .attr("dx", 35)
            .attr("dy", 27)
            .attr("fill", "#fe485e")
            .style("font-size", "11px")
            .text(d=> d.data.sign1);

          if (d.data.sign2) {
            d3.select(this).append("rect")
              .attr("x", 84)
              .attr("y", 13)
              .attr("rx", 2)
              .attr("ry", 2)
              .attr("height", 20)
              .attr("width", 66)
              .attr("fill", "#EEA324")
              .attr('fill-opacity', 0.08)
              .attr("stroke-width", 0.5);

            d3.select(this).append("text")
              .attr("dx", 89)
              .attr("dy", 27)
              .attr("fill", "#EEA324")
              .style("font-size", "11px")
              .text(d => d.data.sign2);

            if (d.data.sign3) {
              d3.select(this).append("rect")
                .attr("x", 160)
                .attr("y", 13)
                .attr("rx", 2)
                .attr("ry", 2)
                .attr("height", 20)
                .attr("width", 66)
                .attr("fill", "#128BED")
                .attr('fill-opacity', 0.08)
                .attr("stroke-width", 0.5);

              d3.select(this).append("text")
                .attr("dx", 165)
                .attr("dy", 27)
                .attr("fill", "#128BED")
                .style("font-size", "11px")
                .text(d => d.data.sign3);
            }
          }
        } else {
          if (d.data.sign2) {
            d3.select(this).append("rect")
              .attr("x", 30)
              .attr("y", 13)
              .attr("rx", 2)
              .attr("ry", 2)
              .attr("height", 20)
              .attr("width", 66)
              .attr("fill", "#EEA324")
              .attr('fill-opacity', 0.08)
              .attr("stroke-width", 0.5);

            d3.select(this).append("text")
              .attr("dx", 35)
              .attr("dy", 27)
              .attr("fill", "#EEA324")
              .style("font-size", "11px")
              .text(d => d.data.sign2);

            if (d.data.sign3) {
              d3.select(this).append("rect")
                .attr("x", 106)
                .attr("y", 13)
                .attr("rx", 2)
                .attr("ry", 2)
                .attr("height", 20)
                .attr("width", 66)
                .attr("fill", "#128BED")
                .attr('fill-opacity', 0.08)
                .attr("stroke-width", 0.5);

              d3.select(this).append("text")
                .attr("dx", 111)
                .attr("dy", 27)
                .attr("fill", "#128BED")
                .style("font-size", "11px")
                .text(d => d.data.sign3);
            }
          } else {
            if (d.data.sign3) {
              d3.select(this).append("rect")
                .attr("x", 30)
                .attr("y", 13)
                .attr("rx", 2)
                .attr("ry", 2)
                .attr("height", 20)
                .attr("width", 66)
                .attr("fill", "#128BED")
                .attr('fill-opacity', 0.08)
                .attr("stroke-width", 0.5);

              d3.select(this).append("text")
                .attr("dx", 35)
                .attr("dy", 27)
                .attr("fill", "#128BED")
                .style("font-size", "11px")
                .text(d => d.data.sign3);
            }
          }
        }
      })

      nodeEnter.append("text")
        .attr("dy", function (d) {
          if (d.data.sign2 || d.data.sign3 || d.data.sign1) {
            return 50.5;
          }
          return 20.5;
        })
        .attr("dx", 30.5)
        .style("font", "11px sans-serif")
        .attr("fill", "#666666")
        .text(function (d) {
          if (d.depth == 0) {
            return "";
          } else {
            return d.data.key1 + '：';
          }
        });
      nodeEnter.append("text")
        .attr("dy", function (d) {
          if (d.data.sign2 || d.data.sign3 || d.data.sign1) {
            return 50.5;
          }
          return 20.5;
        })
        .attr("dx", 85.5)
        .style("font", "11px sans-serif")
        .attr("fill", "#ff7e00")
        .text(function (d) {
          if (d.depth == 0) {
            return "";
          } else {
            if (d.data.value1) {
              return d.data.value1;
            }
            return '-';
          }
        });
      nodeEnter.append("text")
        .attr("dy", function (d) {
          if (d.data.sign2 || d.data.sign3 || d.data.sign1) {
            return 50.5;
          }
          return 20.5;
        })
        .attr("dx", 150.5)
        .style("font", "11px sans-serif")
        .attr("fill", "#666666")
        .text(function (d) {
          if (d.depth == 0) {
            return "";
          } else {
            return d.data.key2 + '：'
          }
        });
      nodeEnter.append("text")
        .attr("dy", function (d) {
          if (d.data.sign2 || d.data.sign3 || d.data.sign1) {
            return 50.5;
          }
          return 20.5;
        })
        .attr("dx", 205.5)
        .style("font", "11px sans-serif")
        .attr("fill", "#ff7e00")
        .text(function (d) {
          if (d.depth == 0) {
            return "";
          } else {
            if (d.data.value2) {
              return d.data.value2;
            }
            return "-";
          }
        });
      nodeEnter.append("path")
        .attr("d", function (d) {
          if (d.depth == 0) {
            _rootD = d;
            if (d.data._children && d.data._children.length > 0) {
              return "M7 -2 H11 V-6 H13 V-2 H17 V0 H13 V4 H11 V0 H7 Z"
            } else if (d.children && d.children.length > 0) {
              return "M7 -2 H17 V0 H7 Z"
            }
          } else {
            if (d.data._children && d.data._children.length > 0) {
              return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z"
            } else if ((d.data.children && d.data.children.length > 0)) {
              return "M7 6 H17 V8 H7 Z"
            }
			      if(d.data.isSearch==='Y')return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z"
          }
        })
        .attr("fill", "#bbbbbb")
        .on("click", function (d) {
          if (d.depth > 0 || true) {
            click(d);
          }
        });
      nodeEnter.append("circle")
        .attr("cx", 12)
        .attr("cy", function (d) {
          if (d.depth == 0) {
            return -1;
          }
          return 7;
        })
        .attr("r", function (d) {
          if ((d._children && d._children.length > 0) || (d.data._children && d.data._children.length > 0) ||d.data.isSearch==='Y') {
            return "6"
          } else if ((d.children && d.children.length > 0)|| (d.data.children && d.data.children.length > 0) || d.data.isSearch==='Y') {
            return "6"
          }
        })
        .attr("fill", "none")
        .attr("stroke", "#999999")
        .attr("stroke-width", "0.5")
        .on("click", function (d) {
          if (d.depth > 0) {
            click(d);
          }
        });

      // Transition nodes to their new position.
      nodeEnter.transition()
        .duration(duration)
        .attr("transform", function (d) {
          return "translate(" + d.y + "," + d.x + ")";
        })
        .style("opacity", 1);
      node.transition()
        .duration(duration)
        .attr("transform", function (d) {
          const y = d.y || d.y0;
          const x = d.x || d.x0;
          return "translate(" + y + "," + x + ")";
        })
        .style("opacity", 1)
        .select("rect")
        .style("stroke", "#999999");

      node.transition()
        .duration(duration)
        .attr("transform", function (d) {
          return "translate(" + d.y + "," + d.x + ")";
        })
        .style("opacity", 1)
        .select("path")
        .attr("d", function (d) {
          if (d.depth == 0) {
            if (d.data._children && d.data._children.length > 0) {
              return "M7 -2 H11 V-6 H13 V-2 H17 V0 H13 V4 H11 V0 H7 Z"
            } else if (d.data.children && d.data.children.length > 0) {
              return "M7 -2 H17 V0 H7 Z"
            }
          } else {
			  
            if (d.data._children && d.data._children.length > 0) {
              return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z"
            } else if (d.data.children && d.data.children.length > 0) {
              return "M7 6 H17 V8 H7 Z"
            }
			      if(d.data.isSearch==='Y')return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z"
          }
        });

      // Transition exiting nodes to the parent's new position.
      node.exit().transition()
        .duration(duration)
        .attr("transform", function (d) {
          const y = source.y || source.y0;
          const x = source.x || source.x0;
          return "translate(" + y + "," + x + ")";
        })
        .style("opacity", 1e-6)
        .remove();

      // Update the links…
      var link = container.selectAll("path.link")
        .data(treeRoot.links(), function (d) { 
          return d.target.id;
        });

      // Enter any new links at the parent's previous position.
      link.enter().insert("path", "g")
        .attr("class", "link")
        .attr("fill", "none")
        .attr("stroke-width", "0.5px")
        .attr("stroke", function (d) {
          if (d.target.data.sign1) {
            return "#fe485e";
          } else if (d.target.data.type == 1) {
            return "#7985f3";
          } else if(d.target.data.type == 2) {
            return "#4aceb1";
          }else{
            return "#FB813D";
          }
        })
        .attr("d", function (d) {
          var o = {
            x: source.x0,
            y: source.y0
          };
          return diagonal({
            source: o,
            target: o
          });
        })
        .style("stroke", function (d) {
          if (d.target.data.sign1) {
            return "#fe5151";
          }
        })
        .transition()
        .duration(duration)
        .attr("d", function (d) {
          return diagonal(d)
        })
        .style("stroke", function (d) {
          if (d.target.data.sign1) {
            return "#fe5151";
          }
        });

      // Transition links to their new position.
      link.transition()
        .duration(duration)
        .attr("d", function (d) {
          return diagonal(d)
        });

      // Transition exiting nodes to the parent's new position.
      link.exit().transition()
        .duration(duration)
        .attr("d", function (d) {
          var o = {
            x: source.x || source.x0,
            y: source.y || source.y0
          };
          return diagonal({
            source: o,
            target: o
          });
        })
        .remove();

      // Stash the old positions for transition.
      nodes.forEach(function (d) {
        d.x0 = d.x;
        d.y0 = d.y;
      });
    }

    function click(e) {
      var d = e.target.__data__;
      if(d.data.children === undefined){
        const param = {
          key: d.name,
          id: d.id
        }
        loadAPiData(param, ({code, data}) => {
          d.children = data.children.map((item)=>{
          if(item.sign1){
            item.height = barHeight+30
          }else{
            item.height = barHeight
          }
          return item
          })
          update(rootData);
        },()=>{
          setMsg('暂无下探数据');
          d.data.children = undefined
          update(rootData);
        })
        return
      }
      const children = d.children || d.data.children;
      if (children) {
        for(let i = 0; i< children.length; i++) {
          if(children[i].data) {
            children[i] = {
              ...children[i],
              ...children[i].data
            }
          }
        }
        d.data._children = children;
        d._children = children;
        d.data.children = null;
        d.children = null;
        d.data.isClose = true;
      } else {
        const _children = d._children || d.data._children;
        if(_children){
          for(let i = 0; i< _children.length; i++) {
            if(_children[i].data) {
              _children[i] = {
                ..._children[i],
                ..._children[i].data
              }
            }
          }
        }
        d.children = _children;
        d.data.children = _children;
        d.data._children = null;
        d._children = null;
        d.data.isClose = false;
      }
      update(rootData);
    }

    function color(d) {
      if (d.depth == 0) {
        return "#128bed";
      } else {
        if (d.data.sign1) {
          return "#fe5151";
        }
        if (d.data.type == 1) {
          return "#7985f3";
        }
        if (d.data.type == 2) {
          return "#4aceb1";
        }
        if(d.data.type == 3){
          return "#FB813D"  //其它类型左侧边边的颜色
        }
      }
    }

    function traverseTree(node) {
      if (node._children) {
        node.children = node._children;
        node._children = null;
      }

      if (node.children && node.children.length > 0) {
        for (var i = 0; i < node.children.length; i++) {
          traverseTree(node.children[i]);
        }
      }
    }

    function post(URL, PARAMS) {
      var temp = document.createElement("form");
      temp.action = URL;
      temp.enctype = "multipart/form-data";
      temp.method = "post";
      temp.style.display = "none";
      for (var x in PARAMS) {
        var opt = document.createElement("textarea");
        opt.name = x;
        opt.value = PARAMS[x];
        // alert(opt.name)        
        temp.appendChild(opt);
      }
      document.body.appendChild(temp);
      temp.submit();
      return temp;
    }
    // 展开收缩
    d3.select("#guquanExtent").on('click', () => {
      if (!isExtent) {
        traverseTree(rootData);
        update(rootData);
        d3.select("#guquanExtent").html(`
          <i class="iconfont iconTab_icon_Putaway ft24"></i>
          <span>收起</span>
        `);
        isExtent = true;
      } else {
        nodes.forEach(function (d) {
          if (d.depth > 0) {
            if (d.data.children) {
              d.data._children = d.data.children;
              d.data.children = null;
            }
          }
        });
        update(rootData);
        d3.select("#guquanExtent").html(`<i class="iconfont iconTab_icon_Expand ft24"></i>
          <span>展开</span>`)
        isExtent = false;
      }
    })
    // 一键展开
    d3.select("#open").on("click", ()=>{
      traverseTree(rootData);
      update(rootData);  
      isExtent = true;
    });
    // 一键收起
    d3.select("#close").on("click", ()=>{
      if (!_rootD.data.isClose) {
        click(_rootD);
      }
    });
    // 还原
    d3.select("#reduction").on("click", () => {
      nodes.forEach(function (d) {
        if (d.depth > 0) {
          if (d.data.children) {
            d.data._children = d.data.children;
            d.data.children = null;
          }
        }
      });
      update(rootData);
      isExtent = false;	  
    });
    // 刷新
    d3.select("#guquanRefresh").on('click', () => {
      d3.select("#guquanExtent").html(`
        <i class="iconfont iconTab_icon_Expand ft24"></i>
        <span>展开</span>
      `);
      traverseTree(rootData);
      initSvg();
      update(rootData);
      isExtent = false;
      scrollTo(0, 0);
    })
    //放大
    d3.select("#scaleLar").on('click', () => {
      var arr = container.attr("transform").split(',');
      var x = arr[0].split('(')[1]
      var y = arr[1].split(')')[0]
      if (scale < 4) {
        scale += 0.2;
      }
      container.transition()
        .duration(500)
        .attr("transform", "translate(" + (x) + "," + (y) + ") scale(" + scale + ")");
    })
    // 缩小
    d3.select("#scaleSml").on('click', () => {
      var arr = container.attr("transform").split(',');
      var x = arr[0].split('(')[1]
      var y = arr[1].split(')')[0]
      if (scale > 0.2) {
        scale -= 0.2;
      }
      container.transition()
        .duration(500)
        .attr("transform", "translate(" + (x) + "," + (y) + ") scale(" + scale + ")");
    })
    // 保存图片
    d3.select("#save").on('click', () => {
      var gNode = target.querySelector('#gbox');
      var _gData = gNode.getBoundingClientRect();
      var saveMain = document.getElementById('saveMain'); // 需要保存的内容的暂存处理空间
      var d3Svg = d3.select('#' + svgId + ' svg');
      var _svgWidth = d3Svg.attr('width');
      var _svgHeight = d3Svg.attr('height');
      var maxW = Math.max(_svgWidth, _gData.width)+10;
      var maxH = Math.max(_svgHeight, _gData.height);
      var svgXml = target.innerHTML;
      // 将所需保存的内容放到暂存空间
      saveMain.innerHTML = svgXml;
      var saveMainSvg = saveMain.querySelector('.svgBox');
      var saveMainG = saveMain.querySelector('#gbox');
      saveMainSvg.setAttribute('width', maxW);
      saveMainSvg.setAttribute('height', maxH);
      saveMainG.setAttribute('transform', `translate(5,60) scale(1)`)
      var newSvgXml = saveMain.innerHTML;
      var image = new Image();
      image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(newSvgXml)));
      setTimeout(function () {
        var canvas = document.createElement('canvas'); //准备空画布
        canvas.width = maxW;
        canvas.height = maxH;
        var context = canvas.getContext('2d'); //取得画布的2d绘图上下文
        if (waterText) {
          var shuiyinCvs = shuiyin().shuiyinCvs;
          var pat = context.createPattern(shuiyinCvs, "repeat");
          context.fillStyle = pat;
        } else {
          context.fillStyle = "#fff";
        }
        context.fillRect(0, 0, maxW, maxH);          
        context.drawImage(image, 0, 0);
        downloadimg(canvas);
      }, 100);
    })
  }
  function downloadimg(canvas) {
    var qual = 1;
    if (canvas.width > 3000) {
      qual = 0.8;
    } else if (canvas.width > 5000) {
      qual = 0.6;
    }
    //设置保存图片的类型
    var downUrl = canvas.toDataURL('image/jpg', qual);
    var filename = `${rootData.name}${new Date().toLocaleDateString()}结构图.jpg`;
    var a = document.createElement("a");
    a.style.display = "none";
    a.href = downUrl;
    a.download = filename;
    a.click();
  }
  // 设置水印
  function shuiyin() {
    var cvs = document.createElement('canvas');
    var ctx = cvs.getContext('2d');
    cvs.width = 180;
    cvs.height = 160;
    ctx.fillStyle = "rgba(255, 255, 255, 1)";
    ctx.fillRect(0, 0, 180, 160);
    ctx.fill();
    ctx.rotate(-30*Math.PI/180);
    ctx.font = "19px 微软雅黑";
    ctx.textAlign = 'left';
    ctx.textBaseline = 'Middle';
    // ctx.strokeStyle = '#c0c0c0';
    // ctx.strokeText(waterText, -30, 80);
    ctx.fillStyle = '#ddd';
    ctx.fillText(waterText, -30, 125);
    ctx.rotate(30*Math.PI/180);
    const shuiyinUrl = cvs.toDataURL('image/jpeg', 1);
    // new Image().src = shuiyinUrl;
    return {
      shuiyinImg: shuiyinUrl,
      shuiyinCvs: cvs
    };
  }
  function addFlag(node) {
    if (node.sign2 || node.sign3 || node.sign1) {
      node.height = barHeight + 30;
    } else {
      node.height = barHeight;
    }

    if (node.children) {
      for (var i = 0; i < node.children.length; i++) {
        addFlag(node.children[i]);
      }
    }
  }
}