import merge from 'deepmerge'
import LogicalStructure from './layouts/LogicalStructure'
import MindMap from './layouts/MindMap'
import CatalogOrganization from './layouts/CatalogOrganization'
import OrganizationStructure from './layouts/OrganizationStructure'
import TextEdit from './TextEdit'
import { copyNodeTree, simpleDeepClone, walk } from './utils'
import { shapeList } from './Shape'
import { lineStyleProps } from './themes/default'

// 布局列表
const layouts = {
  // 逻辑结构图
  logicalStructure: LogicalStructure,
  // 思维导图
  mindMap: MindMap,
  // 目录组织图
  catalogOrganization: CatalogOrganization,
  // 组织结构图
  organizationStructure: OrganizationStructure
}

/**
 * javascript comment
 * @Author: 王林25
 * @Date: 2021-04-08 16:25:07
 * @Desc: 渲染
 */
class Render {
  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-04-08 16:25:32
   * @Desc: 构造函数
   */
  constructor(opt = {}) {
    this.opt = opt
    this.mindMap = opt.mindMap
    this.themeConfig = this.mindMap.themeConfig
    this.draw = this.mindMap.draw
    // 渲染树，操作过程中修改的都是这里的数据
    this.renderTree = merge({}, this.mindMap.opt.data || {})
    // 是否重新渲染
    this.reRender = false
    // 当前激活的节点列表
    this.activeNodeList = []
    // 根节点
    this.root = null
    // 文本编辑框，需要再bindEvent之前实例化，否则单击事件只能触发隐藏文本编辑框，而无法保存文本修改
    this.textEdit = new TextEdit(this)
    // 布局
    this.setLayout()
    // 绑定事件
    this.bindEvent()
    // 注册命令
    this.registerCommands()
    // 注册快捷键
    this.registerShortcutKeys()
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-07-13 16:20:07
   * @Desc: 设置布局结构
   */
  setLayout() {
    this.layout = new (
      layouts[this.mindMap.opt.layout]
        ? layouts[this.mindMap.opt.layout]
        : layouts.logicalStructure
    )(this)
  }

  /**
   * @Author: 王林
   * @Date: 2021-06-20 10:34:06
   * @Desc:  绑定事件
   */
  bindEvent() {
    // 点击事件
    this.mindMap.on('draw_click', () => {
      // 清除激活状态
      if (this.activeNodeList.length > 0) {
        this.mindMap.execCommand('CLEAR_ACTIVE_NODE')
      }
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-05-04 13:19:06
   * @Desc: 注册命令
   */
  registerCommands() {
    // 全选
    this.selectAll = this.selectAll.bind(this)
    this.mindMap.command.add('SELECT_ALL', this.selectAll)
    // 回退
    this.back = this.back.bind(this)
    this.mindMap.command.add('BACK', this.back)
    // 前进
    this.forward = this.forward.bind(this)
    this.mindMap.command.add('FORWARD', this.forward)
    // 插入同级节点
    this.insertNode = this.insertNode.bind(this)
    this.mindMap.command.add('INSERT_NODE', this.insertNode)
    // 插入子节点
    this.insertChildNode = this.insertChildNode.bind(this)
    this.mindMap.command.add('INSERT_CHILD_NODE', this.insertChildNode)
    // 上移节点
    this.upNode = this.upNode.bind(this)
    this.mindMap.command.add('UP_NODE', this.upNode)
    // 下移节点
    this.downNode = this.downNode.bind(this)
    this.mindMap.command.add('DOWN_NODE', this.downNode)
    // 移动节点
    this.insertAfter = this.insertAfter.bind(this)
    this.mindMap.command.add('INSERT_AFTER', this.insertAfter)
    this.insertBefore = this.insertBefore.bind(this)
    this.mindMap.command.add('INSERT_BEFORE', this.insertBefore)
    this.moveNodeTo = this.moveNodeTo.bind(this)
    this.mindMap.command.add('MOVE_NODE_TO', this.moveNodeTo)
    // 删除节点
    this.removeNode = this.removeNode.bind(this)
    this.mindMap.command.add('REMOVE_NODE', this.removeNode)
    // 粘贴节点
    this.pasteNode = this.pasteNode.bind(this)
    this.mindMap.command.add('PASTE_NODE', this.pasteNode)
    // 剪切节点
    this.cutNode = this.cutNode.bind(this)
    this.mindMap.command.add('CUT_NODE', this.cutNode)
    // 修改节点样式
    this.setNodeStyle = this.setNodeStyle.bind(this)
    this.mindMap.command.add('SET_NODE_STYLE', this.setNodeStyle)
    // 切换节点是否激活
    this.setNodeActive = this.setNodeActive.bind(this)
    this.mindMap.command.add('SET_NODE_ACTIVE', this.setNodeActive)
    // 清除所有激活节点
    this.clearAllActive = this.clearAllActive.bind(this)
    this.mindMap.command.add('CLEAR_ACTIVE_NODE', this.clearAllActive)
    // 切换节点是否展开
    this.setNodeExpand = this.setNodeExpand.bind(this)
    this.mindMap.command.add('SET_NODE_EXPAND', this.setNodeExpand)
    // 展开所有节点
    this.expandAllNode = this.expandAllNode.bind(this)
    this.mindMap.command.add('EXPAND_ALL', this.expandAllNode)
    // 收起所有节点
    this.unexpandAllNode = this.unexpandAllNode.bind(this)
    this.mindMap.command.add('UNEXPAND_ALL', this.unexpandAllNode)
    // 展开到指定层级
    this.expandToLevel = this.expandToLevel.bind(this)
    this.mindMap.command.add('UNEXPAND_TO_LEVEL', this.expandToLevel)
    // 设置节点数据
    this.setNodeData = this.setNodeData.bind(this)
    this.mindMap.command.add('SET_NODE_DATA', this.setNodeData)
    // 设置节点文本
    this.setNodeText = this.setNodeText.bind(this)
    this.mindMap.command.add('SET_NODE_TEXT', this.setNodeText)
    // 设置节点图片
    this.setNodeImage = this.setNodeImage.bind(this)
    this.mindMap.command.add('SET_NODE_IMAGE', this.setNodeImage)
    // 设置节点图标
    this.setNodeIcon = this.setNodeIcon.bind(this)
    this.mindMap.command.add('SET_NODE_ICON', this.setNodeIcon)
    // 设置节点超链接
    this.setNodeHyperlink = this.setNodeHyperlink.bind(this)
    this.mindMap.command.add('SET_NODE_HYPERLINK', this.setNodeHyperlink)
    // 设置节点备注
    this.setNodeNote = this.setNodeNote.bind(this)
    this.mindMap.command.add('SET_NODE_NOTE', this.setNodeNote)
    // 设置节点标签
    this.setNodeTag = this.setNodeTag.bind(this)
    this.mindMap.command.add('SET_NODE_TAG', this.setNodeTag)
    // 添加节点概要
    this.addGeneralization = this.addGeneralization.bind(this)
    this.mindMap.command.add('ADD_GENERALIZATION', this.addGeneralization)
    // 删除节点概要
    this.removeGeneralization = this.removeGeneralization.bind(this)
    this.mindMap.command.add('REMOVE_GENERALIZATION', this.removeGeneralization)
    // 设置节点自定义位置
    this.setNodeCustomPosition = this.setNodeCustomPosition.bind(this)
    this.mindMap.command.add(
      'SET_NODE_CUSTOM_POSITION',
      this.setNodeCustomPosition
    )
    // 一键整理布局
    this.resetLayout = this.resetLayout.bind(this)
    this.mindMap.command.add('RESET_LAYOUT', this.resetLayout)
    // 设置节点形状
    this.setNodeShape = this.setNodeShape.bind(this)
    this.mindMap.command.add('SET_NODE_SHAPE', this.setNodeShape)
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-11 16:55:44
   * @Desc: 注册快捷键
   */
  registerShortcutKeys() {
    // 插入下级节点
    this.mindMap.keyCommand.addShortcut('Tab', () => {
      this.mindMap.execCommand('INSERT_CHILD_NODE')
    })
    // 插入同级节点
    this.insertNodeWrap = () => {
      if (this.textEdit.showTextEdit) {
        return
      }
      this.mindMap.execCommand('INSERT_NODE')
    }
    this.mindMap.keyCommand.addShortcut('Enter', this.insertNodeWrap)
    // 插入概要
    this.mindMap.keyCommand.addShortcut('Control+s', this.addGeneralization)
    // 展开/收起节点
    this.toggleActiveExpand = this.toggleActiveExpand.bind(this)
    this.mindMap.keyCommand.addShortcut('/', this.toggleActiveExpand)
    // 删除节点
    this.removeNodeWrap = () => {
      this.mindMap.execCommand('REMOVE_NODE')
    }
    this.mindMap.keyCommand.addShortcut('Del|Backspace', this.removeNodeWrap)
    // 节点编辑时某些快捷键会存在冲突，需要暂时去除
    this.mindMap.on('before_show_text_edit', () => {
      this.startTextEdit()
    })
    this.mindMap.on('hide_text_edit', () => {
      this.endTextEdit()
    })
    // 全选
    this.mindMap.keyCommand.addShortcut('Control+a', () => {
      this.mindMap.execCommand('SELECT_ALL')
    })
    // 一键整理布局
    this.mindMap.keyCommand.addShortcut('Control+l', this.resetLayout)
    // 上移节点
    this.mindMap.keyCommand.addShortcut('Control+Up', this.upNode)
    // 下移节点
    this.mindMap.keyCommand.addShortcut('Control+Down', this.downNode)
    // 复制节点、剪切节点、粘贴节点的快捷键需开发者自行注册实现，可参考demo
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2022-05-09 10:43:52
   * @Desc: 开启文字编辑，会禁用回车键和删除键相关快捷键防止冲突
   */
  startTextEdit() {
    this.mindMap.keyCommand.save()
    // this.mindMap.keyCommand.removeShortcut('Del|Backspace')
    // this.mindMap.keyCommand.removeShortcut('/')
    // this.mindMap.keyCommand.removeShortcut('Enter', this.insertNodeWrap)
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2022-05-09 10:45:11
   * @Desc: 结束文字编辑，会恢复回车键和删除键相关快捷键
   */
  endTextEdit() {
    this.mindMap.keyCommand.restore()
    // this.mindMap.keyCommand.addShortcut('Del|Backspace', this.removeNodeWrap)
    // this.mindMap.keyCommand.addShortcut('/', this.toggleActiveExpand)
    // this.mindMap.keyCommand.addShortcut('Enter', this.insertNodeWrap)
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-04-08 16:27:55
   * @Desc:  渲染
   */
  render() {
    if (this.reRender) {
      this.clearActive()
    }
    this.layout.doLayout(root => {
      this.root = root
      this.root.render(() => {
        this.mindMap.emit('node_tree_render_end')
      })
    })
    this.mindMap.emit('node_active', null, this.activeNodeList)
  }

  /**
   * @Author: 王林
   * @Date: 2021-04-12 22:45:01
   * @Desc: 清除当前激活的节点
   */
  clearActive() {
    this.activeNodeList.forEach(item => {
      this.setNodeActive(item, false)
    })
    this.activeNodeList = []
  }

  /**
   * @Author: 王林
   * @Date: 2021-08-03 23:14:34
   * @Desc: 清除当前所有激活节点，并会触发事件
   */
  clearAllActive() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    this.clearActive()
    this.mindMap.emit('node_active', null, [])
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-11 10:54:00
   * @Desc:  添加节点到激活列表里
   */
  addActiveNode(node) {
    let index = this.findActiveNodeIndex(node)
    if (index === -1) {
      this.activeNodeList.push(node)
    }
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 10:04:04
   * @Desc: 在激活列表里移除某个节点
   */
  removeActiveNode(node) {
    let index = this.findActiveNodeIndex(node)
    if (index === -1) {
      return
    }
    this.activeNodeList.splice(index, 1)
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-11 10:55:23
   * @Desc: 检索某个节点在激活列表里的索引
   */
  findActiveNodeIndex(node) {
    return this.activeNodeList.findIndex(item => {
      return item === node
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-05-04 13:46:08
   * @Desc: 获取节点在同级里的索引位置
   */
  getNodeIndex(node) {
    return node.parent
      ? node.parent.children.findIndex(item => {
          return item === node
        })
      : 0
  }

  /**
   * @Author: 王林
   * @Date: 2021-08-04 23:54:52
   * @Desc: 全选
   */
  selectAll() {
    walk(
      this.root,
      null,
      node => {
        if (!node.nodeData.data.isActive) {
          node.nodeData.data.isActive = true
          this.addActiveNode(node)
          setTimeout(() => {
            node.renderNode()
          }, 0)
        }
      },
      null,
      true,
      0,
      0
    )
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-11 22:34:12
   * @Desc: 回退
   */
  back(step) {
    this.clearAllActive()
    let data = this.mindMap.command.back(step)
    if (data) {
      this.renderTree = data
      this.mindMap.reRender()
    }
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-07-12 10:44:51
   * @Desc: 前进
   */
  forward(step) {
    this.clearAllActive()
    let data = this.mindMap.command.forward(step)
    if (data) {
      this.renderTree = data
      this.mindMap.reRender()
    }
  }

  /**
   * @Author: 王林
   * @Date: 2021-05-04 13:19:54
   * @Desc: 插入同级节点，多个节点只会操作第一个节点
   */
  insertNode() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    let first = this.activeNodeList[0]
    if (first.isRoot) {
      this.insertChildNode()
    } else {
      let text = first.layerIndex === 1 ? '二级节点' : '分支主题'
      if (first.layerIndex === 1) {
        first.parent.initRender = true
      }
      let index = this.getNodeIndex(first)
      first.parent.nodeData.children.splice(index + 1, 0, {
        inserting: true,
        data: {
          text: text,
          expand: true
        },
        children: []
      })
      this.mindMap.render()
    }
  }

  /**
   * @Author: 王林
   * @Date: 2021-05-04 13:31:02
   * @Desc: 插入子节点
   */
  insertChildNode() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    this.activeNodeList.forEach(node => {
      if (!node.nodeData.children) {
        node.nodeData.children = []
      }
      let text = node.isRoot ? '二级节点' : '分支主题'
      node.nodeData.children.push({
        inserting: true,
        data: {
          text: text,
          expand: true
        },
        children: []
      })
      // 插入子节点时自动展开子节点
      node.nodeData.data.expand = true
      if (node.isRoot) {
        node.initRender = true
        // this.mindMap.batchExecution.push('renderNode' + index, () => {
        //     node.renderNode()
        // })
      }
    })
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-14 23:34:14
   * @Desc: 上移节点，多个节点只会操作第一个节点
   */
  upNode() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    let node = this.activeNodeList[0]
    if (node.isRoot) {
      return
    }
    let parent = node.parent
    let childList = parent.children
    let index = childList.findIndex(item => {
      return item === node
    })
    if (index === -1 || index === 0) {
      return
    }
    let insertIndex = index - 1
    // 节点实例
    childList.splice(index, 1)
    childList.splice(insertIndex, 0, node)
    // 节点数据
    parent.nodeData.children.splice(index, 1)
    parent.nodeData.children.splice(insertIndex, 0, node.nodeData)
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-14 23:34:18
   * @Desc: 下移节点，多个节点只会操作第一个节点
   */
  downNode() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    let node = this.activeNodeList[0]
    if (node.isRoot) {
      return
    }
    let parent = node.parent
    let childList = parent.children
    let index = childList.findIndex(item => {
      return item === node
    })
    if (index === -1 || index === childList.length - 1) {
      return
    }
    let insertIndex = index + 1
    // 节点实例
    childList.splice(index, 1)
    childList.splice(insertIndex, 0, node)
    // 节点数据
    parent.nodeData.children.splice(index, 1)
    parent.nodeData.children.splice(insertIndex, 0, node.nodeData)
    this.mindMap.render()
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-11-25 10:51:34
   * @Desc: 将节点移动到另一个节点的前面
   */
  insertBefore(node, exist) {
    if (node.isRoot) {
      return
    }
    let parent = node.parent
    let childList = parent.children
    // 要移动节点的索引
    let index = childList.findIndex(item => {
      return item === node
    })
    if (index === -1) {
      return
    }
    // 目标节点的索引
    let existIndex = childList.findIndex(item => {
      return item === exist
    })
    if (existIndex === -1) {
      return
    }
    // 当前节点在目标节点前面
    if (index < existIndex) {
      existIndex = existIndex - 1
    }
    // 节点实例
    childList.splice(index, 1)
    childList.splice(existIndex, 0, node)
    // 节点数据
    parent.nodeData.children.splice(index, 1)
    parent.nodeData.children.splice(existIndex, 0, node.nodeData)
    this.mindMap.render()
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-11-25 10:51:34
   * @Desc: 将节点移动到另一个节点的后面
   */
  insertAfter(node, exist) {
    if (node.isRoot) {
      return
    }
    let parent = node.parent
    let childList = parent.children
    // 要移动节点的索引
    let index = childList.findIndex(item => {
      return item === node
    })
    if (index === -1) {
      return
    }
    // 目标节点的索引
    let existIndex = childList.findIndex(item => {
      return item === exist
    })
    if (existIndex === -1) {
      return
    }
    // 当前节点在目标节点前面
    if (index < existIndex) {
      // do nothing
    } else {
      existIndex = existIndex + 1
    }
    // 节点实例
    childList.splice(index, 1)
    childList.splice(existIndex, 0, node)
    // 节点数据
    parent.nodeData.children.splice(index, 1)
    parent.nodeData.children.splice(existIndex, 0, node.nodeData)
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-05-04 13:40:39
   * @Desc: 移除节点
   */
  removeNode() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    for (let i = 0; i < this.activeNodeList.length; i++) {
      let node = this.activeNodeList[i]
      if (node.isGeneralization) {
        // 删除概要节点
        this.setNodeData(node.generalizationBelongNode, {
          generalization: null
        })
        node.generalizationBelongNode.update()
        this.removeActiveNode(node)
        i--
      } else if (node.isRoot) {
        node.children.forEach(child => {
          child.remove()
        })
        node.children = []
        node.nodeData.children = []
        break
      } else {
        this.removeActiveNode(node)
        this.removeOneNode(node)
        i--
      }
    }
    this.mindMap.emit('node_active', null, [])
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-15 22:46:27
   * @Desc: 移除某个指定节点
   */
  removeOneNode(node) {
    let index = this.getNodeIndex(node)
    node.remove()
    node.parent.children.splice(index, 1)
    node.parent.nodeData.children.splice(index, 1)
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-07-15 09:53:23
   * @Desc: 复制节点，多个节点只会操作第一个节点
   */
  copyNode() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    return copyNodeTree({}, this.activeNodeList[0], true)
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-15 22:36:45
   * @Desc: 剪切节点，多个节点只会操作第一个节点
   */
  cutNode(callback) {
    if (this.activeNodeList.length <= 0) {
      return
    }
    let node = this.activeNodeList[0]
    if (node.isRoot) {
      return null
    }
    let copyData = copyNodeTree({}, node, true)
    this.removeActiveNode(node)
    this.removeOneNode(node)
    this.mindMap.emit('node_active', null, this.activeNodeList)
    this.mindMap.render()
    if (callback && typeof callback === 'function') {
      callback(copyData)
    }
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2021-11-24 16:54:01
   * @Desc: 移动一个节点作为另一个节点的子节点
   */
  moveNodeTo(node, toNode) {
    if (node.isRoot) {
      return
    }
    let copyData = copyNodeTree({}, node)
    this.removeActiveNode(node)
    this.removeOneNode(node)
    this.mindMap.emit('node_active', null, this.activeNodeList)
    toNode.nodeData.children.push(copyData)
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-15 20:09:39
   * @Desc:  粘贴节点到节点
   */
  pasteNode(data) {
    if (this.activeNodeList.length <= 0) {
      return
    }
    this.activeNodeList.forEach(item => {
      item.nodeData.children.push(simpleDeepClone(data))
    })
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-08 21:54:30
   * @Desc: 设置节点样式
   */
  setNodeStyle(node, prop, value, isActive) {
    let data = {}
    if (isActive) {
      data = {
        activeStyle: {
          ...(node.nodeData.data.activeStyle || {}),
          [prop]: value
        }
      }
    } else {
      data = {
        [prop]: value
      }
    }
    this.setNodeDataRender(node, data)
    // 更新了连线的样式
    if (lineStyleProps.includes(prop)) {
      ;(node.parent || node).renderLine(true)
    }
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-08 22:13:03
   * @Desc: 设置节点是否激活
   */
  setNodeActive(node, active) {
    this.setNodeData(node, {
      isActive: active
    })
    node.renderNode()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 16:52:41
   * @Desc: 设置节点是否展开
   */
  setNodeExpand(node, expand) {
    this.setNodeData(node, {
      expand
    })
    if (expand) {
      // 展开
      node.children.forEach(item => {
        item.render()
      })
      node.renderLine()
      node.updateExpandBtnNode()
    } else {
      // 收缩
      node.children.forEach(item => {
        item.remove()
      })
      node.removeLine()
      node.updateExpandBtnNode()
    }
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-15 23:23:37
   * @Desc: 展开所有
   */
  expandAllNode() {
    walk(
      this.renderTree,
      null,
      node => {
        if (!node.data.expand) {
          node.data.expand = true
        }
      },
      null,
      true,
      0,
      0
    )
    this.mindMap.reRender()
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-15 23:27:14
   * @Desc: 收起所有
   */
  unexpandAllNode() {
    walk(
      this.renderTree,
      null,
      (node, parent, isRoot) => {
        node._node = null
        if (!isRoot) {
          node.data.expand = false
        }
      },
      null,
      true,
      0,
      0
    )
    this.mindMap.reRender()
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2022-09-23 16:31:27
   * @Desc: 展开到指定层级
   */
  expandToLevel(level) {
    walk(
      this.renderTree,
      null,
      (node, parent, isRoot, layerIndex) => {
        node._node = null
        node.data.expand = layerIndex < level
      },
      null,
      true,
      0,
      0
    )
    this.mindMap.reRender()
  }

  /**
   * @Author: 王林
   * @Date: 2022-08-14 09:18:40
   * @Desc: 切换激活节点的展开状态
   */
  toggleActiveExpand() {
    this.activeNodeList.forEach(node => {
      if (node.nodeData.children.length <= 0) {
        return
      }
      this.toggleNodeExpand(node)
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-11 17:15:33
   * @Desc: 切换节点展开状态
   */
  toggleNodeExpand(node) {
    this.mindMap.execCommand(
      'SET_NODE_EXPAND',
      node,
      !node.nodeData.data.expand
    )
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-09 22:04:19
   * @Desc: 设置节点文本
   */
  setNodeText(node, text) {
    this.setNodeDataRender(node, {
      text
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 08:37:40
   * @Desc: 设置节点图片
   */
  setNodeImage(node, { url, title, width, height }) {
    this.setNodeDataRender(node, {
      image: url,
      imageTitle: title || '',
      imageSize: {
        width,
        height
      }
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 08:44:06
   * @Desc: 设置节点图标
   */
  setNodeIcon(node, icons) {
    this.setNodeDataRender(node, {
      icon: icons
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 08:49:33
   * @Desc: 设置节点超链接
   */
  setNodeHyperlink(node, link, title = '') {
    this.setNodeDataRender(node, {
      hyperlink: link,
      hyperlinkTitle: title
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 08:52:59
   * @Desc: 设置节点备注
   */
  setNodeNote(node, note) {
    this.setNodeDataRender(node, {
      note
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 08:54:53
   * @Desc: 设置节点标签
   */
  setNodeTag(node, tag) {
    this.setNodeDataRender(node, {
      tag
    })
  }

  /**
   * @Author: 王林
   * @Date: 2022-07-30 20:52:42
   * @Desc: 添加节点概要
   */
  addGeneralization(data) {
    if (this.activeNodeList.length <= 0) {
      return
    }
    this.activeNodeList.forEach(node => {
      if (node.nodeData.data.generalization || node.isRoot) {
        return
      }
      this.setNodeData(node, {
        generalization: data || {
          text: '概要'
        }
      })
      node.update()
    })
    this.mindMap.render()
  }

  /**
   * @Author: 王林
   * @Date: 2022-07-30 21:16:33
   * @Desc: 删除节点概要
   */
  removeGeneralization() {
    if (this.activeNodeList.length <= 0) {
      return
    }
    this.activeNodeList.forEach(node => {
      if (!node.nodeData.data.generalization) {
        return
      }
      this.setNodeData(node, {
        generalization: null
      })
      node.update()
    })
    this.mindMap.render()
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2022-08-02 19:04:24
   * @Desc: 设置节点自定义位置
   */
  setNodeCustomPosition(node, left = undefined, top = undefined) {
    let nodeList = [node] || this.activeNodeList
    nodeList.forEach(item => {
      this.setNodeData(item, {
        customLeft: left,
        customTop: top
      })
    })
  }

  /**
   * javascript comment
   * @Author: 王林25
   * @Date: 2022-08-02 20:02:50
   * @Desc: 一键整理布局，即去除自定义位置
   */
  resetLayout() {
    walk(
      this.root,
      null,
      node => {
        node.customLeft = undefined
        node.customTop = undefined
        this.setNodeData(node, {
          customLeft: undefined,
          customTop: undefined
        })
        this.mindMap.render()
      },
      null,
      true,
      0,
      0
    )
  }

  /**
   * javascript comment
   * @Author: 王林
   * @Date: 2022-09-12 21:44:01
   * @Desc: 设置节点形状
   */
  setNodeShape(node, shape) {
    if (!shape || !shapeList.includes(shape)) {
      return
    }
    let nodeList = [node] || this.activeNodeList
    nodeList.forEach(item => {
      this.setNodeStyle(item, 'shape', shape)
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-05-04 14:19:48
   * @Desc: 更新节点数据
   */
  setNodeData(node, data) {
    Object.keys(data).forEach(key => {
      node.nodeData.data[key] = data[key]
    })
  }

  /**
   * @Author: 王林
   * @Date: 2021-07-10 08:45:48
   * @Desc: 设置节点数据，并判断是否渲染
   */
  setNodeDataRender(node, data) {
    this.setNodeData(node, data)
    let changed = node.getSize()
    node.renderNode()
    if (changed) {
      if (node.isGeneralization) {
        // 概要节点
        node.generalizationBelongNode.updateGeneralization()
      }
      this.mindMap.render()
    }
  }
}

export default Render
