import { describe, it, expect } from 'vitest';
import type { FurnitureItem } from '@house-plan-maker/shared';
import { findCollidingFurniture } from '../collisionDetection';

function makeFurniture(overrides: Partial<FurnitureItem> = {}): FurnitureItem {
  return {
    id: 'f1',
    roomId: 'r1',
    type: 'TABLE',
    x: 0,
    y: 0,
    width: 1,
    depth: 1,
    height: 0.75,
    rotation: 0,
    elevationFromFloor: 0,
    label: null,
    positionAnchor: { horizontal: 'left', vertical: 'top' },
    ...overrides,
  };
}

describe('findCollidingFurniture', () => {
  it('returns empty set for fewer than 2 items', () => {
    expect(findCollidingFurniture([])).toEqual(new Set());
    expect(findCollidingFurniture([makeFurniture()])).toEqual(new Set());
  });

  it('detects overlapping furniture', () => {
    const items: readonly FurnitureItem[] = [
      makeFurniture({ id: 'f1', x: 0, y: 0, width: 2, depth: 2 }),
      makeFurniture({ id: 'f2', x: 1, y: 1, width: 2, depth: 2 }),
    ];
    const result = findCollidingFurniture(items);
    expect(result.has('f1')).toBe(true);
    expect(result.has('f2')).toBe(true);
  });

  it('returns empty set for non-overlapping furniture', () => {
    const items: readonly FurnitureItem[] = [
      makeFurniture({ id: 'f1', x: 0, y: 0, width: 1, depth: 1 }),
      makeFurniture({ id: 'f2', x: 5, y: 5, width: 1, depth: 1 }),
    ];
    const result = findCollidingFurniture(items);
    expect(result.size).toBe(0);
  });

  it('handles rotated furniture (AABB check)', () => {
    // A 2x1 table rotated 90 degrees becomes 1x2 AABB
    const items: readonly FurnitureItem[] = [
      makeFurniture({ id: 'f1', x: 0, y: 0, width: 2, depth: 0.5, rotation: 0 }),
      makeFurniture({ id: 'f2', x: 0, y: 0.5, width: 2, depth: 0.5, rotation: 0 }),
    ];
    const result = findCollidingFurniture(items);
    // These should be touching at edge, potentially overlapping depending on centers
    // f1 center at (0,0), AABB y range: -0.25 to 0.25
    // f2 center at (0,0.5), AABB y range: 0.25 to 0.75
    // They touch at y=0.25 but don't overlap (strict inequality)
    expect(result.size).toBe(0);
  });

  it('detects multiple collisions', () => {
    const items: readonly FurnitureItem[] = [
      makeFurniture({ id: 'f1', x: 0, y: 0, width: 2, depth: 2 }),
      makeFurniture({ id: 'f2', x: 0.5, y: 0.5, width: 2, depth: 2 }),
      makeFurniture({ id: 'f3', x: 10, y: 10, width: 1, depth: 1 }),
    ];
    const result = findCollidingFurniture(items);
    expect(result.has('f1')).toBe(true);
    expect(result.has('f2')).toBe(true);
    expect(result.has('f3')).toBe(false);
  });
});
