<template>
  <div class="m-map">
    <div id="map"></div>
    <div
      class="btn"
      v-if="mapStyleType == 'light'"
      @click="shiftMapStyle('dark')"
    >
      切换深色模式
    </div>
    <div class="btn" v-else @click="shiftMapStyle('light')">切换浅色模式</div>
  </div>
</template>

<script>
import { requestPost } from "@/js/dai/request";
import cptCard from "@/views/modules/visual/cpts/card";
import cptTb from "@/views/modules/visual/cpts/tb";
import nextTick from "dai-js/tools/nextTick";
import { Scene, PolygonLayer, LineLayer, PointLayer } from "@antv/l7";
import { GaodeMap, Map } from "@antv/l7-maps";
import { spliceIntoChunks } from "@/utils/index";

let scene;
let polygonLayer;
let lineLayer;
let textLayer;
let posLayer;
let circleLayer;
let dotLayer;
let dotBgLayer;

export default {
  name: "l7",
  inject: ["refresh"],

  data() {
    return {
      mapStyleType: localStorage.getItem("mapStyle") || "dark",
      //   srcGridData: {},
      darkStyle: {
        style: "amap://styles/blue",
        polygonColor: [
          "rgba(255, 100, 60, 0.5)",
          "rgba(43, 231, 253, 0.35)",
          "rgba(255, 255, 50, 0.35)",
        ],
        lineColor: [
          "rgba(255, 180, 150, 0.9)",
          "rgba(43, 231, 253, 0.7)",
          "rgba(255, 255, 50, 0.7)",
        ],
        circleColor: [
          "rgba(255, 180, 150, 0.99)",
          "rgba(43, 231, 253, 0.99)",
          "rgba(255, 255, 50, 0.99)",
        ],
        textColor: [
          "rgba(255, 100, 60, 0.99)",
          "rgba(43, 231, 253, 0.99)",
          "rgba(255, 255, 50, 0.99)",
        ],
        textStrokeColor: "#fff",
      },

      lightStyle: {
        style: "amap://styles/whitesmoke",
        polygonColor: [
          "rgba(255, 100, 60, 0.3)",
          "rgba(43, 231, 253, 0.3)",
          "rgba(255, 255, 50, 0.3)",
        ],
        lineColor: [
          "rgba(220, 150, 120, 0.9)",
          "rgba(33, 201, 223, 0.8)",
          "rgba(200, 200, 50, 0.9)",
        ],
        circleColor: [
          "rgba(255, 180, 150, 0.99)",
          "rgba(13, 181, 203, 0.8)",
          "rgba(255, 255, 50, 0.99)",
        ],
        textColor: [
          "rgba(200, 50, 10, 0.99)",
          "rgba(0, 130, 153, 0.99)",
          "rgba(120, 120, 0, 0.99)",
        ],
        textStrokeColor: "#666",
      },
    };
  },

  props: {
    pitch: {
      type: Number,
      default: 60,
    },

    srcGridData: {
      type: Object,
      default: null,
    },

    dotList: {
      type: Array,
      default: () => [],
    },

    dotIcoList: {
      type: Object,
      default: () => ({}),
    },

    dotList2: {
      type: Array,
      default: () => [],
    },

    dotIcoList2: {
      type: Object,
      default: () => ({}),
    },
  },

  computed: {},

  components: {
    cptCard,
    cptTb,
  },

  watch: {},

  async mounted() {
    // 临时这么用吧
    window._AMapSecurityConfig = {
      securityJsCode: "92ea2c965c6cf1ba7ee3a8fe01449ef2",
    };

    this.iniMap();
  },

  computed: {
    polygonData() {
      const { srcGridData } = this;
      if (
        !srcGridData ||
        !srcGridData.children ||
        !Array.isArray(srcGridData.children)
      ) {
        return { type: "FeatureCollection", features: [] };
      }
      const polygon = [
        ...srcGridData.children
          .filter((item) => item.coordinates.length > 0)
          .map((item) => ({
            type: "Feature",
            properties: {
              //   id: item.id,
              //   name: item.name,
              //   level: item.level,
              center: [item.longitude, item.latitude],
              ...item,
            },
            geometry: {
              type: "Polygon",
              coordinates: [
                spliceIntoChunks(
                  item.coordinates.split(",").map((item) => parseFloat(item)),
                  2
                ).filter((item) => item.length == 2),
              ],
            },
          })),
      ];
      return { type: "FeatureCollection", features: polygon };
    },

    polygonDotData() {
      const { srcGridData } = this;
      if (
        !srcGridData ||
        !srcGridData.children ||
        !Array.isArray(srcGridData.children)
      ) {
        return { type: "FeatureCollection", features: [] };
      }
      const polygon = [
        ...srcGridData.children
          .filter((item) => item.coordinates.length > 0)
          .map((item) => ({
            type: "Feature",
            properties: {
              //   id: item.id,
              //   name: item.name,
              //   level: item.level,
              center: [item.longitude, item.latitude],
              ...item,
            },
            geometry: {
              type: "Polygon",
              coordinates: [
                item.latitude
                  ? [[item.longitude, item.latitude]]
                  : spliceIntoChunks(
                      item.coordinates
                        .split(",")
                        .map((item) => parseFloat(item)),
                      2
                    ).filter((item) => item.length == 2),
              ],
            },
          })),
      ];
      return { type: "FeatureCollection", features: polygon };
    },

    dotData() {
      const { dotList } = this;
      return {
        type: "FeatureCollection",
        features: [
          ...dotList
            .filter((item) => item.latitude)
            .map((item) => ({
              type: "Feature",
              properties: {
                ...item,
              },
              geometry: {
                type: "Point",
                coordinates: [
                  parseFloat(item.longitude),
                  parseFloat(item.latitude),
                ],
              },
            })),
        ],
      };
    },

    
    dotData2() {
      const { dotList2 } = this;
      return {
        type: "FeatureCollection",
        features: [
          ...dotList2
            .filter((item) => item.latitude)
            .map((item) => ({
              type: "Feature",
              properties: {
                ...item,
              },
              geometry: {
                type: "Point",
                coordinates: [
                  parseFloat(item.longitude),
                  parseFloat(item.latitude),
                ],
              },
            })),
        ],
      };
    },
  },

  watch: {
    srcGridData(val, oldValue) {
      if (oldValue == null) {
        this.iniMap();
      } else {
        this.updateGrid();
      }
      this.zoomInABit();
    },
    dotList(val, oldValue) {
      this.updateDot();
    },
    dotList2(val, oldValue) {
      this.updateDot();
    },
  },

  methods: {
    iniMap() {
      const { darkStyle, lightStyle, srcGridData } = this;
      if (!srcGridData) return false;

      let styleConfig = darkStyle;
      if (this.mapStyleType == "light") {
        styleConfig = lightStyle;
      }

      scene = new Scene({
        id: "map",
        logoVisible: false,
        map: new GaodeMap({
          pitch: this.pitch,
          style: styleConfig.style,
          center: [
            srcGridData.longitude ||
              this.$store.state.user.longitude ||
              116.39743841556731,
            srcGridData.latitude ||
              this.$store.state.user.latitude ||
              39.9088810666821,
          ],
          token: "fc14b42e0ca18387866d68ebd4f150c1",
          zoom: 18,
          isHotspot: false,
          resizeEnable: true,
          doubleClickZoom: false,
        }),
      });

      scene.on("loaded", async () => {
        this.iniMapGrid(scene);
        this.iniMapDot(scene);
        this.iniMapDot2(scene);
        await nextTick(0);
        this.zoomInABit();
      });
    },

    iniMapGrid(scene) {
      const { darkStyle, lightStyle, polygonData, polygonDotData } = this;

      let styleConfig = darkStyle;
      if (this.mapStyleType == "light") {
        styleConfig = lightStyle;
      }

      console.log("地图初始化数据", polygonData);

      polygonLayer = new PolygonLayer({
        autoFit: true,
      })
        // .size(0)
        .source(polygonData)
        .color("name", styleConfig.polygonColor)
        //   .shape("extrude")
        .shape("fill")
        .style({
          opacityLinear: {
            enable: true, // true - false
            dir: "out", // in - out
          },
          opacity: 1,
          // heightfixed: true,
          // pickLight: true,
          raisingHeight: 0,
          // sourceColor: "#333",
          // targetColor: "rgba(255,255,255, 0.5)",
        });

      scene.addLayer(polygonLayer);

      lineLayer = new LineLayer({
        zIndex: 2,
        name: "line2",
      })
        .source(polygonData)
        .shape("line")
        .size(1)
        .color("name", styleConfig.lineColor)
        .style({
          opacity: 1,
        })
        .animate({
          interval: 1, // 间隔
          duration: 2, // 持续时间，延时
          trailLength: 2, // 流线长度
        });
      scene.addLayer(lineLayer);

      circleLayer = new PolygonLayer({
        zIndex: 3,
      })
        .source(polygonDotData)
        .color("name", styleConfig.circleColor)
        .shape("circle")
        .active(true)
        .animate(true)
        .size(50)
        .style({
          offsets: [0, -10], // 文本相对锚点的偏移量 [水平, 垂直]
          opacity: 1,
        });
      scene.addLayer(circleLayer);

      scene.addImage("pos-red", require("@/assets/img/shuju/grid/pos-red.png"));
      scene.addImage(
        "pos-green",
        require("@/assets/img/shuju/grid/pos-green.png")
      );
      scene.addImage(
        "pos-yellow",
        require("@/assets/img/shuju/grid/pos-yellow.png")
      );
      posLayer = new PolygonLayer({
        zIndex: 4,
      })
        .source(polygonDotData)
        .shape("name", ["pos-red", "pos-green", "pos-yellow"])
        .size(12)
        .style({
          offsets: [0, 8], // 文本相对锚点的偏移量 [水平, 垂直]
          // rotation: 60,
          layerType: "fillImage",
        });
      scene.addLayer(posLayer);

      textLayer = new PolygonLayer({
        zIndex: 20,
      })
        .source(polygonDotData)
        .color("name", styleConfig.textColor)
        .shape("name", "text")
        .size(16)
        .style({
          textAnchor: "center", // 文本相对锚点的位置 center|left|right|top|bottom|top-left
          textOffset: [0, 40], // 文本相对锚点的偏移量 [水平, 垂直]
          spacing: 2, // 字符间距
          padding: [2, 2], // 文本包围盒 padding [水平，垂直]，影响碰撞检测结果，避免相邻文本靠的太近
          stroke: styleConfig.textStrokeColor, // 描边颜色
          strokeWidth: 0.1, // 描边宽度
          strokeOpacity: 0.8,
          textAllowOverlap: true,
        })
        .active(true);
      scene.addLayer(textLayer);

      polygonLayer.on("mousemove", (e) => {
        polygonLayer.style({
          raisingHeight: 0,
        });
      });

      polygonLayer.on("click", (e) => {
        console.log(e.feature.properties);
        this.$emit("clickAgency", e.feature.properties);
      });

      polygonLayer.on("unmousemove", (e) => {
        polygonLayer.style({
          raisingHeight: 0,
        });
      });
    },

    iniMapDot(scene) {
      const { darkStyle, lightStyle, dotIcoList, dotData } = this;
      Object.keys(dotIcoList).forEach((k) => {
        scene.addImage(k, dotIcoList[k]);
      });
      dotBgLayer = new PointLayer({
        zIndex: 20,
      })
        .source(dotData)
        .shape("circle")
        .color("rgba(255,255,255,0.8)")
        .size(20)
        .style({
          strokeWidth: 3,
          strokeOpacity: 0.1,
          stroke: "#000",
        });
      scene.addLayer(dotBgLayer);

      dotLayer = new PointLayer({
        zIndex: 21,
      })
        .source(dotData)
        .shape("categoryKey", (k) => k)
        .size(10)
        .style({
          offsets: [0, 0],
          layerType: "fillImage",
        });
      scene.addLayer(dotLayer);

      dotBgLayer.on("click", (e) => {
        console.log(e.feature.properties);
        this.$emit("clickDot", e.feature.properties);
      });

      dotBgLayer.on("mousemove", (e) => {
        // console.log(e);
        if (e.feature.properties.content) {
          const popup = new Popup({
            offsets: [0, -0],
            closeButton: false,
          })
            .setLnglat(e.feature.geometry.coordinates)
            .setHTML(`<span>${e.feature.properties.content}</span>`);
          scene.addPopup(popup);
        }
      });

      dotBgLayer.on("unmousemove", (e) => {});
    },

    iniMapDot2(scene) {
      const { dotIcoList2: dotIcoList, dotData2: dotData } = this;
      Object.keys(dotIcoList).forEach((k) => {
        scene.addImage(k, dotIcoList[k]);
      });

      dotLayer2 = new PointLayer({
        zIndex: 21,
      })
        .source(dotData)
        .shape("categoryKey", (k) => k)
        .size(20)
        .style({
          offsets: [0, 0],
          layerType: "fillImage",
        });
      scene.addLayer(dotLayer2);

      dotLayer2.on("click", (e) => {
        console.log(e.feature.properties);
        this.$emit("clickDot", e.feature.properties);
      });

      dotLayer2.on("mousemove", (e) => {
        // console.log(e);
        if (e.feature.properties.content) {
          const popup = new Popup({
            offsets: [0, -0],
            closeButton: false,
          })
            .setLnglat(e.feature.geometry.coordinates)
            .setHTML(`<span>${e.feature.properties.content}</span>`);
          scene.addPopup(popup);
        }
      });

      dotLayer2.on("unmousemove", (e) => {});
    },

    // 把地图缩放等级在原来基础上大一点
    zoomInABit() {
      let current = scene.getZoom();
      scene.setZoomAndCenter(current + 0.5);
    },

    shiftMapStyle(type) {
      this.mapStyleType = type;
      localStorage.setItem("mapStyle", type);
      this.refresh();
    },

    updateMap() {
      this.updateGrid();
      this.updateDot();
      this.updateDot2();
    },

    updateGrid() {
      const { polygonData } = this;
      if (polygonLayer) {
        polygonLayer.setData(polygonData);
        lineLayer.setData(polygonData);
        textLayer.setData(polygonData);
        posLayer.setData(polygonData);
        circleLayer.setData(polygonData);
      }
    },

    updateDot() {
      const { dotData } = this;
      if (dotLayer) {
        console.log(dotData);
        dotLayer.setData(dotData);
        dotBgLayer.setData(dotData);
      }
    },

    updateDot2() {
      const { dotData2: dotData } = this;
      if (dotLayer2) {
        console.log(dotData);
        dotLayer2.setData(dotData);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.m-map {
  position: relative;
  height: 100%;
  border-radius: 10px;
  overflow: hidden;

  #app {
    width: 100%;
    height: 100%;
  }
  .btn {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100px;
    line-height: 36px;
    height: 36px;
    text-align: center;
    color: #ffffff;
    font-size: 14px;
    background-color: rgba(#000, 0.2);
    cursor: pointer;
  }
}
</style>
