import { ConfigMgr, MapJsonLoader } from '@data/ConfigMgr';
import { LevelMgr } from '@logic/LevelMgr';
import { cameraFromLevel } from '@logic/CameraScroller';
import { EnemyType } from '@data/Interfaces';

// Reuse delivered JSON.
import enemies from '../../assets/resources/configs/enemies.json';
import items from '../../assets/resources/configs/items.json';
import weapons from '../../assets/resources/configs/weapons.json';
import levels from '../../assets/resources/configs/levels.json';
import bosses from '../../assets/resources/configs/bosses.json';
import stories from '../../assets/resources/configs/stories.json';

async function loadBundle() {
    const mgr = new ConfigMgr(
        new MapJsonLoader({
            'configs/enemies': enemies,
            'configs/items': items,
            'configs/weapons': weapons,
            'configs/levels': levels,
            'configs/bosses': bosses,
            'configs/stories': stories,
        })
    );
    await mgr.load();
    return mgr;
}

describe('Chapter-1 levels — JSON × LevelMgr integration (task 7.2)', () => {
    it('exposes all 5 levels (1-1 … 1-5)', async () => {
        const mgr = await loadBundle();
        for (const id of ['1-1', '1-2', '1-3', '1-4', '1-5']) {
            expect(mgr.level(id)).toBeDefined();
        }
    });

    it('1-1 requires killing 3 妖坊 within 75s (req 8.1)', async () => {
        const mgr = await loadBundle();
        const lv = mgr.level('1-1');
        expect(lv.timeLimitSec).toBe(75);
        expect(lv.objective).toEqual({ kind: 'kill_count', enemy: EnemyType.YaoFang, count: 3 });
    });

    it('1-3 is a bi-directional cave stage with 10 青忍 objective (req 8.3)', async () => {
        const mgr = await loadBundle();
        const lv = mgr.level('1-3');
        expect(lv.scrollDirection).toBe('horizontal_bi');
        expect(lv.objective).toEqual({ kind: 'kill_count', enemy: EnemyType.QingRen, count: 10 });
    });

    it('1-4 is a vertical castle-wall stage with reach_top objective (req 8.4)', async () => {
        const mgr = await loadBundle();
        const lv = mgr.level('1-4');
        expect(lv.scrollDirection).toBe('vertical');
        expect(lv.objective).toEqual({ kind: 'reach_top' });
    });

    it('1-5 is a defeat-boss objective pointing at 双幻坊 (req 8.5)', async () => {
        const mgr = await loadBundle();
        const lv = mgr.level('1-5');
        expect(lv.objective.kind).toBe('defeat_boss');
        expect(lv.objective.bossId).toBe('shuang_huan_fang');
    });

    it('CameraScroller instantiates cleanly from each chapter-1 level', async () => {
        const mgr = await loadBundle();
        for (const id of ['1-1', '1-2', '1-3', '1-4', '1-5']) {
            const cam = cameraFromLevel(mgr.level(id));
            expect(cam.offsetX).toBe(0);
            expect(cam.offsetY).toBe(0);
        }
    });

    it('LevelMgr drives every level to victory via its configured objective', async () => {
        const mgr = await loadBundle();
        for (const id of ['1-1', '1-2', '1-3', '1-4', '1-5']) {
            const lv = new LevelMgr(mgr.level(id));
            switch (lv.level.objective.kind) {
                case 'kill_count':
                    for (let k = 0; k < (lv.level.objective.count ?? 0); k++) {
                        lv.onEnemyKilled(lv.level.objective.enemy!);
                    }
                    break;
                case 'reach_top':
                    lv.onReachedTop();
                    break;
                case 'defeat_boss':
                    lv.onBossKilled();
                    break;
            }
            expect(lv.tick(0.016)).toBe('victory');
        }
    });
});
