import { describe, expect, it } from "vitest";

import { maneuverArrows } from "./routeArrowGeometry";
import type { LatLng, Maneuver, Route } from "../../../modules/mapmap-react-native/src/MapmapNav.types";

function point(latitude: number, longitude: number): LatLng {
  return { latitude, longitude };
}

function maneuver(overrides: Partial<Maneuver> & Pick<Maneuver, "type" | "position">): Maneuver {
  return { instruction: "", distanceMeters: 0, ...overrides };
}

// A route heading east then turning north; the turn is at (0, 0.01).
const ROUTE: Route = {
  index: 0,
  distanceMeters: 0,
  durationSeconds: 0,
  geometry: [point(0, 0), point(0, 0.01), point(0.01, 0.01)],
  maneuvers: [
    maneuver({ type: "depart", position: point(0, 0) }),
    maneuver({ type: "turn-left", position: point(0, 0.01) }),
    maneuver({ type: "arrive", position: point(0.01, 0.01) }),
  ],
};

describe("maneuverArrows", () => {
  it("returns empty for no route", () => {
    const arrows = maneuverArrows(undefined);
    expect(arrows.shafts.features).toHaveLength(0);
    expect(arrows.heads.features).toHaveLength(0);
  });

  it("emits one shaft + head for the single major turn (excludes depart/arrive)", () => {
    const arrows = maneuverArrows(ROUTE);
    expect(arrows.shafts.features).toHaveLength(1);
    expect(arrows.heads.features).toHaveLength(1);
    expect(arrows.shafts.features[0].geometry.type).toBe("LineString");
    // The shaft slice has at least a start + end point.
    expect(arrows.shafts.features[0].geometry.coordinates.length).toBeGreaterThanOrEqual(2);
    // The head carries a numeric bearing for icon-rotate.
    expect(typeof arrows.heads.features[0].properties.bearing).toBe("number");
  });

  it("excludes slight turns and straight/continue", () => {
    const route: Route = {
      ...ROUTE,
      maneuvers: [
        maneuver({ type: "depart", position: point(0, 0) }),
        maneuver({ type: "slight-left", position: point(0, 0.005) }),
        maneuver({ type: "straight", position: point(0, 0.008) }),
        maneuver({ type: "arrive", position: point(0.01, 0.01) }),
      ],
    };
    expect(maneuverArrows(route).shafts.features).toHaveLength(0);
  });
});
