<template>
  <section class="rightsGraph">
    <div id="RightGraph"/>
  </section>
</template>

<script>
import * as echarts from "echarts";

export default {
  name: "rightsGraph",
  inject: ['top'],
  props: {
    instance: Function,
    dict: Object,
    app: Object
  },
  computed: {
    graphData() {
      let data = [...this.users, ...this.nodes].map(e => {
        if (e.x) {
          return e
        } else return {...e, ...this.renderPosition(e)}
      })
      return [
        {
          data,
          links: this.links,
          categories: data.map(e => e.category).flat().map(name => ({name}))
        }
      ]
    }
  },
  data() {
    return {
      graph: null,
      nodes: [],
      links: [],
      users: []
    }
  },
  watch: {
    graphData: {
      deep: true, handler() {
        this.refreshGraph()
      }
    }
  },
  methods: {
    initGraph() {
      let dom = document.querySelector("#RightGraph")
      if (dom) {
        this.graph = echarts.init(dom)
        this.graph.setOption({
          tooltip: {},
          series: [
            {
              type: 'graph',
              layout: 'none',
              roam: true,
              label: {
                show: true,
                position: 'right',
                formatter: '{b}'
              },
              labelLayout: {
                hideOverlap: true,
              },
              scaleLimit: {
                min: 0.4,
                max: 4
              },
              lineStyle: {
                color: 'target',
                curveness: 0.1
              },
              emphasis: {
                focus: 'adjacency',
                lineStyle: {
                  width: 5
                }
              }
            }
          ]
        })
        this.graph.on('click', this.handleNodeClick)
      }
    },
    refreshGraph() {
      this.graph?.setOption({
        series: this.graphData
      })
    },
    getAppRoles(role) {
      if (role) {
        this.nodes.push({...role, category: '应用角色', value: "应用角色", symbolSize: 15})
      } else this.instance.post(this.top.actions.list, null, {
        params: {pageSize: 999}
      }).then(res => {
        if (res?.data) {
          res.data.records.map(e => {
            this.getUsers(e.users, e.id)
            this.nodes.push({...e, category: '应用角色', value: "应用角色"})
          })
        }
      })
    },
    getUsers(pending, source) {
      pending?.map(e => {
        if (!this.users.some(u => u.id == e.phone)) {
          this.users.push({id: e.phone, name: e.name, symbolSize: 5, category: '用户', value: "用户"})
        }
        this.links.push({source, target: e.phone})
      })
    },
    getPermissions({appId: id, id: roleId, name: category, dataIndex}) {
      const addNodes = (list, source, category, pos) => {
        list?.map(e => {
          let node = {
            ...e,
            symbolSize: 5,
            category,
            value: e.list?.length > 0 ? "应用" : "权限",
          }
          node = {...node, ...this.renderPosition(pos || node)}
          this.nodes.splice(dataIndex, 0, node)
          this.links.push({source, target: e.id})
          addNodes(e.list, e.id, e.label, node)
        })
      }
      id && this.instance.post(this.top.actions.detail, null, {
        params: {id, roleId}
      }).then(res => {
        if (res?.data) {
          addNodes(res.data.list, roleId, category)
        }
      })
    },
    handleNodeClick(v) {
      let {data: role, dataIndex} = v
      if (!this.nodes.some(e => e.category == role?.name)) {
        role && this.getPermissions({...role, dataIndex})
      }
    },
    renderPosition(node) {
      node = JSON.parse(JSON.stringify(node))
      let pos = {x: 0, y: 0}
      if (node?.x) {
        pos.x = Math.max(this.graph?.getWidth() / 3 * 2, node.x) + 100 + Math.random() * 50
        pos.y = node.y + Math.random() * 100 - 50
      } else if (node.value == '应用角色') {
        pos.x = this.graph?.getWidth() / 3 - 200 + Math.random() * 200
        pos.y = this.graph?.getHeight() / 2 - 100 + Math.random() * 200
      } else if (node.value == '应用') {
        pos.x = this.graph?.getWidth() / 3 * 2 - 100 + Math.random() * 100
        pos.y = Math.random() * this.graph?.getHeight()
      } else if (node.value == '用户') {
        pos.x = Math.random() * 50
        pos.y = Math.random() * this.graph?.getHeight()
      } else {
        pos.x = this.graph?.getWidth() - 100 + Math.random() * 100
        pos.y = Math.random() * this.graph?.getHeight()
      }
      return pos
    }
  },
  created() {
    this.getAppRoles(this.app)
    if (this.app?.id) {
      this.getUsers(this.app.users, this.app.id)
      this.getPermissions(this.app)
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initGraph()
    })
  }
}
</script>

<style lang="scss" scoped>
.rightsGraph {
  height: 100%;

  ::v-deep #RightGraph {
    width: 100%;
    height: 100%;
    min-height: 500px;
  }
}
</style>
