<template>
  <div class="griddv">
    <div class="left">
      <div class="griddv-title">
        <h2>网格列表</h2>
      </div>
      <div class="griddv-tree">
        <el-tree
            :data="treeList"
            :props="defaultProps"
            @node-click="handleNodeClick"
            node-key="id"
            ref="tree"
            default-expand-all
            :expand-on-click-node="false"
            highlight-current>
        </el-tree>
      </div>
    </div>
    <div class="middle" :class="[girdLevel == '2' ? 'middle-active' : '']" ref="container" v-loading="isLoading"
         element-loading-background="rgba(0, 0, 0, 0.5)">
      <div
          ref="middleTree"
          id="tree"
          class="tree"
          :style="{left: x, top: y, transform: `scale(${scale}) translate(-50%, -50%) `, 'transform-origin': `${0} ${0}`}">
        <VueOkrTree
            ref="VueOkrTree"
            :data="chartData"
            node-key="id"
            show-collapsable
            aniamte
            animate-name="okr-fade-in-linear"
            :render-content="renderContent"
            default-expand-all>
        </VueOkrTree>
      </div>
    </div>
    <div class="right">
      <div class="right-top">
        <div class="griddv-title">
          <h2>网格内人员情况</h2>
        </div>
        <div class="right-chart">
          <ai-echart
              style="height: 100%; width: 100%;"
              :data="userInfo"
              :ops="barChart1">
          </ai-echart>
        </div>
      </div>
      <div class="right-bottom">
        <div class="griddv-title">
          <h2>事件上报情况</h2>
        </div>
        <div class="right-chart">
          <ai-echart
              style="height: 100%; width: 100%;"
              :data="eventInfo"
              :ops="pieChart">
          </ai-echart>
        </div>
      </div>
    </div>
    <el-dialog :visible.sync="isShowInfo" width="640px" :close-on-click-modal="false" :modal-append-to-body="false">
      <template slot="title">
        <h2>家庭信息</h2>
        <img src="../assets/grid/close.png" @click="isShowInfo = false">
      </template>
      <div class="grid-info">
        <div class="grid-info__title">
          <h2>家庭地址</h2>
          <span>{{ residentInfo.currentAreaName }}</span>
        </div>
        <ai-table
            v-if="tableData.length"
            style="width: 558px"
            :tableData="tableData"
            :col-configs="colConfigs"
            :total="total"
            :isShowPagination="false"
            :current.sync="search.current"
            :size.sync="search.size"
            @getList="() => {}">
        </ai-table>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import pieChart from '../../../components/AiEchart/template/pie/pieChart2'
import barChart1 from '../../../components/AiEchart/template/bar/barChart1'
import {VueOkrTree} from 'vue-okr-tree'
import 'vue-okr-tree/dist/vue-okr-tree.css'

