import { describe, expect, it } from 'vitest';
import { hasLineOfSight, tileOpaque } from '../los';
import { buildMeadowsMap } from '../../../data/map';
import { mapWithWall } from '../../../testing/maps';

describe('hasLineOfSight', () => {
    const opaque = tileOpaque({ data: mapWithWall() });

    it('свободная линия видна', () => {
        expect(hasLineOfSight({ x: 0.5, y: 0.5 }, { x: 4.5, y: 0.5 }, opaque)).toBe(true);
    });

    it('стена в середине перекрывает обзор', () => {
        expect(hasLineOfSight({ x: 0.5, y: 5.5 }, { x: 9.5, y: 5.5 }, opaque)).toBe(false);
    });

    it('линия мимо стены видит', () => {
        expect(hasLineOfSight({ x: 0.5, y: 0.5 }, { x: 9.5, y: 4.5 }, opaque)).toBe(true);
    });

    it('короткие отрезки и нулевая длина видимы', () => {
        expect(hasLineOfSight({ x: 3, y: 3 }, { x: 3.2, y: 3 }, opaque)).toBe(true);
        expect(hasLineOfSight({ x: 3, y: 3 }, { x: 3, y: 3 }, opaque)).toBe(true);
    });

    it('вне карты — непрозрачно', () => {
        expect(hasLineOfSight({ x: 9.5, y: 5.5 }, { x: 15.5, y: 5.5 }, opaque)).toBe(false);
    });
});

describe('tileOpaque на реальной карте', () => {
    it('дерево/дом непрозрачны, трава/тропа/вода прозрачны', () => {
        const data = buildMeadowsMap();
        const map = { data };
        const is = tileOpaque(map);
        // Дерево и воду ищем на карте: раскладка seeded, но не привязываем тест к координате.
        let tree: { x: number; y: number } | null = null;
        let water: { x: number; y: number } | null = null;
        for (let y = 0; y < data.height; y++) {
            for (let x = 0; x < data.width; x++) {
                const t = data.tiles[y * data.width + x];
                if (t === 3 && !tree) tree = { x, y };
                if (t === 2 && !water) water = { x, y };
            }
        }
        expect(tree).not.toBeNull();
        expect(water).not.toBeNull();
        expect(is(tree!.x, tree!.y)).toBe(true); // дерево
        expect(is(16, 28)).toBe(false); // трава у спавна
        expect(is(water!.x, water!.y)).toBe(false); // вода прозрачна
    });
});