import { describe, it, expect } from 'vitest';
import { blockingSegments, segmentsIntersect, pathBlocked, computeVisibleCells } from './vision';

describe('vision', () => {
  it('detects crossing segments', () => {
    expect(segmentsIntersect({ x: 0, y: 0 }, { x: 10, y: 10 }, { x: 0, y: 10 }, { x: 10, y: 0 })).toBe(true);
    expect(segmentsIntersect({ x: 0, y: 0 }, { x: 10, y: 0 }, { x: 0, y: 5 }, { x: 10, y: 5 })).toBe(false);
  });

  it('open doors do not block; closed doors do', () => {
    const open = blockingSegments({ walls: [], doors: [{ a: { x: 0, y: 0 }, b: { x: 0, y: 10 }, open: true }] });
    const closed = blockingSegments({ walls: [], doors: [{ a: { x: 0, y: 0 }, b: { x: 0, y: 10 }, open: false }] });
    expect(open).toHaveLength(0);
    expect(closed).toHaveLength(1);
  });

  it('a wall hides the cell behind it but not beside it', () => {
    // vertical wall at x=100 from y=0..300; viewer at (50,150)
    const segs = blockingSegments({ walls: [{ points: [{ x: 100, y: 0 }, { x: 100, y: 300 }] }] });
    const grid = { gridSize: 100, cols: 3, rows: 3 }; // cell centers at 50/150/250
    const vis = computeVisibleCells({ viewers: [{ x: 50, y: 150 }], segments: segs, ...grid });
    expect(vis.has('0,1')).toBe(true);  // viewer's own cell
    expect(vis.has('2,1')).toBe(false); // directly behind the wall
  });

  it('respects sight radius', () => {
    const vis = computeVisibleCells({ viewers: [{ x: 50, y: 50 }], segments: [], gridSize: 100, cols: 5, rows: 1, radiusPx: 150 });
    expect(vis.has('0,0')).toBe(true);
    expect(vis.has('1,0')).toBe(true); // center (150,50) dist 100 ≤ 150
    expect(vis.has('4,0')).toBe(false); // center (450,50) dist 400 > 150
  });

  it('pathBlocked is false with no segments', () => {
    expect(pathBlocked({ x: 0, y: 0 }, { x: 100, y: 100 }, [])).toBe(false);
  });
});
