<template>
  <div :class="$style.jsMind">
    <div :class="[$style.navbarwrapper, { [$style.editbtn]: !readOnly }]">
      <div>
        <a-button-group>
          <a-button icon="zoom-in" :disabled="zoomIndisabled" title="放大" @click="fnZoomIn">
          </a-button>
          <a-button icon="zoom-out" :disabled="zoomOutdisabled" title="缩小" @click="fnZoomOut">
          </a-button>
        </a-button-group>
      </div>
      <div v-if="!readOnly" :class="$style.primarybtn">
        <a-button
          icon="small-dash"
          :disabled="noSelectedNode"
          title="添加子节点"
          @click="fnAddNode"
        >
        </a-button>
        <a-button
          icon="dash"
          :disabled="noSelectedNode"
          title="添加兄弟节点"
          @click="fnAddBrotherNode"
        >
        </a-button>
        <a-button icon="delete" :disabled="noSelectedNode" title="删除节点" @click="fnDeleteNode">
        </a-button>
        <a-button
          icon="link"
          :disabled="noSelectedNode"
          title="设置链接"
          @click="fnShowAddLinkModal"
        >
        </a-button>
      </div>
      <a-modal
        title="设置链接"
        :visible="visible"
        @ok="fnAddLinkOk"
        @cancel="() => (visible = false)"
      >
        <a-input v-model="link">
          <a-select slot="addonBefore" v-model="protocol" default-value="Http://">
            <a-select-option value="http://">
              http://
            </a-select-option>
            <a-select-option value="https://">
              https://
            </a-select-option>
          </a-select>
        </a-input>
      </a-modal>
    </div>
    <js-mind ref="jsMind" :values="objectValue" :options="options" height="660px"></js-mind>
  </div>
</template>

<script>
import { Message } from 'ant-design-vue'
import Vue from 'vue'
import jm from 'vue-jsmind'
import components from './_import-components/km-js-mind-import'

Vue.use(jm)

// 生成ID
function newid() {
  return (
    new Date().getTime().toString(16) +
    Math.random()
      .toString(16)
      .substr(2)
  ).substr(2, 16)
}

