import { describe, expect, it } from 'vitest';
import { readMenuInput, type MenuActionMap, type MenuInputSource } from '../menuInput';

/** Фейковый источник: нажатия задаются списком действий на тик. */
function fakeInput(pressed: string[]): MenuInputSource & { pressed: string[] } {
    return { pressed, isActionJustPressed: (a) => pressed.includes(a) };
}

const MAP: MenuActionMap = { up: 'up', down: 'down', confirm: 'advance', cancel: 'menu' };

describe('readMenuInput', () => {
    it('движение и подтверждение по карте действий', () => {
        const ev = readMenuInput(fakeInput(['down']), 2, MAP);
        expect(ev).toEqual([{ kind: 'move', delta: 1, index: 2 }]);
        expect(readMenuInput(fakeInput(['advance']), 1, MAP)).toEqual([
            { kind: 'confirm', index: 1 }
        ]);
        expect(readMenuInput(fakeInput(['menu']), 1, MAP)).toEqual([{ kind: 'cancel' }]);
    });

    it('cancel замыкает тик — остальные события не читаются', () => {
        const ev = readMenuInput(fakeInput(['menu', 'down', 'advance']), 0, MAP);
        expect(ev).toEqual([{ kind: 'cancel' }]);
    });

    it('up и down в один тик дают один move', () => {
        const ev = readMenuInput(fakeInput(['up', 'down']), 0, MAP);
        expect(ev).toEqual([{ kind: 'move', delta: -1, index: 0 }]);
    });

    it('нажатые left/right подавляют confirm (настройки: без двойного шага)', () => {
        const map: MenuActionMap = { ...MAP, left: 'left', right: 'right' };
        const ev = readMenuInput(fakeInput(['right', 'advance']), 3, map);
        expect(ev).toEqual([{ kind: 'adjust', delta: 1, index: 3 }]);
        const onlyEnter = readMenuInput(fakeInput(['advance']), 3, map);
        expect(onlyEnter).toEqual([{ kind: 'confirm', index: 3 }]);
    });

    it('extra-действия читаются последними', () => {
        const map: MenuActionMap = { ...MAP, extra: ['attack'] };
        const ev = readMenuInput(fakeInput(['down', 'attack']), 1, map);
        expect(ev).toEqual([
            { kind: 'move', delta: 1, index: 1 },
            { kind: 'action', action: 'attack', index: 1 }
        ]);
    });
});