export default {
  name: 'AppGridDV',

  label: '网格数据大屏',

  props: {
    instance: Function,
    dict: Object,
  },

  data() {
    return {
      isLoading: false,
      treeList: [],
      search: {
        size: 100,
        current: 1
      },
      barChart1,
      userInfo: [],
      eventInfo: [],
      pieChart,
      total: 0,
      isShowInfo: false,
      defaultProps: {
        children: 'girdList',
        label: 'girdName',
      },
      colConfigs: [
        {prop: 'name', label: '姓名', align: 'center', width: 120},
        {
          prop: 'householdRelation',
          label: '与户主关系',
          align: 'center',
          render: (h, {row}) => {
            return h('span', {
              style: {
                color: row.householdName === '1' ? '#1DE94D' : '#A8D7F3'
              }
            }, row.householdName === '1' ? '户主' : (this.dict.getLabel('householdRelation', row.householdRelation) || '-'))
          },
          formart: v => this.dict.getLabel('householdRelation', v)
        },
        {
          prop: 'idNumber',
          label: '身份证号',
          align: 'center',
          width: 220,
          formart: v => v ? v.replace(/^(\d{10})\d{4}(.{4}$)/g, `$1${Array(5).join('*')}$2`) : '-'
        },
        {prop: 'phone', label: '联系方式', align: 'center'}
      ],
      girdId: '',
      residentInfo: {},
      tableData: [],
      chartData: [],
      girdLevel: '0',
      scale: 1,
      x: '50%',
      y: '50%',
      offsetX: 0,
      offsetY: 0,
      defaultUrl: 'https://cdn.cunwuyun.cn/dvcp/dv/avatar.png'
    }
  },

  components: {
    VueOkrTree
  },

  created() {
    this.dict.load('householdRelation')
    this.getTreeList()
    this.getGirdInfo()
  },

  mounted() {
    this.bindEvent()
  },

  destroyed() {
    document.querySelector('body').removeEventListener('mousewheel', this.onMousewheel)
    document.querySelector('body').removeEventListener('mouseup', this.onMouseUp)
    document.querySelector('body').removeEventListener('mousedown', this.onMousedown)
    document.querySelector('body').removeEventListener('mousemove', this.onMouseMove)
  },

  methods: {
    bindEvent() {
      document.querySelector('body').addEventListener('mousewheel', this.onMousewheel, true)

      document.querySelector('body').addEventListener('mouseup', this.onMouseUp, true)
      document.querySelector('body').addEventListener('mousedown', this.onMousedown, true)
      document.querySelector('body').addEventListener('mousemove', this.onMouseMove, true)
    },

    onMousewheel(event) {
      if (!event) return false
      const elClass = event.target.className
      if (elClass === 'tree' || elClass === 'middle' || (elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) {
        var dir = event.deltaY > 0 ? 'Up' : 'Down'
        if (dir === 'Up') {
          this.scale = this.scale - 0.2 <= 0.1 ? 0.1 : this.scale - 0.2
        } else {
          this.scale = this.scale + 0.2
        }
      }

      return false
    },

    onMousedown(e) {
      const elClass = e.target.className
      if ((elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) {
        const left = document.querySelector('#tree').offsetLeft
        const top = document.querySelector('#tree').offsetTop
        this.isMove = true
        this.offsetX = e.clientX - left
        this.offsetY = e.clientY - top
      }
    },

    onMouseMove(e) {
      if (!this.isMove) return

      this.x = (e.clientX - this.offsetX) + 'px'
      this.y = (e.clientY - this.offsetY) + 'px'
    },

    onMouseUp() {
      this.isMove = false
    },

    debounce(func, wait = 1000) {
      let timeout
      return function (event) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          func.call(this, event)
        }, wait)
      }
    },

    handleNodeClick(e) {
      this.girdLevel = e.girdLevel
      this.isLoading = true
      console.log(e)
      this.getGirdInfo(e.id, e.girdLevel)
      this.getStatisticsInfo(e.id)
    },

    getStatisticsInfo(id) {
      this.instance.post(`/app/appgirdmemberinfo/girdMemberAndResidentStatistic?girdId=${id}`).then((res) => {
        if (res.code == 0) {
          this.userInfo = [
            {
              'name': '网格长',
              '人数': res.data['网格长'] || 0
            },
            {
              'name': '网格员',
              '人数': res.data['网格员'] || 0
            },
            {
              'name': '责任家庭数',
              '人数': res.data['责任家庭数'] || 0
            }
          ]
        }
      })

      this.instance.post(`/app/appclapeventinfo/clapEventStatistic?girdId=${id}`).then((res) => {
        if (res.code == 0) {
          this.eventInfo = Object.keys(res.data).map(v => {
            return {
              '事件类型': v,
              v1: res.data[v]
            }
          })
        }
      })
    },

    renderContent(h, node) {
      return h('div', {
        class: 'userlist-container'
      }, [h('div', {
        class: `userlist ${node.data.label === '子节点' ? 'last-level' : ''} ${node.data.girdLevel > 1 ? 'userlist-wrapper' : ''} userlist-${node.data.girdLevel}`
      }, node.data.userList.map(v => {
        return h('div', {
          class: `user-item user-item-${v.girdLevel}`
        }, [h('img', {
          class: 'user-img',
          attrs: {
            src: v.photo || this.defaultUrl
          },
          on: {
            dragstart: e => {
              e.preventDefault()
              e.stopPropagation()
              return false
            }
          }
        }), h('p', {
          class: 'user-p',
          attrs: {
            title: v.label,
            'data-id': v.id
          },
          on: {
            click: () => {
              if (node.data.label === '子节点') {
                this.getResidentInfo(v.id)
              }
            }
          }
        }, v.label), h('span', {
          class: 'user-span',
          style: {
            display: v.girdLevel === '2' ? 'block' : 'none',
            fontSize: v.girdLevel === '2' ? '12px' : ''
          }
        }, v.checkType ? (v.checkType === '1' ? '网格员' : '网格长') : '-')])
      })), h('div', {
        class: 'user-gridName',
        style: {
          display: node.data.label === '子节点' ? 'none' : 'block',
          color: 'rgba(255, 255, 255, 0.8)',
          fontSize: '12px',
          margin: '4px 0'
        }
      }, node.data.label)])
    },

    getResidentInfo(id) {
      this.isLoading = true
      this.instance.post(`/app/appresident/detail?id=${id}`).then((res) => {
        if (res.code == 0) {
          this.residentInfo.resident = res.data
          this.tableData = res.data.family || []
          this.isShowInfo = true
        }

        this.isLoading = false
      })
    },

    autoScale() {
      const treeWidth = this.$refs.middleTree.offsetWidth
      const containerWidth = this.$refs.container.offsetWidth
      this.scale = treeWidth < containerWidth ? 1 : containerWidth / treeWidth
      this.x = '50%'
      this.y = '50%'
    },

    getGirdInfo(id) {
      this.instance.post(`/app/appgirdinfo/listAllGirdAndMemberByTop?id=${id || ''}`).then((res) => {
        if (res.code == 0) {
          const chartData = this.formatList([res.data])
          console.log(chartData)
          this.chartData = chartData

          this.$nextTick(() => {
            if (id) {
              this.getUserList(id, chartData[0].id)
            } else {
              this.isLoading = false
              this.autoScale()
            }
          })
        }
      })
    },

    getUserList(id, parentId) {
      this.instance.post(`/app/appgirdmemberresident/listByGirdMember`, null, {
        params: {
          size: 1000,
          girdId: id
        }
      }).then(res => {
        if (res.code == 0) {
          const userList = res.data.records.map(v => {
            return {
              ...v,
              isLast: true,
              label: v.name
            }
          })

          this.isLoading = false

          if (!userList.length) {
            this.autoScale()
            return false
          }

          const node = this.$refs.VueOkrTree.getNode(parentId)
          this.$refs.VueOkrTree.append({
            id: new Date().getTime(),
            label: '子节点',
            userList: userList || []
          }, node)
          this.$nextTick(() => {
            this.autoScale()
          })
        }
      })
    },

    formatList(list) {
      return list.map(item => {
        let userList = []
        const girdMemberManageList = item.girdMemberManageList ? item.girdMemberManageList.map(v => {
          return {
            ...v,
            label: v.name,
            id: v.id,
            checkType: '2',
            girdName: item.girdName,
            girdLevel: item.girdLevel,
            isUser: true
          }
        }) : []
        const girdMemberList = item.girdMemberList ? item.girdMemberList.map(v => {
          return {
            ...v,
            label: v.name,
            id: v.id,
            checkType: '1',
            girdName: item.girdName,
            girdLevel: item.girdLevel,
            isUser: true
          }
        }) : []

        if (this.girdLevel === '2' && item.girdLevel === '2' && girdMemberList.length) {
          userList = girdMemberManageList
          item.girdList = [{
            girdLevel: '2',
            id: item.id,
            isUser: false,
            userList: girdMemberList,
            label: item.girdName,
            children: []
          }]
        } else {
          userList = [...girdMemberManageList, ...girdMemberList]
        }
        if (!userList.length) {
          userList = [{
            label: '-',
            id: item.id,
            girdLevel: item.girdLevel,
            girdName: item.girdName
          }]
        }

        const obj = {
          label: item.girdName,
          id: `${new Date().getTime()}-${item.id}`,
          girdLevel: item.girdLevel,
          isUser: false,
          userList: userList,
          children: item.girdList || []
        }

        if (obj.children && obj.children.length && this.girdLevel !== '2') {
          obj.children = this.formatList(obj.children)
        }

        return obj
      })
    },

    getTreeList() {
      this.instance.post('/app/appgirdinfo/listAll').then((res) => {
        if (res.code == 0) {
          this.treeList = [...res.data]

          this.$nextTick(() => {
            this.$refs.tree.setCurrentKey(res.data[0].id)
            this.getStatisticsInfo(res.data[0].id)
          })
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.griddv {
  display: flex;
  align-items: center;
  height: 100%;
  user-select: none;

  ::-webkit-scrollbar {
    width: 6px;
  }

  ::-webkit-scrollbar-track {
    border-radius: 5px;
    background: rgba(93, 163, 255, 0.1);
  }

  ::-webkit-scrollbar-thumb {
    border-radius: 5px;
    background: rgba(173, 208, 255, 0.5);
  }

  .grid-info {
    width: 100%;

    .grid-info__title {
      display: flex;
      align-items: center;
      margin-bottom: 20px;

      h2, span {
        color: #fff;
        font-size: 14px;
        font-weight: 500;
      }
    }
  }

  ::v-deep .el-dialog__body {
    padding: 10px 40px 30px;

    .el-table {
      background-color: transparent;
    }

    .el-table__body tr td:first-child .cell, .ai-table .el-table__header tr th:first-child .cell {
      padding-left: 0 !important;
    }

    .el-table th, .el-table tr {
      color: #fff;
      font-size: 14px;
      background-color: rgba(28, 39, 65, 0.9);
    }

    .el-table__row--striped, .el-table--striped .el-table__body tr.el-table__row--striped td {
      background-color: transparent !important;
    }

    .el-table__header-wrapper {
      display: none;
    }

    .el-table--enable-row-hover .el-table__body tr:hover > td, .el-table-filter {
      background-color: transparent;
    }
  }

  ::v-deep .el-dialog {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: 0 !important;
    transform: translate(-50%, -50%);
    background: rgba(2, 13, 43, 0.9);
    box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.5), inset 0px 0px 10px 0px #2C7CFF;
    border: 1px solid #2D65C9;

    .el-dialog__header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      background: transparent;
      box-shadow: none;

      h2 {
        color: #fff;
        font-size: 18px;
      }

      img {
        cursor: pointer;
        width: 16px;
        height: 16px;

        &:hover {
          opacity: 0.6;
        }
      }
    }

    .el-dialog__headerbtn {
      display: none;
    }
  }

  ::v-deep .userlist-container {
    .userlist {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 10px;
      background: rgba(76, 166, 255, 0.1);
      border: 1px solid rgba(255, 255, 255, 0.2);

      .user-item {
        margin-right: 10px;
        color: #fff;
        font-size: 0;

        &:last-child {
          margin-right: 0;
        }

        img {
          width: 58px;
          height: 80px;
          object-fit: cover;
          user-select: none;
        }

        p {
          max-width: 120px;
          margin: 4px 0 0 0;
          font-size: 19px;
          text-align: center;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }

        span {
          display: block;
          max-width: 120px;
          font-size: 17px;
          color: #9DD3FF;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }

        &.user-item-0 {
          img {
            width: 86px;
            height: 120px;
          }
        }

        &.user-item-2 {
          p {
            line-height: 14px;
            font-size: 12px;
            margin-bottom: 4px;
          }

          span {
            line-height: 14px;
          }

          img {
            width: 40px;
            height: 56px;
          }
        }
      }

      &.userlist-2 {
        justify-content: space-between;
        max-width: 130px;
        flex-wrap: wrap;
        padding-bottom: 0;
        width: fit-content;
        margin: 0 auto;

        .user-item {
          width: 48px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          margin-bottom: 10px;

          &:nth-of-type(2n) {
            margin-right: 0;
          }
        }
      }

      &.last-level {
        flex-wrap: wrap;
        max-width: 690px;
        font-size: 0;
        background: rgba(0, 0, 0, 0.1);
        border: 1px solid rgba(255, 255, 255, 0.2);
        padding: 12px 12px 0 12px;
        box-sizing: border-box;

        .user-item {
          margin-bottom: 12px;
        }

        img {
          display: none;
        }

        p {
          padding: 8px;
          font-size: 12px;
          background: #0B477D;
          border-radius: 4px;
        }

        span {
          display: none !important;
        }
      }
    }
  }

  * {
    box-sizing: border-box;
  }

  .griddv-title {
    display: flex;
    width: 320px;
    height: 62px;
    background-image: url(../assets/grid/title-bg.png);
    background-size: 100% 100%;

    h2 {
      width: 100%;
      height: 50px;
      line-height: 50px;
      padding-left: 24px;
      font-weight: 600;
      font-size: 20px;
      letter-spacing: 1px;
      color: #fff;
    }
  }

  & > div {
    height: 100%;
  }

  .right {
    display: flex;
    justify-content: space-between;
    flex-direction: column;
    width: 440px;
    margin-left: 20px;

    & > div {
      flex: 1;
      width: 100%;
      padding-bottom: 20px;
      background: rgba(7, 11, 35, 0.4);
      border: 1px solid #2D50B5;
      box-sizing: border-box;

      .right-chart {
        height: calc(100% - 82px);
        padding: 0 20px;
      }

      &:last-child {
        margin-top: 20px;
      }
    }
  }

  .middle {
    position: relative;
    flex: 1;
    margin-left: 20px;
    background: rgba(7, 11, 35, 0.4);
    border: 1px solid #2D50B5;
    overflow: hidden;

    #tree {
      display: flex;
      position: absolute;
      align-items: center;
      justify-content: center;
      left: 50%;
      top: 50%;
      padding: 20px;
      overflow: hidden;
      width: max-content;
      height: 300%;
    }

    ::v-deep .org-chart-container {
      display: flex;
      justify-content: center;

      .org-chart-node-children:before, .org-chart-node:after, .org-chart-node:last-child:before,
      .org-chart-node.is-leaf:before {
        border-radius: 0;
        border-color: #9CD7FF !important;
      }

      .vertical .org-chart-node:after, .vertical .org-chart-node:before {
        border-radius: 0;
        border-color: #9CD7FF !important;
      }

      .org-chart-node-label-inner {
        padding: 0 !important;
      }

      .org-chart-node-btn {
        margin-left: 0;
        transform: translateX(-50%);
      }

      .org-chart-node {
        // max-width: 500px;
      }
    }

    ::v-deep .org-chart-node-children {
      display: flex;
      justify-content: center;
    }
  }

  .left {
    width: 320px;
    background: rgba(7, 11, 35, 0.4);
    border: 1px solid #2D50B5;

    .griddv-tree {
      height: calc(100% - 62px);
      overflow-y: auto;
      margin: 0 8px;
      padding-bottom: 8px;
    }

    ::v-deep .el-tree {
      background: transparent;

      .el-tree-node__expand-icon {
        color: #eaeff9;
      }

      .el-tree-node__expand-icon.is-leaf {
        color: transparent;
      }

      .el-tree-node__content {
        height: 32px;
        color: #eaeff9;
        font-size: 14px;
        user-select: none;
        font-weight: normal !important;
        background: transparent;
      }

      .is-current > .el-tree-node__content, .el-tree-node__content:hover {
        background: linear-gradient(270deg, #4895D9 0%, #2D52CA 100%);
      }
    }
  }
}
</style>
