/*
 * @Author: your name
 * @Date: 2022-01-11 13:45:12
 * @LastEditTime: 2022-02-17 10:10:11
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /test/hello-world/src/utils/mapClass.js
 */

// 编辑类
// 在地图上新增的设备可以直接编辑，
// 已经保存完成的设备需要点编辑才可以编辑
export class EditorMap {
  // 地图的对象实例
  map = null;
  // 父vue的实例
  vue = null;
  // 操作 新建，编辑，删除，编辑跟删除只对已经在图上的设备有效 默认值：0， 新建：1，编辑：2, 删除: 3。
  // 新建的时候会把未保存的线条清空
  control = 0;
  // 鼠标事件对象，用来将点跟线上图
  mousetool = null;
  // 当前正在手动绘制的对象
  nowMouseTarget = null;
  // 当线mousetool线被按下的时候的flag 当线被按下的时候为true，就不询问是否删除了
  mosueToolPolineDownFlag = false;
  // 绘制marer的时候的配置，在绘制完挂载事件的时候需要使用
  mouseToolMarkerOptions = null;
  // 绘制poline的时候的配置，在绘制完挂载事件的时候需要使用
  mouseToolPolineOptions = null;

  constructor(contaienr, config = {}, vue) {
    this.map = new AMap.Map(contaienr, {
      viewMode: "3D",
      center: [116.397083, 39.874531],
      layers: [AMap.createDefaultLayer()], // layers 字段为空或者不赋值将会自动创建默认底图。
      zoom: 12,
      ...config,
    });

    this.vue = vue;
    this.init();
  }

  init() {
    // 地图事件
    this.mapEvent();
    // 手动点线上图准备,编辑模式
    this.mouseAddDevice();
    window.func = () => {
      this.getPath();
    };
    // this.mouseAddMarker();
    // this.mouseAddPipeline();
  }
  // map的事件监听
  mapEvent() {
    this.map.on("click", () => {
      // mousetool对象画出的对象的操作
      // 如果有手动绘制对象，要手动清楚一下，因为画线的时候不好清除旧线，这其实是用来清楚旧线的
      // 当画出来的线被mousedown，不删除，但是mouseToolPipeLineFlag要归位，在移出线的时候统一归位
      // 如果对象是marker，直接删除
      if (this.nowMouseTarget?.type == "AMap.Marker") {
        console.log("???");
        this.mouseToolDrawClear();
      } else {
        // 当地图上已经画了线，并且没有点在线上，询问是否删除
        if (this.nowMouseTarget && !this.mosueToolPolineDownFlag) {
          this.confirm("是否重新绘制管道", { type: "warning" })
            .then(() => {
              // 删除原来的线
              this.mouseToolDrawClear();
              // 鼠标事件开启，并且赋值原来的属性，this.mouseToolMarkerOptions是开启绘制的时候记录的
              this.mousetool.polyline(this.mouseToolPolineOptions);
            })
            .catch(() => {});
        }
      }
    });
    this.map.on("moveend", () => {
      console.log("地图停止移动");
      if (this.flag) {
        console.log("弹框");
        this.flag = false;
      }
    });
    window.panTo = () => {
      this.flag = true;
      this.map.panTo([116.428285, 39.886129]);
    };
  }
  // 弹框工具
  confirm(message, obj) {
    return this.vue.$confirm(message, obj);
  }

  // 改变操作状态
  changeControl(num) {
    this.control = num;
  }

  // 点线编辑上图准备
  mouseAddDevice() {
    this.map.plugin(["AMap.MouseTool"], () => {
      this.mousetool = new AMap.MouseTool(this.map);
    });
    // 挂载绘制结束的事件
    this.mouseDrawEvent();
  }

  // 点或者线上图结束后触发的事件
  mouseDrawEvent() {
    this.mousetool.on("draw", (e) => {
      const target = e.obj;
      // console.log([target._position.lng, target._position.lat]);
      const { type: targetType } = target;
      // 当这个点是marker的时候
      if (targetType == "AMap.Marker") {
        this.mouseToolMarkerEvent(target);
      } else {
        // 如果是线,挂上编辑
        this.lineEditor(target);
        this.mousetool.close();
        this.mouseToolPolineEvent(target);
        console.log(targetType, "当前对象是管道");
      }
      this.nowMouseTarget = target;
    });
  }

  // 绘制marker结束后，在marker身上添加的事件
  mouseToolMarkerEvent(target) {
    // 由于画出来的marker点击会换位置，所以当移入的时候删除绘制事件，移出去在增加绘制事件
    target.on("mouseover", (e) => {
      // 鼠标事件关闭
      this.mousetool.close(false);
    });
    target.on("mouseout", (e) => {
      // 这里不方便获取原来的属性，因为position不好解决，还是设置一个值吧
      // 鼠标事件开启，并且赋值原来的属性，this.mouseToolMarkerOptions是开启绘制的时候记录的
      this.mousetool.marker(this.mouseToolMarkerOptions);
    });
    // 点
    target.on("click", (e) => {
      // 弹框
    });
  }
  // 挂上线以及线的事件
  lineEditor(line) {
    // line.editor && line.editor.close();
    // 当前点击次数，1次为编辑，2次为弹框
    line.editorNum = 0;
    line.editor = new AMap.PolyEditor(this.map, line);
  }
  // 绘制管道的时候，挂载的事件
  mouseToolPolineEvent(target) {
    // 线按下的时候会变成编辑，mousetool事件会清空 移出线的时候 在把polyline事件加上
    target.on("mouseover", (e) => {
      // 鼠标事件关闭
      // this.mousetool.close(false);
    });
    target.on("mouseout", (e) => {
      // 有时候按在线上移动地图，map点击事件中mosueToolPolineDownFlag无法归位，在这里归位
      this.mosueToolPolineDownFlag = false;
      // 鼠标事件开启，并且赋值原来的属性，this.mouseToolMarkerOptions是开启绘制的时候记录的
      // this.mousetool.polyline(this.mouseToolPolineOptions);
    });
    // 线
    target.on("mousedown", (e) => {
      const line = e.target;
      // mosueTool按下的flag,按在线上，不询问是否删除
      this.mosueToolPolineDownFlag = true;
      // 按下的时候要关闭事件
      this.mousetool.close(false);

      // 如果当前状态不是编辑，则进入编辑状态
      if (line.editorNum < 1) {
        // 打开并且++
        line.editor.open();
        line.editorNum++;
      } else {
        // 这里就要弹框了
        console.log(line.getPath());
      }
    });
  }

