from src.gameplay.core.tasks import refill as refillModule
from src.gameplay.core.tasks.buyItem import BuyItemTask
from src.gameplay.core.tasks.refill import RefillTask


def _waypoint():
    return {
        'type': 'refill',
        'options': {
            'manaPotion': {'item': 'mana potion', 'quantity': 300},
            'healthPotion': {'item': 'health potion', 'quantity': 200},
            'healthPotionEnabled': True,
            'houseNpcEnabled': False,
        },
    }


def _context(death=None):
    context = {
        'ng_screenshot': None,
        'healing': {'potions': {
            'firstHealthPotion': {'slot': 1, 'hotkey': 'F1'},
            'firstManaPotion': {'slot': 2, 'hotkey': 'F2'},
        }},
    }
    if death is not None:
        context['ng_death'] = death
    return context


def _buyAmounts(task):
    return {
        buy.itemName: buy.itemQuantity
        for buy in task.tasks if isinstance(buy, BuyItemTask)
    }


def test_refill_buys_full_target_without_death(mocker):
    mocker.patch.object(refillModule, 'getSlotCount', return_value=0)
    task = RefillTask(_waypoint())

    task.onBeforeStart(_context())

    assert _buyAmounts(task) == {'mana potion': 300, 'health potion': 200}


def test_refill_cap_limits_emergency_purchase(mocker):
    mocker.patch.object(refillModule, 'getSlotCount', return_value=0)
    task = RefillTask(_waypoint())

    task.onBeforeStart(_context(death={'refillCap': 30}))

    assert _buyAmounts(task) == {'mana potion': 30, 'health potion': 30}


def test_refill_cap_does_not_exceed_needed_amount(mocker):
    mocker.patch.object(refillModule, 'getSlotCount', return_value=290)
    task = RefillTask(_waypoint())

    task.onBeforeStart(_context(death={'refillCap': 30}))

    # Es fehlen nur 10/0 — die Kappung kauft nicht mehr als noetig.
    assert _buyAmounts(task) == {'mana potion': 10, 'health potion': 0}


def test_refill_treats_unreadable_slot_as_zero(mocker):
    mocker.patch.object(refillModule, 'getSlotCount', return_value=None)
    task = RefillTask(_waypoint())

    task.onBeforeStart(_context())

    assert _buyAmounts(task) == {'mana potion': 300, 'health potion': 200}
