<template>
  <div ref="map" class="full">
    <div class="container-main center">
      <!--        <div  v-loading="loading"  element-loading-text="网格加载中"-->
      <!--              element-loading-background="rgba(0, 0, 0, 0.5)"  style="height: 100%;width: 100%;background: rgba(0,0,0,0.5);">-->
      <div v-if="mode==='none'" class="tools-bar center" style="background-color: rgba(49, 68, 108,1);z-index: 9999;">
          <el-dropdown trigger="click" size="mini" style="margin: 20px">
            <div style="color: #dddddd;font-size: 15px">
              <icon style="font-size: 22px;margin-right: 5px" class="el-icon-map-location"></icon>
              当前所在网格：{{grid.gridName}}
              <icon style="font-size: 16px;margin-left: 5px" class="el-icon-arrow-down"></icon>
            </div>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item :key="item.id" v-for="(item,index) of userInfo.grid">
                  <div @click="onLoad(item.id)">{{item.gridName}}</div>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-button v-if="grid.newable==1" class="button" @click="paint">新建网格区域</el-button>
          <div v-else>
            <el-button class="button" disabled>当前网格不支持新建网格区域</el-button>
          </div>
          <el-button class="button" @click="edit(grid)">编辑当前网格</el-button>
          <el-button v-if="grid.boundsType!='system'" class="button" style="background: rgba(255,30,30,0.41)"
            @click="deleteGrid(grid.id)">删除当前网格</el-button>
          <el-button v-if="!isMyGrid(grid.id)" class="button" @click="back()">返回上一级网格</el-button>
      </div>

      <div v-else class="tools-bar" style="background: rgba(150,56,56,0.5)">
        <el-button class="button" @click="finish">绘制完成</el-button>
        <el-button class="button" @click="reset">重置</el-button>
        <el-button class="button" @click="cancel">退出</el-button>
        <div style="color: #dddddd">鼠标在地图上单击开始绘制多边形，鼠标左键双击或右键单击结束当前多边形的绘制</div>
      </div>
      <div id="container" class="full"></div>
      <my-dialog ref="bingDialog" @close="editClose">
        <avue-form :key="keyIndex" v-model="form" :option="option" @submit="update">
        </avue-form>
      </my-dialog>
    </div>
  </div>
