import numpy as np

from src.gameplay import backpackWatch as watchModule
from src.gameplay.backpackWatch import ensureBackpacksOpen


def _context(main='Fur Backpack', loot='Demon Backpack'):
    return {
        'ng_pause': False,
        'ng_screenshot': np.zeros((200, 400), dtype=np.uint8),
        'ng_cave': {'enabled': True},
        'ng_backpacks': {'main': main, 'loot': loot},
    }


def test_opens_missing_backpacks(mocker):
    mocker.patch.object(
        watchModule.inventoryCore, 'isContainerOpen', return_value=False)
    mocker.patch.object(
        watchModule, 'locate', return_value=(100, 50, 32, 32))
    clickSpy = mocker.patch.object(watchModule, 'useClick')
    context = _context()

    ensureBackpacksOpen(context)

    assert clickSpy.call_count == 2
    clickSpy.assert_called_with((105, 55))


def test_open_backpacks_stay_untouched(mocker):
    mocker.patch.object(
        watchModule.inventoryCore, 'isContainerOpen', return_value=True)
    clickSpy = mocker.patch.object(watchModule, 'useClick')
    context = _context()

    ensureBackpacksOpen(context)

    clickSpy.assert_not_called()


def test_paused_or_disabled_skips(mocker):
    mocker.patch.object(
        watchModule.inventoryCore, 'isContainerOpen', return_value=False)
    clickSpy = mocker.patch.object(watchModule, 'useClick')

    context = _context()
    context['ng_pause'] = True
    ensureBackpacksOpen(context)
    context = _context()
    context['ng_cave']['enabled'] = False
    ensureBackpacksOpen(context)

    clickSpy.assert_not_called()


def test_same_backpack_opens_only_once(mocker):
    mocker.patch.object(
        watchModule.inventoryCore, 'isContainerOpen', return_value=False)
    mocker.patch.object(
        watchModule, 'locate', return_value=(100, 50, 32, 32))
    clickSpy = mocker.patch.object(watchModule, 'useClick')
    context = _context(main='Fur Backpack', loot='Fur Backpack')

    ensureBackpacksOpen(context)

    assert clickSpy.call_count == 1
