from src.gameplay import death as deathModule
from src.gameplay import vitals as vitalsModule
from src.gameplay.vitals import watchVitals


def _context(hp=100, previous=(100, 100, 7), current=(100, 100, 7), task=None):
    rootTask = type('Task', (), {'name': task})() if task else None
    context = {
        'ng_pause': False,
        'ng_screenshot': None,
        'ng_statusBar': {'hpPercentage': hp},
        'ng_radar': {'coordinate': list(current) if current else None},
        'ng_tasksOrchestrator': type('Orch', (), {'rootTask': rootTask})(),
        'ng_vitals': {},
    }
    if previous is not None:
        context['ng_vitals']['coordinate'] = list(previous)
    return context


def test_death_records_monster_death(mocker):
    logSpy = mocker.patch.object(deathModule, 'logEvent')
    mocker.patch.object(deathModule, 'saveEventScreenshot')
    context = _context(hp=0)

    watchVitals(context)

    assert context['ng_pause'] is False
    assert logSpy.call_args[0][0] == 'deathByMonster'
    assert context['ng_death']['killer'] == 'monster'


def test_death_with_recent_player_sighting_pauses(mocker):
    logSpy = mocker.patch.object(deathModule, 'logEvent')
    mocker.patch.object(deathModule, 'saveEventScreenshot')
    context = _context(hp=0)
    context['gameWindow'] = {'players': [{'name': 'Pk Killa'}]}

    watchVitals(context)

    assert context['ng_pause'] is True
    assert logSpy.call_args[0][0] == 'deathByPlayer'


def test_teleport_skipped_during_death_recovery(mocker):
    mocker.patch.object(vitalsModule, 'logEvent')
    context = _context(previous=(100, 100, 7), current=(180, 160, 7))
    context['ng_death'] = {'killer': 'monster', 'coordinate': [100, 100, 7]}

    watchVitals(context)

    assert context['ng_pause'] is False


def test_teleport_jump_pauses(mocker):
    logSpy = mocker.patch.object(vitalsModule, 'logEvent')
    context = _context(previous=(100, 100, 7), current=(180, 160, 7))

    watchVitals(context)

    assert context['ng_pause'] is True
    assert logSpy.call_args[0][0] == 'teleportDetected'


def test_normal_movement_is_no_teleport(mocker):
    mocker.patch.object(vitalsModule, 'logEvent')
    context = _context(previous=(100, 100, 7), current=(110, 108, 7))

    watchVitals(context)

    assert context['ng_pause'] is False


def test_travel_tasks_allow_big_jumps(mocker):
    mocker.patch.object(vitalsModule, 'logEvent')
    context = _context(
        previous=(100, 100, 7), current=(400, 100, 7), task='bbotSay')

    watchVitals(context)

    assert context['ng_pause'] is False


def test_first_tick_only_seeds(mocker):
    mocker.patch.object(vitalsModule, 'logEvent')
    context = _context(previous=None, current=(100, 100, 7))

    watchVitals(context)

    assert context['ng_pause'] is False
    assert context['ng_vitals']['coordinate'] == [100, 100, 7]
