import { Message } from "@arco-design/web-vue";
import * as echarts from "echarts";
import { FlyLineFormat, mapFlyLineFormat, mapPointFormat, defaultFlyLineFormat } from "./interface";
/** 地图类 */
export class Map {
  /** 是否开启下钻 */
  static isDrill = true;
  /** 地图名称 */
  static mapName = "";
  /** 层级列表 */
  static mapList: string[] = [];
  /** 地图数据列表 */
  static mapJsonList: { [key: string]: any } = {};
  /** 地图配置项 */
  static option = {
    backgroundColor: "black",
    tooltip: {
      show: true,
      trigger: "axis",
      alwaysShowContent: false,
      backgroundColor: "black",
      borderColor: "black",
      showDelay: 0,
      hideDelay: 100,
      triggerOn: "mousemove",
      enterable: true,
      textStyle: {
        color: "#DADADA",
        fontSize: "12",
        width: 20,
        height: 30,
        overflow: "break",
      },
    },
    geo: {
      map: "",
      roam: true,
      zlevel: 1,
      zoom: 1.2,
      label: {
        show: true,
        color: "white",
      },
      itemStyle: {
        areaColor: "rgba(6, 49, 96, 1)",
        borderColor: "rgba(255, 255, 255, 0.3500)",
        borderType: "dashed",
        borderWidth: 0,
      },
      emphasis: {
        itemStyle: {
          borderWidth: 0,
        },
        label: {
          color: "white",
        },
      },
      tooltip: {
        show: true,
      },
      regions: [] as any[],
    },
    series: [] as any[],
  };
  /** 飞线系列 */
  static flySeries = {
    type: "lines",
    zlevel: 10,
    effect: {
      show: true,
      period: 6,
      trailLength: 0.7,
      color: "orange",
      symbol: "",
      symbolSize: 5,
    },
    lineStyle: {
      show: true,
      color: "#F56C6C",
      width: 2,
      opacity: 0.4,
      curveness: 0.2,
    },
    data: [] as FlyLineFormat[],
  };
  /** 飞线列表 */
  static flyLineList: mapFlyLineFormat[] = [];
  /** 点位系列 */
  static pointSeries = {
    type: "effectScatter",
    coordinateSystem: "geo",
    zlevel: 10,
    geoIndex: 0,
    symbolSize: 8,
    itemStyle: {
      color: "#b02a02",
    },
    encode: {
      tooltip: 2,
    },
    data: [] as any[],
  };
  /** 点位列表 */
  static pointList: mapPointFormat[] = [];

  /**
   * 设置飞线
   * @param flyLine 飞线数据
   */
  static setFlyLine(flyLine: (defaultFlyLineFormat | FlyLineFormat)[]) {
    const geoJson = this.mapJsonList[this.mapName]; // 获取地图

    flyLine.forEach((e) => {
      const t: FlyLineFormat = {
        fromName: "",
        toName: "",
        coords: [[], []],
      };
      // 默认飞线
      if (Array.isArray(e)) {
        if (e[0] && e[1]) {
          geoJson.features.forEach((v: any) => {
            if (e[0] === v.properties.name) {
              t.fromName = v.properties.name;
              t.coords[0] = [...v.properties.center];
            }
            if (e[1] === v.properties.name) {
              t.toName = v.properties.name;
              t.coords[1] = [...v.properties.center];
            }
          });
          this.flySeries.data.push(t);
        }
      }
      // 自定义
      else {
        this.flySeries.data.push(e);
      }
    });

    // 添加至飞线数据列表 方便切换地图后存储
    this.flyLineList.push({
      map: this.mapName,
      data: this.flySeries.data,
    });

    // 添加至配置项
    this.option.series.push(this.flySeries);
  }

  /**
   * 设置点位
   * @param point 点位数据
   */
  static setPoint(point: (string | any)[]) {
    const geoJson = this.mapJsonList[this.mapName];

    point.forEach((e) => {
      // 默认点位
      if (typeof e === "string") {
        geoJson.features.forEach((v: any) => {
          if (v.properties.name === e) {
            this.pointSeries.data.push({
              name: e,
              value: [...v.properties.center, 100],
            });
          }
        });
      }
      // 自定义
      else {
        this.pointSeries.data.push(e);
      }
    });

    // 添加至点位数据列表 方便切换地图后存储
    this.pointList.push({
      map: this.mapName,
      data: this.pointSeries.data,
    });

    // 添加至配置项
    this.option.series.push(this.pointSeries);
  }

  /**
   * 添加或删除层级列表
   * @param action 操作(push or pop)
   */
  static handleMapList(action: string) {
    if (action === "push") {
      if (!this.mapList.includes(this.mapName)) {
        this.mapList.push(this.mapName);
      } else {
        return "error";
      }
    }
    if (action === "pop") {
      if (this.mapList.length > 1) {
        this.mapList.pop();
      } else {
        return "error";
      }
    }
  }

  /**
   * 创建地图
   * @param id 标签id
   */
  static initMap(id: string) {
    const geoJson = this.mapJsonList[this.mapName];

    // 首次加载时添加至层级列表
    this.handleMapList("push");

    const element = document.getElementById(id) as HTMLElement;

    // 是否已存在实例
    const instance = echarts.getInstanceByDom(element);

    if (instance) {
      instance.dispose(); // 销毁
    }

    const map = echarts.init(element); // 初始化

    echarts.registerMap(this.mapName, geoJson); // 注册地图

    // 绑定配置项
    this.option.geo.map = this.mapName;

    console.log(this.option);

    map.setOption(this.option);

    // 是否允许地图操作
    if (this.isDrill) {
      // 左键下钻
      map.on("click", (p) => {
        // 判断是否存在地图
        if (!this.mapJsonList[p.name]) {
          Message.error({
            content: `暂无${p.name}区域数据`,
          });
          return;
        } else {
          this.mapName = p.name; // 切换地图并重新绑定
          this.handleMapList("push"); // 添加至层级列表
          this.initOption();
          this.initMap(id);
        }
      });

      // 鼠标右键返回
      const canvas = document.getElementById(id) as HTMLElement;
      // 清除浏览器默认右键事件
      canvas.oncontextmenu = () => {
        return false;
      };

      map.on("contextmenu", () => {
        const upper = this.mapList[this.mapList.length - 2];
        if (!upper) {
          Message.warning({
            content: "当前已是最上层",
          });
          return;
        } else {
          this.mapName = upper; // 切换地图并重新绑定
          this.handleMapList("pop"); // 添加至层级列表
          this.initOption();
          this.initMap(id);
        }
      });
    }

    // 自适应
    window.onresize = () => {
      map.resize();
    };
    // 返回map 方便页面进一步操作
    return map;
  }

  /**
   * 初始化option,遍历是否有该地图飞线、点位数据
   */
  static initOption() {
    // 初始化
    this.flySeries.data = [];
    this.pointSeries.data = [];

    // 飞线
    this.flyLineList.forEach((e) => {
      if (e.map === this.mapName) {
        this.flySeries.data = [...e.data];
        this.option.series.push(this.flySeries);
      }
    });

    // 点位
    this.pointList.forEach((e) => {
      if (e.map === this.mapName) {
        this.pointSeries.data = [...e.data];
        this.option.series.push(this.pointSeries);
      }
    });
  }
}
