/** Shared geometry helpers used by both collision.ts and interactions.ts */

type Vec2 = [number, number];

/** Compute 4 corners of an oriented box anchored at a point along a direction.
 *  anchorSide='right': box extends backward from anchor (left box, right-center at anchor).
 *  anchorSide='left': box extends forward from anchor (right box, left-center at anchor). */
export function orientedBoxCorners(
  anchorX: number, anchorY: number,
  dirX: number, dirY: number,
  boxW: number, boxH: number,
  anchorSide: 'left' | 'right'
): Vec2[] {
  const len = Math.sqrt(dirX * dirX + dirY * dirY);
  if (len === 0) return [[anchorX, anchorY]];
  const ux = dirX / len, uy = dirY / len;
  const nx = -uy, ny = ux;
  const hh = boxH / 2;

  if (anchorSide === 'right') {
    return [
      [anchorX - ux * boxW - nx * hh, anchorY - uy * boxW - ny * hh],
      [anchorX - nx * hh, anchorY - ny * hh],
      [anchorX + nx * hh, anchorY + ny * hh],
      [anchorX - ux * boxW + nx * hh, anchorY - uy * boxW + ny * hh],
    ];
  } else {
    return [
      [anchorX - nx * hh, anchorY - ny * hh],
      [anchorX + ux * boxW - nx * hh, anchorY + uy * boxW - ny * hh],
      [anchorX + ux * boxW + nx * hh, anchorY + uy * boxW + ny * hh],
      [anchorX + nx * hh, anchorY + ny * hh],
    ];
  }
}

/** Check if mouse has moved past a drag threshold */
export function pastDragThreshold(
  posX: number, posY: number,
  startX: number, startY: number,
  threshold: number
): boolean {
  const dx = posX - startX;
  const dy = posY - startY;
  return dx * dx + dy * dy >= threshold * threshold;
}

/** Create a world-transform pair (toLocal / toWorld) for a rotated curve symbol.
 *  Arc center is at (acx, acy), symbol center at (scx, scy). */
export function createCurveTransforms(
  acx: number, acy: number,
  scx: number, scy: number,
  curveRotRad: number
) {
  const invCos = Math.cos(-curveRotRad), invSin = Math.sin(-curveRotRad);
  const fwdCos = Math.cos(curveRotRad), fwdSin = Math.sin(curveRotRad);

  /** World → arc-local (Y up) */
  function toLocal(wx: number, wy: number): Vec2 {
    let lx = wx, ly = wy;
    if (curveRotRad) {
      const dx = wx - scx, dy = wy - scy;
      lx = scx + dx * invCos - dy * invSin;
      ly = scy + dx * invSin + dy * invCos;
    }
    return [lx - acx, acy - ly];
  }

  /** Unrotated-local → world */
  function toWorld(localX: number, localY: number): Vec2 {
    if (!curveRotRad) return [localX, localY];
    const dx = localX - scx, dy = localY - scy;
    return [scx + dx * fwdCos - dy * fwdSin, scy + dx * fwdSin + dy * fwdCos];
  }

  return { toLocal, toWorld };
}
