/**
 * RouteArrows — Mapbox-style manoeuvre arrows: at each MAJOR turn, a short
 * white shaft sliced from the route polyline (so it follows the road's bend)
 * with an arrowhead at its head. See routeArrowGeometry.ts for the slicing.
 *
 * Four layers, ordered bottom→top so the white reads over the blue route line
 * and the arrowhead sits on top: shaft casing (dark, wide) → shaft (white) →
 * head. All ground-aligned so they lie flat on the road and tilt in 3D. Only
 * shown zoomed in enough to see individual turns.
 */
import React, { useMemo } from "react";
import { Images, GeoJSONSource, Layer } from "@maplibre/maplibre-react-native";
import type { Route } from "../../../modules/mapmap-react-native/src/MapmapNav.types";
import { maneuverArrows } from "./routeArrowGeometry";

export type RouteArrowsProps = {
  route?: Route;
};

const MIN_ZOOM = 14;

type LayerLayout = NonNullable<React.ComponentProps<typeof Layer>["layout"]>;

const LINE_LAYOUT = { "line-cap": "round" as const, "line-join": "round" as const };
const SHAFT_CASING_PAINT = { "line-color": "#123E86", "line-width": 15 };
const SHAFT_PAINT = { "line-color": "#FFFFFF", "line-width": 9 };
const HEAD_LAYOUT: LayerLayout = {
  "icon-image": "route-arrow-head",
  "icon-size": 0.22,
  "icon-rotate": ["get", "bearing"],
  "icon-rotation-alignment": "map",
  "icon-pitch-alignment": "map",
  "icon-allow-overlap": true,
  "icon-ignore-placement": true,
};

export function RouteArrows({ route }: RouteArrowsProps): React.JSX.Element | null {
  const arrows = useMemo(() => maneuverArrows(route), [route]);
  if (arrows.shafts.features.length === 0) return null;

  return (
    <>
      {/* Required lazily (not at module scope) so the pure geometry can be unit
       * tested without a bundler-provided PNG transform. */}
      <Images images={{ "route-arrow-head": require("../../../assets/arrow-head.png") }} />

      <GeoJSONSource id="guidance-arrow-shafts" data={arrows.shafts}>
        <Layer
          id="guidance-arrow-shaft-casing"
          type="line"
          minzoom={MIN_ZOOM}
          paint={SHAFT_CASING_PAINT}
          layout={LINE_LAYOUT}
        />
        <Layer
          id="guidance-arrow-shaft"
          type="line"
          minzoom={MIN_ZOOM}
          paint={SHAFT_PAINT}
          layout={LINE_LAYOUT}
        />
      </GeoJSONSource>

      <GeoJSONSource id="guidance-arrow-heads" data={arrows.heads}>
        <Layer
          id="guidance-arrow-head"
          type="symbol"
          minzoom={MIN_ZOOM}
          layout={HEAD_LAYOUT}
        />
      </GeoJSONSource>
    </>
  );
}
