from src.gameplay.core.tasks.attackClosestCreature import AttackClosestCreatureTask
from src.gameplay.core.tasks.clickInClosestCreature import ClickInClosestCreatureTask
from src.gameplay.core.tasks.walkToTargetCreature import WalkToTargetCreatureTask


context = {'ng_cave': {'runToCreatures': True}}

def test_should_test_default_params():
    task = AttackClosestCreatureTask()
    assert task.name == 'attackClosestCreature'
    assert task.isRootTask == 1

def test_onBeforeStart():
    task = AttackClosestCreatureTask()
    assert task.onBeforeStart(context) == context
    assert len(task.tasks) == 2
    assert isinstance(task.tasks[0], ClickInClosestCreatureTask)
    assert task.tasks[0].parentTask == task
    assert task.tasks[0].rootTask == task
    assert isinstance(task.tasks[1], WalkToTargetCreatureTask)
    assert task.tasks[1].parentTask == task
    assert task.tasks[1].rootTask == task


def _confirmContext(isAttacking=False, monsterCount=1):
    return {
        'ng_cave': {
            'runToCreatures': True,
            'isAttackingSomeCreature': isAttacking,
            'closestCreature': {'name': 'wasp'},
        },
        'gameWindow': {
            'monsters': [{'slot': (7, 5)}] * monsterCount,
        },
        'ng_targeting': {},
    }


def test_unconfirmed_attack_escapes_and_ignores_creature(mocker):
    from src.gameplay.core.tasks.attackClosestCreature import (
        ATTACK_CONFIRM_LOOP_LIMIT,
    )
    pressSpy = mocker.patch('src.utils.keyboard.press')
    ignoreSpy = mocker.patch(
        'src.gameplay.core.tasks.attackClosestCreature.ignoreCreatureTemporarily')
    task = AttackClosestCreatureTask()
    context = _confirmContext(isAttacking=False)

    result = False
    for _ in range(ATTACK_CONFIRM_LOOP_LIMIT):
        result = task.shouldManuallyComplete(context)

    assert result is True
    pressSpy.assert_called_once_with('esc')
    ignoreSpy.assert_called_once_with(context, 'wasp')


def test_confirmed_attack_resets_counter(mocker):
    from src.gameplay.core.tasks.attackClosestCreature import (
        ATTACK_CONFIRM_LOOP_LIMIT,
    )
    mocker.patch('src.utils.keyboard.press')
    task = AttackClosestCreatureTask()
    context = _confirmContext(isAttacking=False)

    for _ in range(ATTACK_CONFIRM_LOOP_LIMIT - 1):
        task.shouldManuallyComplete(context)
    context['ng_cave']['isAttackingSomeCreature'] = True
    assert task.shouldManuallyComplete(context) is False
    assert task.loopsWithoutAttackConfirm == 0
