import { Graphics } from "pixi.js";
import { useCallback } from "react";
import { PATH_COLOR, PATH_WIDTH, UNPASSED_STATION_COLOR } from "./Constants";

interface TravelPathProps {
  points: { x: number; y: number }[];
  busCoordinates?: { x: number; y: number };
}

const PASSED_PATH_COLOR = PATH_COLOR;
const UNPASSED_PATH_COLOR = UNPASSED_STATION_COLOR;

export function TravelPath({
  points,
  busCoordinates,
}: Readonly<TravelPathProps>) {
  const draw = useCallback(
    (g: Graphics) => {
      g.clear();

      if (points.length < 2) {
        return;
      }

      g.moveTo(points[0].x, points[0].y);
      for (let i = 1; i < points.length; i++) {
        g.lineTo(points[i].x, points[i].y);
      }
      g.stroke({
        color: UNPASSED_PATH_COLOR,
        width: PATH_WIDTH,
      });

      if (!busCoordinates) {
        return;
      }

      let minDistance = Infinity;
      let closestSegmentIndex = -1;
      let busSegmentStartPoint: { x: number; y: number } | null = null;

      for (let i = 0; i < points.length - 1; i++) {
        const p1 = points[i];
        const p2 = points[i + 1];

        const lineLengthSq = (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2;
        if (lineLengthSq === 0) continue;

        const t =
          ((busCoordinates.x - p1.x) * (p2.x - p1.x) +
            (busCoordinates.y - p1.y) * (p2.y - p1.y)) /
          lineLengthSq;
        const projectionT = Math.max(0, Math.min(1, t));

        const projectedX = p1.x + projectionT * (p2.x - p1.x);
        const projectedY = p1.y + projectionT * (p2.y - p1.y);

        const dist = Math.sqrt(
          (busCoordinates.x - projectedX) ** 2 +
            (busCoordinates.y - projectedY) ** 2
        );

        if (dist < minDistance) {
          minDistance = dist;
          closestSegmentIndex = i;
          busSegmentStartPoint = { x: projectedX, y: projectedY };
        }
      }

      if (closestSegmentIndex !== -1 && busSegmentStartPoint) {
        g.moveTo(points[0].x, points[0].y);
        for (let i = 1; i <= closestSegmentIndex; i++) {
          g.lineTo(points[i].x, points[i].y);
        }
        g.lineTo(busSegmentStartPoint.x, busSegmentStartPoint.y);

        g.stroke({
          color: PASSED_PATH_COLOR,
          width: PATH_WIDTH,
        });
      }
    },
    [points, busCoordinates]
  );

  if (points.length === 0) {
    console.error("points is empty");
    return null;
  }

  return <pixiGraphics draw={draw} />;
}
