import { Point } from "@noya-app/noya-geometry";
import { Group, Polyline, Rectangle } from "@noya-app/noya-graphics";
import React, { useMemo } from "react";
import { BaseCanvasData, getCanvasTransform } from "../plugins/baseCanvas";
import {
  GradientEditorData,
  GradientEditorGradient,
  GradientEditorMode,
  useGradientEditor,
} from "../plugins/gradientEditorPlugin";

const ACTIVE_COLOR = "#FFA500";
const DEFAULT_BORDER_COLOR = "#FFFFFF";

export function GradientHandles({
  gradient,
  data,
  mode,
}: {
  gradient?: GradientEditorGradient;
  data?: GradientEditorData & Pick<BaseCanvasData, "origin" | "zoom">;
  mode?: GradientEditorMode<unknown>;
}) {
  const gradientState = useGradientEditor();

  gradient = gradient ?? gradientState.gradient;
  data = data ?? gradientState.data;
  mode = mode ?? gradientState.mode;

  const transform = useMemo(() => getCanvasTransform(data), [data]);

  if (!gradient || gradient.stops.length < 2) return null;

  const start = gradient.stops.find((stop) => stop.type === "start");
  const end = gradient.stops.find((stop) => stop.type === "end");

  if (!start || !end) return null;

  const lineStrokeWidth = 1 / data.zoom;

  const getHandleRect = (point: Point) => {
    const size = data.handleSize / data.zoom;
    return {
      x: point.x - size / 2,
      y: point.y - size / 2,
      width: size,
      height: size,
    };
  };

  return (
    <Group transform={transform}>
      <Polyline
        points={[start.point, end.point]}
        paint={{
          style: "stroke",
          strokeWidth: lineStrokeWidth,
          color: "#FFFFFF",
        }}
      />
      {gradient.stops.map((stop) => {
        const rect = getHandleRect(stop.point);

        const isActive =
          mode?.type === "draggingGradientStop" && mode.stopId === stop.id;
        const isHovered = data.hoveredStopId === stop.id;

        return (
          <React.Fragment key={stop.id}>
            <Rectangle
              rect={rect}
              cornerRadius={rect.width / 2}
              paint={{
                style: "fill",
                color: stop.color ?? "#FFFFFF",
              }}
            />
            <Rectangle
              rect={rect}
              cornerRadius={rect.width / 2}
              paint={{
                style: "stroke",
                strokeWidth: lineStrokeWidth,
                color:
                  isActive || isHovered ? ACTIVE_COLOR : DEFAULT_BORDER_COLOR,
              }}
            />
          </React.Fragment>
        );
      })}
    </Group>
  );
}