</template>
<script>
  import {
    mapGetters
  } from "vuex";
  import {
    add,
    getAgencysByAreaCode,
    getDetail,
    getList,
    remove,
    update
  } from "../../api/grid/grid";
  import GridDetail from "../../components/form/gridDetail";
  import MyDialog from "../../components/myDialog";

  export default {
    components: {
      MyDialog,
      GridDetail
    },
    data() {
      return {
        keyIndex: 0,
        resourceList: [],
        currentGridIndex: 0,
        form: {},
        detail: {},
        zoom: '7',
        agencyList: [],
        features: ['bg', 'road', 'building'],
        loading: false,
        center: [106.278179, 50.46637],
        grid: {},
        polygon: [],
        currentGridPolygon: [],
        newGrid: {},
        subGridList: [],
        gridDetailVisible: false,
        mode: 'none',
        skyColor: '#026D71',
        map: {},
        AMap: {},
        mouseTools: {},
        polyEdit: {},
      };
    },
    async mounted() {
      await this.onLoad();
    },
    computed: {
      ...mapGetters(["userInfo"]),
      option() {
        return {
          size: 'mini',
          submitText: '完成',
          column: [{
              label: '网格名称',
              prop: 'gridName',
              rules: [{
                required: true,
                message: "请输入网格名称",
                trigger: "blur"
              }]
            },
            {
              label: '网格颜色',
              prop: 'gridColor',
              type: 'color',
              rules: [{
                required: true,
                message: "请输入网格名称",
                trigger: "blur"
              }]
            },
            {
              label: '网格员',
              prop: 'userCode',
              type: 'select',
              dataType: 'string',
              multiple: true,
              dicUrl: '/api/blade-user/page',
              props: {
                label: 'realName',
                value: 'id',
                res: 'data.records'
              },
              rules: [{
                required: true,
                message: "请选择网格员",
                trigger: "blur"
              }]
            }
            // {
            //   label: '网格员',
            //   prop: 'userCode',
            //   component: 'lazySelect',
            //   params: {
            //     dicUrl: '/api/blade-user/page',
            //     code: 'id',
            //     title: 'realName',
            //     // query: {
            //     //   deptId: '1369890156940664833',
            //     // },
            //     size: 10
            //   },
            //   event: {
            //     change: (data)=>{
            //       this.form['userCode'] = data.id;
            //     }
            //   },
            //   // type: 'select',
            // }
          ],
        }
      }
    },
    watch: {
      $route() {
        if (this.$route.path == '/grid/divide') {
          this.$store.commit('SET_TAG_INDEX', 1);
          this.map.resize()
        }
      },
    },
    methods: {
      isMyGrid(id) {
        for (let item of this.userInfo.grid) {
          if (id == item.id) {
            return true
          }
        }
        return false;
      },
      async getBounds(code, config) {
        const _this = this;
        return new Promise((resolve, reject) => {
          let districtSearch = new _this.AMap.DistrictSearch(config);
          districtSearch.search(code, (x, y) => {
            resolve(y.districtList[0].boundaries);
          });
        })
      },
      paint() {
        const _this = this;
        this.mode = 'polygon';
        this.polygon = [];
        this.map.setPitch(0);
        this.form = {
          gridColor: "#5abbec"
        }
        this.mouseTools.polygon({
          strokeColor: "#FF33FF",
          strokeWeight: 6,
          strokeOpacity: 0.2,
          fillColor: '#1791fc',
          fillOpacity: 0.4,
          strokeStyle: "solid",
        })
      },
      cancel() {
        this.mode = 'none';
        this.map.remove(this.newGrid);
        this.polygon = [];
        this.polyEdit.close();
        this.map.setPitch(50);
      },
      isInRing() {
        const _this = this;
        let result = false;
        this.currentGridPolygon.forEach(item => {
          console.log(_this.AMap.GeometryUtil.isRingInRing(_this.polygon, item))
          if (_this.AMap.GeometryUtil.isRingInRing(_this.polygon, item)) {
            result = true;
          }
        })
        return result;
      },
      finish() {
        this.polyEdit.close();
        if (this.polygon.length == 0) {
          layer.msg("请先绘制网格区域！")
          return
        }
        if (!this.isInRing()) {
          layer.alert("请确保绘制网格区域在当前网格内！")
          this.polyEdit.open();
          return
        }
        this.generateResourceList();
        console.log(this.resourceList);
        this.$refs['bingDialog'].show();
      }, //网格绘制完成
      edit(grid) {
        this.form = grid;
        this.$refs['bingDialog'].show();
      }, //打开编辑网格表单
      editClose() {
        if (this.mode == 'polygon') {
          this.polyEdit.open();
        }
      }, //关闭表单回调
      back() {
        this.onLoad(this.grid.pid);
      }, //返回上级网格
      reset() {
        this.map.remove(this.newGrid);
        this.polygon = [];
        this.paint();
        this.polyEdit.close();
      }, //重置绘画
      async update(loading, done) {
        if (this.mode == "none") {
          update(this.form).then(() => {
            done();
            this.$refs['bingDialog'].hide();
            layer.msg("操作成功！");
            this.onLoad(this.grid.id);
          })
        } else {
          this.mode = 'none';
          this.form.pid = this.grid.id;
          this.form.type = "community";
          this.form.zoom = this.map.getZoom();
          this.form.boundsType = "customer";
          this.form.bounds = JSON.stringify(this.polygon);
          this.form.newable = 1;
          this.form.resourceList = this.resourceList.join(',');
          let center = this.newGrid.getBounds().getCenter();
          this.form.center = JSON.stringify([center.getLng(), center.getLat()])
          add(this.form).then(() => {
            layer.msg("添加网格成功！");
            this.onLoad(this.grid.id);
          }).catch(res => {
            layer.msg(res)
          })
          done();
          this.map.setPitch(50);
          this.$refs['bingDialog'].hide();
        }

      }, //修改或新增网格
      async initSubGridBounds(list) {
        const _this = this;
        if (list.length == 0) {
          return;
        }

        let polygons = [];
        for (let item of list) {
          let data = JSON.parse(item.bounds);
          item.bounds = item.boundsType == 'system' ? await this.getBounds(data["search"], data["config"]) : [data];
          let marker = new _this.AMap.Marker({
            position: JSON.parse(item.center),
            content: "<div style='color: #dddddd;font-family:Arial,Helvetica,sans-serif'>" + item.gridName +
              "</div>",
          });
          _this.map.add(marker);
          for (let ele of item.bounds) {
            //生成行政区划polygon
            let polygon = new _this.AMap.Polygon({
              strokeWeight: 1,
              path: ele,
              fillOpacity: 0.4,
              fillColor: item.gridColor,
              strokeColor: item.gridColor,
              extData: {
                grid: item
              }
            });
            polygon.on('click', (e) => {
              _this.showGridDetail(polygon.getExtData().grid)
            })
            polygon.on('mouseover', () => {
              polygon.setOptions({
                fillOpacity: 0.7,
              })
            })
            polygon.on('dblclick', () => {
              this.onLoad(polygon.getExtData().grid.id)
            })
            polygon.on('mouseout', () => {
              polygon.setOptions({
                fillOpacity: 0.3,
              })
            })

            polygons.push(polygon);
          }
        }
        _this.map.add(polygons)
        _this.map.setFitView(polygons);
      }, //渲染当前网格下的所有子网格
      async initGrid(grid) {
        this.map.setCenter(JSON.parse(grid.center));
        this.map.setZoom(grid.zoom);
        let data = JSON.parse(grid.bounds);
        let paths = (grid.boundsType == 'system' ? await this.getBounds(data["search"], data["config"]) : [data]);
        this.currentGridPolygon = paths;
        for (let item of paths) {
          let polyline = new this.AMap.Polyline({
            strokeColor: grid.gridColor,
            borderWeight: 100,
            strokeWeight: 6,
            path: item,
          });
          this.map.add(polyline);
        }
      }, //初始化地图，当前网格员所管理的网格
      async getMap() {
        let _this = this;
        return new Promise((resolve, reject) => {
          this.$AMap.load({
            key: 'cbb265e2a60bbbc04a52eec4eecdeb12',
            version: '2.0',
            resizeEnable: true,
            plugins: ['AMap.DistrictSearch', 'AMap.ControlBar', 'AMap.Object3DLayer', 'AMap.MouseTool',
              'AMap.PolygonEditor'
            ]
          }).then((AMap) => {
            let map = new AMap.Map('container', {
              zoom: 11,
              pitch: 50,
              doubleClickZoom: false,
              viewMode: '3D',
              skyColor: '#7e7b9b',
              roofColor: '#38665c',
              wallColor: '#385b54',
              showLabel: true,
              mapStyle: 'amap://styles/macaron'
            });
            var buildingLayer = new AMap.Buildings({
              heightFactor: 2,
              zooms: [20, 20],
              zIndex: 2
            });
            map.addLayer(buildingLayer);
            map.addControl(new AMap.ControlBar({
              position: {
                top: '80px',
                left: '10px'
              }
            }))
            _this.AMap = AMap;
            _this.map = map;
            _this.setMouseTools();
            resolve();
          })
        })
      }, //获取高德地图对象（map 以及 AMap）
      setMouseTools() {
        const _this = this;
        let mouseTool = new this.AMap.MouseTool(_this.map);
        this.mouseTools = mouseTool;
        this.mouseTools.on('draw', function(event) {
          let newGrid = new _this.AMap.Polygon({
            strokeColor: "#FF33FF",
            strokeWeight: 6,
            strokeOpacity: 0.2,
            fillColor: '#1791fc',
            fillOpacity: 0.4,
            strokeStyle: "solid",
            path: event.obj._opts.path
          })
          _this.newGrid = newGrid;

          _this.mouseTools.close(true);

          _this.setPolyEditor(newGrid);
          _this.map.add(newGrid);
          _this.polyEdit.open();
        })
      }, //设置鼠标绘制工具
      setPolyEditor(polygon) {
        const _this = this;
        let polyEditor = new _this.AMap.PolygonEditor(_this.map, polygon);
        polyEditor.on('end', function(res) {
          _this.polygon = res.target._opts.path;
          _this.polygon.push(_this.polygon[0])
        })
        _this.polyEdit = polyEditor;
      }, //设置多边形编辑器
      showGridDetail(grid) {
        let realName = (typeof grid.user.realName) == 'undefined' ? '暂未绑定网格员' : grid.user.realName;
        let imgSrc = (typeof grid.user.avatar) == 'undefined' ?
          'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3159037829,1721246489&fm=26&gp=0.jpg' : grid.user
          .avatar;
        let infoWindow = new this.AMap.InfoWindow({
          content: `
            <div style="width: 300px;height: 200px;color: rgb(0, 186, 189);">
                <table   style="width: 100%;height: 100%;text-align: left" >
                    <tr>
                      <th style="width: 120px" rowspan="2">
                        <img style="width: 115px;height: 150px;border-radius: 5px" src="` + imgSrc + `" />
                      <th style="height: 30px" colspan="2">` + grid.gridName + `</th>
                    </tr>
                    <tr>
                      <th>
                        <div style="width: 100%;height: 100%;padding: 5px;font-weight: normal">
                            网格员：` + realName + `</br>
                            所属网格：` + this.grid.gridName + `</br>
                            网格颜色： <div style="display: inline-block;width: 15px;height: 15px;background: ` + grid
            .gridColor + `;border-radius: 1px"></div></br>
                            网格坐标：` + grid.center + `</br>
                        </div>
                      </th>
                    </tr>
                </table>
            </div>
          `
        });
        infoWindow.open(this.map, JSON.parse(grid.center));
      },
      async initAgencyList(list) {
        const _this = this;
        list.forEach((item, index) => {
          if (item['longitude'] != '' && item['latitude'] != '') {
            let marker = new AMap.Marker({
              position: new AMap.LngLat(item['longitude'], item['latitude']),
              offset: new AMap.Pixel(-10, -10),
              label: {
                direction: 'top',
                content: item.agencyName,
              },
            });
            _this.map.add(marker);
          }
        })
      },
      deleteGrid(id) {
        const _this = this;
        layer.confirm('删除后的数据将不能恢复！，确定删除当前网格吗？', {
            btn: ['删除', '取消'] //按钮
          },
          function() {
            remove(id).then(res => {
              layer.msg('删除成功');
              _this.$router.go(0);
            })
          },
          function() {

          });

      },
      generateResourceList() {
        const _this = this;
        console.log(this.polygon, 'polygon')
        this.agencyList.forEach(item => {
          if (item['longitude'] != '' || item['latitude'] != '') {
            if (_this.AMap.GeometryUtil.isPointInRing([(item['longitude']), item['latitude']], _this.polygon)) {
              _this.resourceList.push(item.id)
            }
          }
        })
      },
      async onLoad(id) {
        this.$store.commit('SET_LOADING', true);
        this.loading = true;
        let grids = (await getList(1, 100, {
          userCode: this.userInfo['user_id']
        })).data.data.records;
        this.userInfo.grid = grids;
        this.$store.commit('SET_USER_INFO', this.userInfo);
        await this.getMap();
        this.form = {};
        this.keyIndex++; //重载表单虚拟dom，防止表单数据残留
        this.mode = 'none';
        const grid = typeof id == 'undefined' ? this.userInfo.grid[this.currentGridIndex] : (await getDetail({
          "id": id
        })).data.data;
        this.grid = grid;
        await this.initGrid(grid);
        const gridList = (await getList(1, 100, {
          pid: grid.id
        })).data.data.records;
        this.subGridList = await this.initSubGridBounds(gridList);
        if (grid.boundsType == 'system' && grid.newable == 1) {
          this.agencyList = (await getAgencysByAreaCode({
            areaCode: grid.areaCode
          })).data.data;
          await this.initAgencyList(this.agencyList);
        }
        this.$store.commit('SET_LOADING', false);

      },
    },

  };
</script>

<style scoped>
  .full {
    margin: 0;
    padding: 0px;
    width: 100%;
    height: 100%;
  }

  .tools-bar {
    width: 100%;
    height: 60px;
    background: rgba(0, 0, 0, 0.5);
    position: absolute;
    top: 0;
    z-index: 9;
  }

  .center {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .button {
    margin: 10px;
    color: white;
    border-radius: 0px;
    background: rgba(4, 4, 4, 0.5);
  }

  .container-main {
    width: 100%;
    height: 100%;
  }

  .activeTitle {
    font-size: 55px;
    background: #00a680;
  }

  /deep/ .amap-marker-label {
    position: absolute;
    z-index: 2;
    border: 0px solid #f8f8f8;
    background-color: #103b0e;
    white-space: nowrap;
    color: rgb(0, 186, 189);
    cursor: default;
    padding: 3px;
    font-size: 12px;
    line-height: 14px;
  }

  /deep/ .amap-info-content {
    position: relative;
    background: rgba(97, 99, 99, 0.7);
    padding: 10px 18px 10px 10px;
    line-height: 1.4;
    overflow: auto;
  }
</style>
