import * as KMap from "@/utils/ol-map/KMap";
import config from "@/api/config";
import { wktCastGeom, newAreaFeature } from "@/common/ol_common";
import { unByKey } from "ol/Observable";
import Feature from "ol/Feature";
import { Point } from "ol/geom";
import Style from "ol/style/Style";
import Icon from "ol/style/Icon";
import mapPointImg from "@/assets/page/map-point.png";

/** 与 workDetail/areaMap 默认中心一致 */
const DEFAULT_LOCATION = "POINT(113.61448114737868 23.585550924763083)";

/**
 * 存放点位选择地图
 * - 展示蓝区范围（不可点选）
 * - 地图中心默认点位图标，点击地图移动点位
 */
export default class LocationSelectMap {
  constructor() {
    const vectorStyle = new KMap.VectorStyle();
    this.vectorStyle = vectorStyle;
    this.kmap = null;
    this.clickKey = null;
    this.pointFeature = null;

    this.blueRegionLayer = new KMap.VectorLayer("blueRegionLayer", 99999, {
      minZoom: 1,
      maxZoom: 22,
      style: () =>
        vectorStyle.getPolygonStyle(
          "rgba(0, 0, 0, 0.45)",
          "rgba(255, 212, 137, 0.85)",
          1.5
        ),
    });

    this.pointLayer = new KMap.VectorLayer("locationPointLayer", 100000, {
      minZoom: 1,
      maxZoom: 22,
      style: new Style({
        image: new Icon({
          src: mapPointImg,
          scale: 0.55,
          anchor: [0.5, 1],
          anchorXUnits: "fraction",
          anchorYUnits: "fraction",
        }),
      }),
    });
  }

  /**
   * @param {HTMLElement} target
   * @param {string} location WKT，优先用于点位初始位置
   */
  init(target, location = DEFAULT_LOCATION) {
    this.destroy();

    const level = 16;
    const coordinate = wktCastGeom(location).getFirstCoordinate();

    this.kmap = new KMap.Map(
      target,
      level,
      coordinate[0],
      coordinate[1],
      null,
      1,
      22,
      "vec",
      true,
      true
    );

    this.kmap.addLayer(this.blueRegionLayer.layer);
    this.kmap.addLayer(this.pointLayer.layer);

    const xyz = config.base_img_url + "map/lby/{z}/{x}/{y}.png";
    this.kmap.addXYZLayer(xyz, { minZoom: 8, maxZoom: 22 }, 2);

    this.setPoint(coordinate);
    this.addMapSingleClick();
    setTimeout(() => this.updateSize(), 80);
  }

  addMapSingleClick() {
    this.clickKey = this.kmap.on("singleclick", (evt) => {
      this.setPoint(evt.coordinate);
    });
  }

  /** @param {[number, number]} coordinate [lng, lat] */
  setPoint(coordinate) {
    if (!this.pointLayer?.source || !coordinate) return;

    if (this.pointFeature) {
      this.pointFeature.getGeometry().setCoordinates(coordinate);
      return;
    }

    this.pointFeature = new Feature({
      geometry: new Point(coordinate),
    });
    this.pointFeature.set("nodeType", "location");
    this.pointLayer.addFeature(this.pointFeature);
  }

  /**
   * 仅展示蓝区，不可点击选择
   * @param {Array} list
   */
  setRegions(list = []) {
    if (!this.blueRegionLayer?.source) return;
    this.blueRegionLayer.source.clear();

    for (const item of list) {
      const wkt = item.geom || item.wkt;
      if (!wkt) continue;
      const id = item.blueZoneCode ?? item.id;
      const feature = newAreaFeature({
        ...item,
        geom: wkt,
        id,
        name: item.name || item.regionName || item.blueZoneName || String(id),
      });
      this.blueRegionLayer.addFeature(feature);
    }

    this.fitToRegions();
  }

  fitToRegions() {
    const extent = this.blueRegionLayer?.source?.getExtent?.();
    if (!extent || !isFinite(extent[0]) || !this.kmap) return;
    this.kmap.fit(extent, { padding: [40, 40, 40, 40], duration: 300, maxZoom: 18 });
  }

  /** 将点位放到当前地图中心 */
  setPointToCenter() {
    const center = this.kmap?.view?.getCenter?.();
    if (center) this.setPoint(center);
  }

  getPoint() {
    if (!this.pointFeature) return null;
    const [lng, lat] = this.pointFeature.getGeometry().getCoordinates();
    return {
      lng,
      lat,
      wkt: `POINT(${lng} ${lat})`,
      label: `POINT(${Number(lng).toFixed(6)} ${Number(lat).toFixed(6)})`,
    };
  }

  updateSize() {
    this.kmap?.updateSize?.() || this.kmap?.map?.updateSize?.();
  }

  destroy() {
    if (this.clickKey) {
      unByKey(this.clickKey);
      this.clickKey = null;
    }
    this.blueRegionLayer?.source?.clear?.();
    this.pointLayer?.source?.clear?.();
    this.pointFeature = null;
    this.kmap?.destroy?.();
    this.kmap = null;
  }
}
