import { describe, expect, it } from "vitest";
import { createPolygonSpatialIndex, hitTestPolygons, queryPolygonsByBBox } from "./spatialIndex";
import type { MapPolygon } from "../model/mapTypes";

const bottom: MapPolygon = {
  id: "bottom",
  name: "Bottom polygon",
  kind: "planWork",
  layer: "planWorks",
  zIndex: 1,
  points: [
    { lon: 0, lat: 0 },
    { lon: 10, lat: 0 },
    { lon: 10, lat: 10 },
    { lon: 0, lat: 10 }
  ]
};

const top: MapPolygon = {
  id: "top",
  name: "Top polygon",
  kind: "planWork",
  layer: "planWorks",
  zIndex: 2,
  points: [
    { lon: 5, lat: 5 },
    { lon: 15, lat: 5 },
    { lon: 15, lat: 15 },
    { lon: 5, lat: 15 }
  ]
};

describe("polygon spatial index", () => {
  it("uses bbox candidates and returns the top polygon by zIndex", () => {
    const index = createPolygonSpatialIndex([bottom, top]);

    expect(hitTestPolygons(index, { lon: 6, lat: 6 })?.id).toBe("top");
    expect(hitTestPolygons(index, { lon: 2, lat: 2 })?.id).toBe("bottom");
    expect(hitTestPolygons(index, { lon: 20, lat: 20 })).toBeUndefined();
  });

  it("queries polygons by bbox", () => {
    const index = createPolygonSpatialIndex([bottom, top]);

    expect(queryPolygonsByBBox(index, { minLon: 11, minLat: 11, maxLon: 12, maxLat: 12 }).map((polygon) => polygon.id))
      .toEqual(["top"]);
  });

  it("matches polygons whose longitudes are in a different 360° window (western hemisphere)", () => {
    // Контур в долготах 0..360: западное полушарие ~234° вместо −126°.
    const western: MapPolygon = {
      id: "western",
      name: "Western survey route",
      kind: "planWork",
      layer: "planWorks",
      zIndex: 1,
      points: [
        { lon: 233, lat: 48 },
        { lon: 235, lat: 48 },
        { lon: 235, lat: 50 },
        { lon: 233, lat: 50 }
      ]
    };
    const index = createPolygonSpatialIndex([western]);

    // Видовой bbox в нормализованных долготах [−128, −124] — те же координаты, что и контур, со сдвигом −360°.
    expect(
      queryPolygonsByBBox(index, { minLon: -128, minLat: 47, maxLon: -124, maxLat: 51 }).map((polygon) => polygon.id)
    ).toEqual(["western"]);
  });
});