export default {
  name: 'KmJsMind',
  components,

  props: {
    // 是否只读
    readOnly: {
      type: Boolean,
      default: false,
    },

    // 数据
    value: {
      type: [Object, String],
      default: undefined,
    },
  },
  data() {
    return {
      visible: false,
      noSelectedNode: true,
      protocol: 'Http://',
      link: '',
      zoomIndisabled: false,
      zoomOutdisabled: false,
      jm: {},

      options: {
        editable: !this.readOnly,
        // 将新建节点的默认值改为中文
        shortcut: {
          handles: {
            addchild_custom: function(jm, e) {
              const selectedNode = jm.get_selected_node()
              if (selectedNode) {
                const nodeid = newid()
                jm.add_node(selectedNode, nodeid, '新建节点')
                jm.select_node(nodeid)
                jm.begin_edit(nodeid)
              }
            },

            addbrother_custom: function(jm, e) {
              const selectedNode = jm.get_selected_node()
              if (selectedNode) {
                if (selectedNode.isroot) {
                  Message.warn('根节点不能新建兄弟节点')
                  return
                }
                const nodeid = newid()
                jm.insert_node_after(selectedNode, nodeid, '新建节点')
                jm.select_node(nodeid)
                jm.begin_edit(nodeid)
              }
            },
          },
          mapping: {
            addchild_custom: 45, // <Insert>
            addbrother_custom: 13, // <Enter>
          },
        },
      },
    }
  },
  computed: {
    objectValue() {
      // 没有数据时默认的模板数据
      let objectValue = {
        /* 元数据，定义思维导图的名称、作者、版本等信息 */
        meta: {
          name: 'example',
          author: 'example',
          version: '0.1',
        },
        format: 'node_tree',
        data: {
          id: 'root',
          topic: '中心主题',
          children: [
            {
              id: 'children1',
              topic: '分支主题1',
            },
            {
              id: 'children2',
              topic: '分支主题2',
            },
            {
              id: 'children3',
              topic: '分支主题3',
            },
          ],
        },
      }

      if (this.value) {
        if (JSON.parse(this.value)) {
          objectValue = {
            meta: {
              name: 'example',
              author: 'example',
              version: '0.1',
            },
            format: 'node_tree',
            data: JSON.parse(this.value),
          }
        }
      }

      return objectValue
    },
  },
  mounted() {
    this.jm = this.$refs.jsMind.jm

    // 更新数据
    var _this = this
    this.jm.add_event_listener(function(type, data) {
      if (data.evt) {
        _this.updateValue()
      }
    })

    // 如果没有默认值，给更新下默认值
    if (!this.value) {
      this.updateValue()
    }

    // 设置按钮状态
    window.addEventListener('mousedown', (event) => {
      if (!this.readOnly) {
        const ele = event.target
        if (ele.tagName === 'JMNODE') {
          this.noSelectedNode = false
        } else if (ele.tagName === 'JMNODES') {
          this.noSelectedNode = true
        }
      }
    })
  },
  methods: {
    // 获取选中的节点
    fnGetSelectedNode() {
      const selectedNode = this.jm.get_selected_node()
      if (!selectedNode) {
        Message.warn('请先选择一个节点')
      } else {
        return selectedNode
      }
    },

    // 需要手动调一下才能更新
    refresh(item) {
      const objectValue = {
        meta: {
          name: 'example',
          author: 'example',
          version: '0.1',
        },
        format: 'node_tree',
        data: JSON.parse(item),
      }

      this.jm.show(objectValue)
    },

    // 编辑节点
    fnEditNode(node) {
      if (node) {
        this.jm.select_node(node)
        this.jm.begin_edit(node)
      } else {
        const selectedNode = this.fnGetSelectedNode()
        if (selectedNode) {
          this.jm.select_node(node)
          this.jm.begin_edit(selectedNode)
        }
      }
    },

    // 新增子节点
    fnAddNode() {
      const selectedNode = this.fnGetSelectedNode()
      const nodeid = newid()
      const topic = '新建节点'
      const node = this.jm.add_node(selectedNode, nodeid, topic)
      this.fnEditNode(node)
    },

    // 新增兄弟节点
    fnAddBrotherNode() {
      const selectedNode = this.fnGetSelectedNode()
      if (selectedNode.isroot) {
        Message.warn('根节点不能新建兄弟节点')
        return
      }
      if (selectedNode) {
        const nodeid = newid()
        const topic = '新建节点'
        this.jm.insert_node_after(selectedNode, nodeid, topic)
        this.fnEditNode(nodeid)
      }
    },

    // 删除节点
    fnDeleteNode() {
      const selectedNode = this.fnGetSelectedNode()
      this.jm.remove_node(selectedNode)
    },

    // 添加链接
    fnShowAddLinkModal() {
      const selectedNode = this.fnGetSelectedNode()

      if (selectedNode.data.protocol && selectedNode.data.link) {
        this.protocol = selectedNode.data.protocol
        this.link = selectedNode.data.link
      } else {
        this.link = ''
      }

      this.visible = true
    },

    fnAddLinkOk() {
      const selectedNode = this.fnGetSelectedNode()

      if (this.link) {
        let url = this.link
        if (
          url.substr(0, 7).toLowerCase() !== 'http://' &&
          url.substr(0, 8).toLowerCase() !== 'https://'
        ) {
          url = this.protocol + url
        }

        Object.assign(selectedNode.data, {
          link: this.link,
          protocol: this.protocol,
          'background-color': '#eee',
        })
        let topic = selectedNode.topic
        topic = `<a href="${url}" target="_blank">${topic}</a>`
        this.jm.update_node(selectedNode.id, topic)
        this.visible = false
      } else {
        Message.warn('请输入链接地址')
      }
    },

    // 放大
    fnZoomOut() {
      if (this.jm.view.zoomOut()) {
        this.zoomIndisabled = false
      } else {
        this.zoomOutdisabled = true
      }
    },
    // 缩小
    fnZoomIn() {
      if (this.jm.view.zoomIn()) {
        this.zoomOutdisabled = false
      } else {
        this.zoomIndisabled = true
      }
    },

    // 更新数据
    updateValue() {
      this.$emit('input', JSON.stringify(this.jm.get_data().data))
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
$jmexpander-line-height: 8px;
.js-mind {
  .editbtn {
    border-bottom: 1px solid #e4e7ed;
    box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);
  }
  .navbarwrapper {
    position: inherit;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 5px;
    background-color: $white;

    .primarybtn {
      button {
        margin: 0 5px;
      }
    }
  }
  :global(.jsmind-editor) {
    color: $text-color;
  }
  :global(a) {
    color: $blue-6;
  }
}
</style>
