import { getShapePoints } from "./HitTest.js";

export class TransformManager {
  translateStroke(stroke, dx, dy) {
    if (!stroke) {
      return;
    }

    if (Array.isArray(stroke.points)) {
      stroke.points.forEach((point) => {
        point.x += dx;
        point.y += dy;
      });
    }

    ["x", "startX", "endX"].forEach((key) => {
      if (Number.isFinite(stroke[key])) {
        stroke[key] += dx;
      }
    });
    ["y", "startY", "endY"].forEach((key) => {
      if (Number.isFinite(stroke[key])) {
        stroke[key] += dy;
      }
    });
  }

  translateStrokes(strokes, dx, dy) {
    strokes.forEach((stroke) => this.translateStroke(stroke, dx, dy));
  }

  scaleStroke(stroke, bounds, scaleX, scaleY) {
    const originX = bounds.minX;
    const originY = bounds.minY;
    this.#transformStroke(stroke, (point) => ({
      ...point,
      x: originX + (point.x - originX) * scaleX,
      y: originY + (point.y - originY) * scaleY
    }));
  }

  rotateStroke(stroke, center, radians) {
    const cos = Math.cos(radians);
    const sin = Math.sin(radians);
    this.#transformStroke(stroke, (point) => {
      const dx = point.x - center.x;
      const dy = point.y - center.y;
      return {
        ...point,
        x: center.x + dx * cos - dy * sin,
        y: center.y + dx * sin + dy * cos
      };
    });
  }

  #transformStroke(stroke, transformPoint) {
    if (!stroke) {
      return;
    }

    if (Array.isArray(stroke.points)) {
      stroke.points.forEach((point, index) => {
        stroke.points[index] = transformPoint(point);
      });
    }

    if (stroke.tool === "line" || stroke.tool === "rectangle" || stroke.tool === "square") {
      const points = getShapePoints(stroke).map(transformPoint);
      if (points[0]) {
        stroke.startX = points[0].x;
        stroke.startY = points[0].y;
      }
      if (points[1]) {
        stroke.endX = points[1].x;
        stroke.endY = points[1].y;
      }
      if (points.length >= 4) {
        stroke.x = points[0].x;
        stroke.y = points[0].y;
        stroke.width = points[2].x - points[0].x;
        stroke.height = points[2].y - points[0].y;
      }
    }
  }
}
