"""Fehlende Ausruestung aus der offenen Depot-Truhe zurueckholen.

Beim Einlagern wandert alles in die Truhe, was nicht auf der
Behalten-Liste steht. Trotzdem kann Ausruestung fehlen: Seil oder
Schaufel wurden bei einem frueheren Lauf mit eingelagert, ein Trank ist
aufgebraucht. Ohne Seil und Schaufel kommt der Charakter nicht durch die
Hoehle - der naechste Zug waere sofort zu Ende.

Darum nach dem Einlagern: Was fehlt im Rucksack, liegt aber in der
Truhe? Das wird zurueckgeholt.

Bewusst eng gehalten - nur Dinge, die der Bot sicher wiedererkennt und
die er wirklich braucht. Was er nicht erkennt, bleibt liegen.
"""
from src.repositories.inventory.core import images
from src.utils.core import locate
from src.utils.humanize import pause
from src.utils.mouse import drag
from ...typings import Context
from .common.base import BaseTask


# Vorlagen-Namen aus images['slots'], die im Rucksack liegen sollen.
BENOETIGT = ('rope', 'shovel')

FELD = 32
ABSTAND = 37
SPALTEN = 4
ZEILEN = 5


class TakeSuppliesTask(BaseTask):
    def __init__(self, containerBarImage, sourceContainerImage):
        super().__init__()
        self.name = 'takeSupplies'
        self.terminable = False
        self.containerBarImage = containerBarImage
        self.sourceContainerImage = sourceContainerImage

    def _fehlt(self, screenshot, barPosition):
        """Namen, die im Rucksack nicht zu sehen sind."""
        bereich = screenshot[
            barPosition[1] + 18:barPosition[1] + 18 + ZEILEN * ABSTAND,
            barPosition[0] + 10:barPosition[0] + 10 + SPALTEN * ABSTAND,
        ]
        fehlend = []
        for name in BENOETIGT:
            vorlage = images['slots'].get(name)
            if vorlage is None:
                continue
            if locate(bereich, vorlage, confidence=0.85) is None:
                fehlend.append(name)
        return fehlend

    def _inTruhe(self, screenshot, truhePosition, name):
        """Fundstelle eines Items in der Truhe - oder None."""
        vorlage = images['slots'].get(name)
        if vorlage is None:
            return None
        bereich = screenshot[
            truhePosition[1]:truhePosition[1] + ZEILEN * ABSTAND,
            truhePosition[0]:truhePosition[0] + SPALTEN * ABSTAND,
        ]
        treffer = locate(bereich, vorlage, confidence=0.85)
        if treffer is None:
            return None
        return (truhePosition[0] + treffer[0] + 16,
                truhePosition[1] + treffer[1] + 10)

    def do(self, context: Context) -> Context:
        screenshot = context['ng_screenshot']
        barPosition = locate(
            screenshot, self.containerBarImage, confidence=0.8)
        truhePosition = locate(
            screenshot, self.sourceContainerImage, confidence=0.8)
        if barPosition is None or truhePosition is None:
            self.terminable = True
            return context

        fehlend = self._fehlt(screenshot, barPosition)
        if not fehlend:
            self.terminable = True
            return context

        for name in fehlend:
            quelle = self._inTruhe(screenshot, truhePosition, name)
            if quelle is None:
                continue
            drag(quelle, (barPosition[0] + 10 + 16, barPosition[1] + 18 + 10))
            pause(0.5)
            return context

        # Nichts davon liegt in der Truhe - dann ist hier nichts zu holen.
        self.terminable = True
        return context
