import { Style, Icon } from "ol/style";
import { Geometry, Point } from "ol/geom";
import { Feature, Map } from "ol";
import { Vector } from "ol/layer";
import { Vector as SourceVector } from "ol/source";
import { debounce, getRealativeMosePosition } from "@/util";
import mitt from "mitt";

const styles = [
  new Style({
    image: new Icon({
      src: "/map/point_a.png",
      scale: [0.5, 0.5],
      offset: [0, 0],
    }),
  }),
];

const getHotFeature = (pos: number[]) => {
  const feature = new Feature(new Point(pos));
  feature.setStyle(styles[0]);
  return feature;
};

const hotSource = new SourceVector();
export const hotLayer = new Vector({ source: hotSource });
export type HotData = { data: number[]; id: any; label: string };
export const addHots = (posArray: HotData[]) => {
  hotSource.addFeatures(
    posArray.map((item) => {
      const feature = getHotFeature(item.data);
      feature.setProperties({ id: item.id });
      return feature;
    })
  );
};

export const delHots = (ids: HotData["id"][]) => {
  const features = hotSource
    .getFeatures()
    .filter((f) => ids.includes(f.getProperties().id));
  hotSource.removeFeatures(features);
};

export const clearHots = () => {
  hotSource.removeFeatures(hotSource.getFeatures());
};

export const dynamicHots = (map: Map) => {
  const bus = mitt<{ active: any; click: any }>();
  const container = map.getTargetElement();
  const getMouseFeature = (ev: MouseEvent) => {
    const ratio = window.devicePixelRatio;
    const pixel = getRealativeMosePosition(container, [
      ev.offsetX,
      ev.offsetY,
    ]).map((p) => p / ratio);
    return map.forEachFeatureAtPixel(pixel, (feature) => {
      return hotSource.getFeatures().find((f) => f === feature);
    });
  };

  const addEventListener = (
    ev: "mousemove" | "click",
    emitKey: "active" | "click",
    repeat = false
  ) => {
    let last: Feature<Geometry> | null = null;
    container.addEventListener(
      ev,
      debounce((ev) => {
        const feature = getMouseFeature(ev);

        if (feature) {
          if (repeat || feature !== last) {
            bus.emit(emitKey, feature.getProperties()["id"]);
            last = feature;
          }
        } else if (repeat || last) {
          bus.emit(emitKey, null);
          last = null;
        }
      }, 32)
    );

    return last!;
  };
  addEventListener("click", "click", true);
  addEventListener("mousemove", "active");
  return bus;
};
