from time import monotonic

from src.repositories.gameWindow.slot import getSlotPosition
from src.repositories.inventory.core import images
from src.utils.core import locate
from src.utils.keyboard import press
from src.utils.mouse import drag


def handleBBotAutomation(context):
    bbot = context.get('ng_bbot')
    if not bbot:
        return context
    runtime = bbot.setdefault('runtime', {})
    _keep_alive(context, runtime)
    _anti_stuck(context, bbot, runtime)
    _drop_flask(context, bbot, runtime)
    return context


def handleBBotKeepAlive(context):
    bbot = context.get('ng_bbot')
    if bbot:
        _keep_alive(context, bbot.setdefault('runtime', {}))
    return context


def _keep_alive(context, runtime):
    coordinate = context['ng_radar']['coordinate']
    now = monotonic()
    if coordinate is not None and runtime.get('keepAliveCoordinate') != coordinate:
        runtime['keepAliveCoordinate'] = coordinate
        runtime['lastActivityAt'] = now
        return
    if 'lastActivityAt' not in runtime:
        runtime['lastActivityAt'] = now
        return
    if now - runtime.get('lastActivityAt', now) < 600:
        return
    # ponytail: alternate one step each way; use pathfinding only if idle terrain blocks this.
    direction = runtime.get('keepAliveDirection', 'right')
    press(direction)
    runtime['keepAliveDirection'] = 'left' if direction == 'right' else 'right'
    runtime['lastActivityAt'] = now


def _anti_stuck(context, bbot, runtime):
    seconds = bbot.get('antiStuckSeconds', 0)
    coordinate = context['ng_radar']['coordinate']
    if not seconds or coordinate is None:
        return
    now = monotonic()
    if runtime.get('lastCoordinate') != coordinate:
        runtime['lastCoordinate'] = coordinate
        runtime['lastMoveAt'] = now
        return
    if now - runtime.get('lastMoveAt', now) <= seconds:
        return
    root = context['ng_tasksOrchestrator'].rootTask
    # ponytail: only movement is reset; interrupting bank/refill actions risks item loss.
    if root is not None and root.name in {
        'walkToWaypoint', 'singleWalk', 'rightClickUseWaypoint',
        'useRopeWaypoint', 'useShovelWaypoint', 'useLadderWaypoint',
    }:
        context['ng_tasksOrchestrator'].reset()
        context['ng_cave']['waypoints']['state'] = None
    runtime['lastMoveAt'] = now


def _drop_flask(context, bbot, runtime):
    setting = bbot.get('autoDropFlasks', {})
    if not setting.get('enabled') or context['ng_screenshot'] is None:
        return
    now = monotonic()
    if (now - runtime.get('lastFlaskDropAt', 0)) * 1000 < setting.get('intervalMs', 3000):
        return
    backpack = context['ng_backpacks'].get('main')
    container_image = images['containersBars'].get(backpack)
    if container_image is None:
        return
    bar = locate(context['ng_screenshot'], container_image, confidence=0.8)
    if bar is None:
        return
    x0, y0 = bar[0], bar[1] + 18
    region = context['ng_screenshot'][y0:, x0:x0 + 150]
    for name in ('big empty potion flask', 'medium empty potion flask', 'small empty potion flask'):
        position = locate(region, images['slots'][name], confidence=0.9)
        if position is None:
            continue
        target = getSlotPosition((7, 5), context['gameWindow']['coordinate'])
        drag((x0 + position[0] + 16, y0 + position[1] + 10), target)
        runtime['lastFlaskDropAt'] = now
        return
