import { DamageSystem, FIREBALL_KILL_RADIUS, SMOKE_KILL_RADIUS } from '@logic/DamageSystem';
import { PlayerStateMachine } from '@logic/PlayerStateMachine';
import { PlayerColorState } from '@common/Constants';

function setup() {
    const psm = new PlayerStateMachine();
    return { psm, ds: new DamageSystem(psm) };
}

describe('DamageSystem — fireball distance gate (req 10.4)', () => {
    it('misses when distance exceeds FIREBALL_KILL_RADIUS', () => {
        const { ds } = setup();
        const r = ds.applyToPlayer({
            attackType: 'fireball',
            attackerX: 0,
            attackerY: 0,
            victimX: FIREBALL_KILL_RADIUS + 10,
            victimY: 0,
        });
        expect(r).toBeNull();
    });

    it('kills when within radius regardless of color', () => {
        const { psm, ds } = setup();
        psm.pickupCrystalJade();
        psm.pickupCrystalJade();
        const r = ds.applyToPlayer({
            attackType: 'fireball',
            attackerX: 0,
            attackerY: 0,
            victimX: 50,
            victimY: 0,
        });
        expect(r!.kind).toBe('died');
        expect(psm.color).toBe(PlayerColorState.Red);
    });
});

describe('DamageSystem — smoke bomb distance gate (req 10.5)', () => {
    it('misses when distance exceeds SMOKE_KILL_RADIUS', () => {
        const { ds } = setup();
        const r = ds.applyToPlayer({
            attackType: 'smoke_bomb',
            attackerX: 0,
            attackerY: 0,
            victimX: SMOKE_KILL_RADIUS + 1,
            victimY: 0,
        });
        expect(r).toBeNull();
    });

    it('kills when within radius', () => {
        const { ds } = setup();
        const r = ds.applyToPlayer({
            attackType: 'smoke_bomb',
            attackerX: 0,
            attackerY: 0,
            victimX: 40,
            victimY: 0,
        });
        expect(r!.kind).toBe('died');
    });
});

describe('DamageSystem — precedence (req 10.3)', () => {
    it('i-frames beat fireball distance check', () => {
        const { psm, ds } = setup();
        psm.takeHit('shuriken'); // die → consumes a life and starts i-frames
        const r = ds.applyToPlayer({
            attackType: 'fireball',
            attackerX: 0,
            attackerY: 0,
            victimX: 10,
            victimY: 0,
        });
        expect(r).toEqual({ kind: 'no_effect', reason: 'iframe' });
    });
});

describe('DamageSystem — applyToEnemy helper', () => {
    it('reduces HP and floors at 0', () => {
        const { ds } = setup();
        expect(ds.applyToEnemy(3, 2)).toBe(1);
        expect(ds.applyToEnemy(1, 5)).toBe(0);
    });
});
