import { describe, expect, it } from 'vitest';
import type { TileMapData } from '../IsometricTileMap';
import { renderMinimap } from '../minimap';

/** Карта 3×2: два разных тайла + заблокированная клетка. */
function tinyMap(): TileMapData {
    return {
        width: 3,
        height: 2,
        tiles: [1, 2, 1, 2, 1, 2],
        blocked: [0, 0, 1, 0, 0, 0],
    };
}

const px = (img: { width: number; rgba: Uint8Array }, x: number, y: number): [number, number, number] => {
    const i = (y * img.width + x) * 4;
    return [img.rgba[i]!, img.rgba[i + 1]!, img.rgba[i + 2]!];
};

describe('renderMinimap', () => {
    it('размер картинки = карта × cell', () => {
        const img = renderMinimap(tinyMap(), { colors: { 1: 0x101010, 2: 0x202020 }, cell: 3 });
        expect(img.width).toBe(9);
        expect(img.height).toBe(6);
        expect(img.rgba.length).toBe(9 * 6 * 4);
    });

    it('клетка целиком красится цветом своего тайла', () => {
        const img = renderMinimap(tinyMap(), { colors: { 1: 0xff0000, 2: 0x00ff00 }, cell: 2 });
        // Тайл (0,0) = id 1, тайл (1,0) = id 2.
        expect(px(img, 0, 0)).toEqual([255, 0, 0]);
        expect(px(img, 1, 1)).toEqual([255, 0, 0]);
        expect(px(img, 2, 0)).toEqual([0, 255, 0]);
        expect(px(img, 5, 3)).toEqual([0, 255, 0]);
    });

    it('незаданный тайл — fallbackColor', () => {
        const img = renderMinimap(tinyMap(), { colors: { 1: 0xff0000 }, fallbackColor: 0x0a0b0c, cell: 2 });
        expect(px(img, 2, 0)).toEqual([10, 11, 12]);
        // И без явного fallback — тёмный по умолчанию.
        const plain = renderMinimap(tinyMap(), { colors: { 1: 0xff0000 }, cell: 2 });
        expect(px(plain, 2, 0)[0]).toBeLessThan(64);
    });

    it('маркер перекрашивает свою клетку с тёмной рамкой', () => {
        const img = renderMinimap(tinyMap(), {
            colors: { 1: 0x101010, 2: 0x101010 },
            cell: 3,
            markers: [{ x: 1, y: 1, color: 0xffff00 }],
        });
        // Центр клетки — цвет маркера, угол — рамка.
        expect(px(img, 4, 4)).toEqual([255, 255, 0]);
        expect(px(img, 3, 3)[0]).toBeLessThan(64);
        // Соседняя клетка не задета.
        expect(px(img, 7, 4)).toEqual([16, 16, 16]);
    });

    it('маркер вне карты молча пропускается', () => {
        const img = renderMinimap(tinyMap(), {
            colors: { 1: 0x101010, 2: 0x101010 },
            cell: 2,
            markers: [{ x: 9, y: 9, color: 0xffff00 }],
        });
        expect(px(img, 0, 0)).toEqual([16, 16, 16]);
    });

    it('проп красит весь footprint своим цветом поверх тайлов', () => {
        const map = { ...tinyMap(), props: [{ id: 7, x: 0, y: 0, w: 2, h: 2 }] };
        const img = renderMinimap(map, { colors: { 1: 0xff0000, 2: 0x00ff00, 7: 0x0000ff }, cell: 3 });
        // Клетки (0,0) и (1,1) — под пропом, тайл 1/2 перекрашен синим.
        expect(px(img, 0, 0)).toEqual([0, 0, 255]);
        expect(px(img, 4, 4)).toEqual([0, 0, 255]);
        // Клетка вне footprint осталась цветом своего тайла (id 1 — красный).
        expect(px(img, 7, 0)).toEqual([255, 0, 0]);
    });

    it('проп без записи в colors — fallbackColor', () => {
        const map = { ...tinyMap(), props: [{ id: 7, x: 2, y: 1, w: 1, h: 1 }] };
        const img = renderMinimap(map, { colors: { 1: 0x101010, 2: 0x101010 }, fallbackColor: 0x3c3c48, cell: 3 });
        expect(px(img, 8, 4)).toEqual([60, 60, 72]);
    });

    it('footprint у края карты не выходит за границы', () => {
        // Проп 3×3 от (1,0): правый столбец клеток вылезает за ширину 3.
        const map = { ...tinyMap(), props: [{ id: 7, x: 1, y: 0, w: 3, h: 3 }] };
        const img = renderMinimap(map, { colors: { 1: 0x101010, 7: 0x0000ff }, cell: 3 });
        expect(() => px(img, 8, 5)).not.toThrow();
        // Клетка (2,0) под пропом покрашена, выход за карту не рисуется.
        expect(px(img, 8, 0)).toEqual([0, 0, 255]);
    });
});