<template>
  <div class="gridMap">
    <ai-t-map :map.sync="map" :lib.sync="mapLib"/>
    <div class="drawer" ref="drawer">
      <div v-if="show" class="drawer-content">
        <b>网格地图</b>
        <div class="tree">
          <div class="input">
            <el-input placeholder="请输入网格名称"
                      v-model="filterText" size="mini" suffix-icon="el-icon-search"/>
          </div>
          <header class="header">
            <span>网格列表</span>
          </header>
          <div class="tree-div">
            <el-tree
                :data="treeObj.treeList"
                :props="treeObj.defaultProps"
                @node-click="handleNodeClick"
                node-key="id"
                ref="tree"
                :filter-node-method="filterNode"
                default-expand-all
                highlight-current
            >
            </el-tree>
          </div>
        </div>
      </div>
      <div class="rightBtn" :class="{show}" @click="show=!show">
        <i class="iconfont iconArrow_Right"/>
      </div>
    </div>
  </div>
</template>
<script>
import {mapState} from 'vuex'

export default {
  name: "AppGridMap",
  label: "网格地图",
  props: {
    instance: Function,
    dict: Object,
    permissions: Function,
  },
  data() {
    return {
      map: null,
      mapLib: null,
      show: true,
      retryMapCount: 0,
      polygons: [],

      drawer: false,
      filterText: "",
      treeObj: {
        treeList: [],
        defaultProps: {
          children: "girdList",
          label: "girdName",
        },
        defaultExpandedKeys: [],
      },

      path: [],
      searchObj: {
        onlineStatus: "",
        girdMemberName: "",
      },
      member: {
        memberList: [],
      },
      infoWindowHtml: "",
      marker: {},
      activeId: null,
    };
  },
  computed: {
    ...mapState(['user']),
  },
  created() {
    this.dict.load("onlineStatus")
    this.getTreeList().then(() => {
      this.getLeafNodes()
    })
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
  },
  methods: {
    filterNode(value, data) {
      if (!value) return true;
      return data.girdName.indexOf(value) !== -1;
    },
    getTreeList() {
      return this.instance.post(`/app/appgirdinfo/listAll`).then((res) => {
        if (res.code == 0) {
          this.treeObj.treeList = res.data;
        }
      })
    },
    getLeafNodes() {
      this.instance.post(`/app/appgirdinfo/listAll2`).then((res) => {
        if (res?.data) {
          let arr = []
          res.data.forEach(e => {
            if (e.points?.length > 0) {
              arr.push(e.points.map(p => [p.lng, p.lat]))
            }
          })
          this.renderGridMap(arr)
        }
      })
    },
    handleNodeClick(val) {
      let path = [];
      if (val?.points?.length > 0) {
        path = val.points.map(e => [e.lng, e.lat])
        this.renderGridMap([path])
      } else {
        this.$message.error("所选网格没有标绘!")
      }
    },
    renderGridMap(paths) {
      let {map, mapLib: TMap, retryMapCount} = this
      if (TMap) {
        const colors = ["#A194F4", "#7CBDF3", "#F3A57D", "#62D063", "#58DBDA", "#F7D151"]
        const fitBounds = (latLngList) => {
          // 由多边形顶点坐标数组计算能完整呈现该多边形的最小矩形范围
          if (latLngList.length === 0) {
            return null;
          }
          let boundsN = latLngList[0].getLat();
          let boundsS = boundsN;
          let boundsW = latLngList[0].getLng();
          let boundsE = boundsW;
          latLngList.forEach((point) => {
            point.getLat() > boundsN && (boundsN = point.getLat());
            point.getLat() < boundsS && (boundsS = point.getLat());
            point.getLng() > boundsE && (boundsE = point.getLng());
            point.getLng() < boundsW && (boundsW = point.getLng());
          });
          return new TMap.LatLngBounds(
              new TMap.LatLng(boundsS, boundsW),
              new TMap.LatLng(boundsN, boundsE)
          );
        }
        if (this.polygons.length > 0) {
          this.polygons.forEach(e => e.destroy())
          this.polygons = []
        }
        let bounds = []
        paths.forEach((path, i) => {
          let color = colors[i % colors.length]
          let polygon = new TMap.MultiPolygon({
            map, styles: {
              default: new TMap.PolygonStyle({
                showBorder: true,
                borderColor: color,
                borderWidth: 2,
                color: this.$colorUtils.Hex2RGBA(color, 0.1),
                borderDashArray: [10, 10]
              })
            },
            geometries: [{paths: path.map(e => new TMap.LatLng(e[1], e[0]))}]
          })
          this.polygons.push(polygon)
          bounds.push(fitBounds(path.map(e => new TMap.LatLng(e[1], e[0]))))
        })
        bounds = bounds.reduce((a, b) => {
          return fitBounds([
            a.getNorthEast(),
            a.getSouthWest(),
            b.getNorthEast(),
            b.getSouthWest(),
          ]);
        });
        map.fitBounds(bounds, {padding: 100})
      } else {
        if (retryMapCount < 5) {
          setTimeout(() => {
            this.retryMapCount++
            this.renderGridMap(paths)
          }, 1000)
        }
      }

    },
    hasClass(ele, cls) {
      return ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
    },
    addClass(ele, cls) {
      if (!this.hasClass(ele, cls)) ele.className += " " + cls;
    },
    removeClass(ele, cls) {
      if (this.hasClass(ele, cls)) {
        const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
        ele.className = ele.className.replace(reg, " ");
      }
    },
    changClass(ele, className) {
      if (!this.hasClass(ele, className)) {
        this.addClass(ele, className);
      } else {
        this.removeClass(ele, className);
      }
    },
    percentage() {
      if (this.member.onlineNumber == 0) {
        return 0;
      } else {
        return (
            100 *
            (this.member.onlineNumber / this.member.allMemberNumber)
        ).toFixed(2);
      }
    },
    getMemberList() {
      this.instance.post(`/app/appgirdmemberinfo/queryGirdMemberByMap`, this.searchObj).then((res) => {
        if (res.code == 0) {
          let markers = [];
          this.member = res.data;
          this.member.memberList.map((e) => {
            if (e.onlineStatus == "1") {
              markers.push({lng: e.lng, lat: e.lat, name: e.name});
            }
          });
          this.initMap(null, null, markers);
        }
      });
    },
    clickMember(marker) {
      if (marker.onlineStatus == 1) {
        this.activeId = marker.id;
        this.marker = marker;
        this.infoWindowContent(marker);
      }
    },
    infoWindowContent(marker) {
      this.instance
      .post(`/app/location/xyToAddress`, null, {
        params: {
          x: marker.lat,
          y: marker.lng,
        },
      })
      .then((res) => {
        if (res.code == 0) {
          this.infoWindowHtml = `<div class="info">
                                        <p>
                                            <span class="name">${marker.name}</span>
                                            <span class="lat">${marker.lng},${marker.lat}</span>
                                        </p>
                                        <p>
                                            <span class="lat">${res.data}</span>
                                        </p>
                                        <p class="address">
                                            <span class="iconfont iconarea" id="addressSpan">当日轨迹</span>
                                        </p>
                                    </div>`;
          this.initMap(false, marker);
        }
      });
    },
    queryTrajectory() {
      this.instance
      .post(`/app/appgirdmembertrajectory/queryTrajectory`, null, {
        params: {
          userId: this.marker.userId,
        },
      })
      .then((res) => {
        if (res.code == 0) {
          let path = [];
          if (res.data) {
            res.data.map((e, index) => {
              path[index] = [e.lng, e.lat];
            });
          }
          this.initMap(path, this.marker);
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.gridMap {
  height: 100%;
  width: 100%;
  position: relative;

  .drawer-btn {
    position: absolute;
    left: 280px;
    bottom: 0;
    top: 0;
    margin: auto;
    width: 20px;
    height: 24px;
    border-top: 40px solid transparent;
    border-bottom: 40px solid transparent;
    border-left: 16px solid #333c53;
    border-right: 0 solid transparent;
    transition: all 0.5s ease-in-out;
    cursor: pointer;

    .iconfont {
      position: absolute;
      font-size: 26px;
      color: rgb(255, 255, 255);
      left: -21px;
      top: -14px;
      transition: all 0.5s ease-in-out;
    }
  }

  .btn-hide {
    left: 0;
  }

  .drawer {
    width: 280px;
    height: 100%;
    position: absolute;
    z-index: 1000;
    top: 0;
    left: 0;
    visibility: visible;
    opacity: 1;
    transition: all 0.5s ease-in-out;
    display: flex;
    align-items: center;

    .drawer-content {
      width: 100%;
      height: 100%;
      padding: 0 16px;
      box-sizing: border-box;
      background: #333c53;

      & > b {
        color: #fff;
        font-size: 18px;
        line-height: 60px;
      }

      .tree {
        height: calc(100% - 28px - 76px);
        border-radius: 4px;
        overflow: hidden;

        .map-search {
          display: flex;
          padding: 8px 0;
          justify-content: space-between;

          ::v-deep .el-input__inner {
            color: #fff;
          }
        }

        .member-list {
          width: 100%;
          height: calc(100% - 44px - 28px);
          overflow: auto;
          padding: 0;
          margin: 0;

          li {
            width: 100%;
            height: 32px;
            display: flex;
            padding: 0 8px;
            align-items: center;
            color: #fff;
            margin: 0;
            cursor: pointer;

            span {
              padding-right: 8px;
            }
          }

          .active {
            background: #1d2336;
          }

          &::-webkit-scrollbar {
            /*滚动条整体样式*/
            width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
            height: 1px;
          }

          &::-webkit-scrollbar-thumb {
            /*滚动条里面小方块*/
            border-radius: 10px;
            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
            background: #1a1e2c;
          }

          &::-webkit-scrollbar-track {
            /*滚动条里面轨道*/
            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
            border-radius: 10px;
            background: #282f45;
          }
        }

        .empty {
          padding: 20px 0;
          color: #7a88bb;
          text-align: center;
        }

        .header {
          width: 100%;
          height: 28px;
          padding: 0 16px;
          box-sizing: border-box;
          display: flex;
          align-items: center;
          color: #fff;
          justify-content: space-between;
          font-size: 14px;
          background: #3e4a69;
        }

        .input {
          width: 100%;
          padding: 8px 0;

          ::v-deep .el-input__inner {
            color: #fff;
          }
        }

        ::v-deep .el-input__inner {
          background-color: #282f45;
          border: 1px solid #282f45;
        }

        .tree-div {
          width: 100%;
          height: calc(100% - 44px - 28px);
          overflow: auto;

          &::-webkit-scrollbar {
            /*滚动条整体样式*/
            width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
            height: 1px;
          }

          &::-webkit-scrollbar-thumb {
            /*滚动条里面小方块*/
            border-radius: 10px;
            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
            background: #1a1e2c;
          }

          &::-webkit-scrollbar-track {
            /*滚动条里面轨道*/
            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
            border-radius: 10px;
            background: #282f45;
          }
        }

        footer {
          width: 100%;
          height: 32px;
          background-color: #fff;
          display: flex;
          align-items: center;

          span {
            width: 33.33%;
            text-align: center;
            cursor: pointer;
          }
        }

        ::v-deep .el-tree {
          width: 100%;

          .el-tree__empty-block {
            background: #333c53;
          }

          .el-tree-node__label {
            color: #fff;
          }

          .el-tree-node__content {
            background: #333c53;
          }

          .is-current > .el-tree-node__content {
            .el-tree-node__label {
              color: #5088ff;
            }
          }
        }
      }
    }
  }

  .hide {
    left: -280px;
    opacity: 0;
    visibility: hidden;
  }

  .btn {
    position: absolute;
    top: 100px;
  }

  .rightBtn {
    width: 16px;
    height: 80px;
    background: url("https://cdn.cunwuyun.cn/monitor/drawerBtn.png");
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;

    .iconfont {
      transition: transform 0.2s;
    }


    &.show > .iconfont {
      transform: rotate(180deg);
    }
  }
}
</style>
<style lang="scss">
.map {
  .info {
    width: 280px;
    height: 98px;
    background: #fff;
    padding: 8px 0 0 12px;
    box-sizing: border-box;

    p {
      margin: 0;
      padding: 0;
    }

    p {
      line-height: 20px;

      .name {
        color: #333;
        font-size: 16px;
        font-weight: bold;
      }

      .lat {
        font-size: 12px;
        color: #999;
      }
    }

    .address {
      color: #999;
      line-height: 40px;
      font-size: 12px;
      cursor: pointer;
    }
  }

  .title_info {
    width: 68px;
    font-size: 14px;
    font-weight: bold;
    height: 20px;
    text-align: center;
    line-height: 20px;
    border-radius: 4px;
    padding: 0;
    margin: 0;
  }

  .amap-marker-label {
    border: 1px solid rgb(141, 139, 139);
    background-color: #fff;
  }
}
</style>