  // 设备点击上图开启
  mouseAddMarker(markerObj = {}) {
    // 清空已经绘制完的对象
    this.mousetoolClose(true);
    // 记录一下配置项，在挂载点击的时候，需要使用
    this.mouseToolMarkerOptions = {
      draggable: true,
      ...markerObj,
    };
    this.mousetool.marker(this.mouseToolMarkerOptions);
  }
  // 管线点击上图开启
  mouseAddPipeline(pipeObj = {}) {
    this.mousetoolClose(true);
    // 开始画线
    this.mosuetoolPolineFlag = true;
    this.mouseToolPolineOptions = {
      strokeWeight: 5,
      ...pipeObj,
    };
    this.mousetool.polyline(this.mouseToolPolineOptions);
  }

  // 手动清除map上绘制的对象
  mouseToolDrawClear() {
    if (this.nowMouseTarget) {
      this.map.remove(this.nowMouseTarget);
      // 如果有editor,则关闭
      this.nowMouseTarget.editor && this.nowMouseTarget.editor.close();
      this.nowMouseTarget = null;
    }
  }
  // 关闭点击上图事件 true清除之前绘制的图像，false 仅关闭上图事件
  mousetoolClose(boolean) {
    //  清空地图上的绘制对象的同时,也要清楚这个nowMouseTarget控制对象
    if (this.nowMouseTarget) {
      // 如果有editor,则关闭
      this.nowMouseTarget.editor && this.nowMouseTarget.editor.close();
      this.nowMouseTarget = null;
    }
    this.mousetool.close(boolean);
  }

  /**
   *
   *
   *
   *
   *
   *
   * 地图上add设备
   *
   *
   * @description:
   * @param {*} deviceData marker的数据
   * @param {*} compontent marker点击弹出的infowindow的组件
   * @return {*}
   */
  addDevice(deviceData) {
    const { path } = deviceData;
    let device = this.createMarker({
      map: this.map,
      anchor: "bottom-center",
      icon: require("@/assets/mapImages/coordinate.svg"),
      position: path,
      extData: deviceData,
    });
    // 当前设备
    this.mouseAddMarker();
    this.nowMouseTarget = device;
    this.setCenter(path);

    // 设备的事件函数
    // this.deviceEvent(device, compontent);
  }
  deviceEvent(device, compontent) {
    device.on("click", (e) => {
      const target = e.target;
      // 如果control==0就是默认值，没有使用123功能，就显示infowindow
      if (this.control == 0) {
        // this.markerClick(target, compontent);
      } else if (this.control == 2) {
        // 2是已经上图的设备拥有的编辑功能
      } else if (this.control == 3) {
        // 3是删除操作
      }
    });
  }
  // 创建marker
  createMarker(MarkerOptions) {
    return new AMap.Marker(MarkerOptions);
  }
  // 地图上add管道
  addPipeLine(objData) {
    const { path } = objData;
    const pipe = this.createPipeLine({
      path,
      strokeWeight: 4,
      strokeColor: "#000",
      extData: objData,
      cursor: "pointer",
    });
    this.map.add(pipe);
    this.setCenter(path[0]);
    // 当前设备
    this.nowMouseTarget = pipe;
  }
  createPipeLine(pipeLineOptions) {
    return new AMap.Polyline(pipeLineOptions);
  }

  setCenter(path) {
    this.map.setCenter(path, true);
  }
  // 获取路径
  getPath() {
    if(!this.nowMouseTarget) return;
    if (this.nowMouseTarget.type == "AMap.Marker") {
      const { lng, lat } = this.nowMouseTarget.getPosition();
      return [lng, lat];
    } else {
      return this.nowMouseTarget?.getPath().map((item) => [item.lng, item.lat]);
    }
  }
  // 搜索位置
  positionSearch(id) {
    // id 为搜索框id
    var autoOptions = {
      input: id,
    };
    AMap.plugin(["AMap.PlaceSearch", "AMap.AutoComplete"],  ()=> {
      var auto = new AMap.AutoComplete(autoOptions);
      var placeSearch = new AMap.PlaceSearch({
        map: this.map,
      }); //构造地点查询类
      auto.on("select", select); //注册监听，当选中某条记录时会触发
      function select(e) {
        console.log(e)
        placeSearch.setCity(e.poi.adcode);
        placeSearch.search(e.poi.name);  //关键字查询查询
      }
    });
  }
   // 销毁map
   destroy(){
    this.map.destroy();
  }
}
