import { describe, it, expect } from 'vitest';
import { fromTiledIso, type TiledMap } from '../tiled';

const tiled: TiledMap = {
    width: 4,
    height: 3,
    tilewidth: 32,
    tileheight: 16,
    orientation: 'isometric',
    tilesets: [{ firstgid: 1 }],
    layers: [
        { type: 'tilelayer', name: 'ground', data: [1, 1, 2, 1, 1, 3, 1, 1, 0, 1, 1, 1] },
        { type: 'tilelayer', name: 'props', data: [0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0] },
        { type: 'objectgroup', name: 'spawns', objects: [] }
    ]
} as unknown as TiledMap;

describe('fromTiledIso', () => {
    it('смещает gid на firstgid и склеивает слои', () => {
        const map = fromTiledIso(tiled, { blocked: [2] });
        expect(map.width).toBe(4);
        expect(map.height).toBe(3);
        expect(map.tiles).toEqual([
            0, 0, 1, 0, // ground: 1,1,2,1
            0, 2, 0, 0, // ground: 1,3,1,1
            2, 0, 0, 0  // props: верхний слой кладёт 2 на пустое место (index 8)
        ]);
        expect(map.blocked).toEqual([2]);
    });

    it('фильтрует слои по имени', () => {
        const map = fromTiledIso(tiled, { layers: ['ground'] });
        expect(map.tiles[9]).toBe(0); // props-слой не применён
    });

    it('отвергает не-изометрическую ориентацию', () => {
        expect(() => fromTiledIso({ ...tiled, orientation: 'orthogonal' })).toThrow(/isometric/);
    });

    it('отвергает слой неверного размера', () => {
        const bad = {
            ...tiled,
            layers: [{ type: 'tilelayer', name: 'bad', data: [1, 2, 3] }]
        };
        expect(() => fromTiledIso(bad)).toThrow(/размера/);
    });

    it('игнорирует невидимые слои', () => {
        const hidden = {
            ...tiled,
            layers: [
                { type: 'tilelayer', name: 'ground', visible: false, data: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] },
                { type: 'tilelayer', name: 'ok', data: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
            ]
        };
        const map = fromTiledIso(hidden);
        expect(map.tiles[0]).toBe(1);
    });
});