/** Grid snapping and valid position finding */

import { layout } from '../stores/layout.svelte.js';
import { getAABB } from './distance.js';
import { checkSpacingViolation } from './collision.js';

export function snapToGrid(x: number, y: number, w?: number, h?: number, rotation?: number): { x: number; y: number } {
  if (!layout.snapEnabled) return { x, y };
  const size = layout.gridSize;
  if (!rotation || !w || !h) {
    return { x: Math.round(x / size) * size, y: Math.round(y / size) * size };
  }
  const aabb = getAABB(x, y, w, h, rotation);
  const snappedAabbX = Math.round(aabb.x / size) * size;
  const snappedAabbY = Math.round(aabb.y / size) * size;
  return {
    x: snappedAabbX + aabb.w / 2 - w / 2,
    y: snappedAabbY + aabb.h / 2 - h / 2,
  };
}

export function findValidPosition(
  id: number, x: number, y: number, w: number, h: number,
  symbolId: string, rotation: number, curveAngle?: number, w2?: number, mirrored?: boolean
): { x: number; y: number } {
  const snapped = snapToGrid(x, y, w, h, rotation);
  let sx = snapped.x, sy = snapped.y;
  if (!checkSpacingViolation(id, sx, sy, w, h, rotation, symbolId, curveAngle, w2, mirrored)) return { x: sx, y: sy };

  const step = layout.snapEnabled ? layout.gridSize : 1;
  const searchRadius = 20;
  for (let r = 1; r <= searchRadius; r++) {
    for (let dx = -r; dx <= r; dx++) {
      for (let dy = -r; dy <= r; dy++) {
        if (Math.abs(dx) !== r && Math.abs(dy) !== r) continue;
        const cx = sx + dx * step;
        const cy = sy + dy * step;
        const bb = getAABB(cx, cy, w, h, rotation);
        if (bb.x < 0 || bb.y < 0 || bb.x + bb.w > layout.canvasW || bb.y + bb.h > layout.canvasH) continue;
        if (!checkSpacingViolation(id, cx, cy, w, h, rotation, symbolId, curveAngle, w2, mirrored)) return { x: cx, y: cy };
      }
    }
  }
  return { x: sx, y: sy };
}
