import { insetRect, Rect } from "@noya-app/noya-geometry";
import { Group, Rectangle } from "@noya-app/noya-graphics";
import React, { useMemo } from "react";
import { BaseCanvasData, getCanvasTransform } from "../plugins/baseCanvas";
import { PointData } from "../plugins/pointPlugin";
import { useReactCanvas } from "../plugins/ReactCanvas";
import { ScaleData } from "../plugins/scalePlugin";
import { getPointHandles } from "../utils/dragHandleUtils";
import { getAbsolutizeTransform, IdentifiablePoint } from "../utils/pointUtils";

export function PointHandles({
  points,
  data,
}: {
  points: {
    point: IdentifiablePoint;
    pathRect: Rect;
  }[];
  data?: Pick<BaseCanvasData, "zoom" | "origin"> &
    Pick<ScaleData, "dragHandleSize"> &
    PointData;
}) {
  const ReactCanvas = useReactCanvas();
  const canvasData = ReactCanvas.useData() as ScaleData &
    BaseCanvasData &
    PointData;

  data = data ?? canvasData;

  const transform = useMemo(() => getCanvasTransform(data), [data]);
  const pointIds = useMemo(
    () => points.map((point) => point.point.id),
    [points]
  );

  const dragHandles = useMemo(() => {
    const pointHandles = getPointHandles({
      points: points.map((point) =>
        getAbsolutizeTransform(point.pathRect).applyTo(point.point)
      ),
      data: { zoom: data.zoom, pointHandleSize: data.pointHandleSize },
    });
    return pointHandles.filter((handle) => pointIds.includes(handle.id));
  }, [points, data.zoom, data.pointHandleSize, pointIds]);

  return (
    <Group transform={transform}>
      {dragHandles.map((handle, i) => {
        const inset = 0.5 / data.zoom;
        const rect = insetRect(handle.rect, inset);

        return (
          <React.Fragment key={i}>
            <Rectangle
              rect={rect}
              paint={{
                style: "fill",
                color: "#FFFFFF",
              }}
              cornerRadius={data.pointHandleSize / 2}
            />
            <Rectangle
              rect={rect}
              paint={{
                style: "stroke",
                strokeWidth: handle.strokeWidth,
                color:
                  data.highlightedPointId === handle.id ? "#FFA500" : "#1E90FF",
              }}
              cornerRadius={data.pointHandleSize / 2}
            />
          </React.Fragment>
        );
      })}
    </Group>
  );
}
