"""Inventar: Backpack-Auswahl mit Suche statt Scroll-Dropdown.

Die Liste kommt aus der kanonischen Container-Erkennung
(src.repositories.inventory.config) — nicht mehr aus einer
hartkodierten Teilmenge. Ungleich-Regel wird inline geprueft.

Darunter: Auto-Erkennung geoeffneter Backpacks (Scan-Button) und der
Loot-Regeln-Editor ("das Item > in das Backpack"), gespeichert in
ng_lootRules und ausgefuehrt vom Loot-Router im Loop.
"""
import customtkinter

from src.repositories.actionBar.slotIcons import SLOT_ITEMS
from src.repositories.inventory.config import images as containerImages
from src.ui import theme
from src.ui.widgets import Card, SearchableComboBox

BACKPACKS = sorted(
    name for name in containerImages['containersBars']
    if name != 'backpack bottom'
)
_ITEM_NAMES = sorted(set(SLOT_ITEMS.values()))
_ITEM_BY_NAME = {name: itemId for itemId, name in SLOT_ITEMS.items()}


class InventoryPage(customtkinter.CTkFrame):
    def __init__(self, master, context):
        super().__init__(master, fg_color='transparent')
        self.context = context
        self.grid_columnconfigure((0, 1), weight=1, uniform='cards')

        config = self.context.enabledProfile['config']['ng_backpacks']

        main = Card(
            self, 'Main Backpack',
            'Rucksack, aus dem gespielt wird')
        main.grid(row=0, column=0, padx=(0, 6), pady=(0, 10), sticky='nsew')
        self.mainPicker = SearchableComboBox(
            main.body, values=BACKPACKS,
            placeholder='Backpack suchen …',
            command=lambda _v: self.setMainBackpack(),
        )
        self.mainPicker.grid(row=0, column=0, sticky='ew')
        if config['main'] is not None:
            self.mainPicker.set(config['main'])

        loot = Card(
            self, 'Loot Backpack',
            'Ziel fuer gesammelte Items')
        loot.grid(row=0, column=1, padx=(6, 0), pady=(0, 10), sticky='nsew')
        self.lootPicker = SearchableComboBox(
            loot.body, values=BACKPACKS,
            placeholder='Backpack suchen …',
            command=lambda _v: self.setLootBackpack(),
        )
        self.lootPicker.grid(row=0, column=0, sticky='ew')
        if config['loot'] is not None:
            self.lootPicker.set(config['loot'])

        self.warningLabel = customtkinter.CTkLabel(
            self, text='', font=theme.font(11), text_color=theme.DANGER,
        )
        self.warningLabel.grid(row=1, column=0, columnspan=2, sticky='w')

        self._buildDetectedCard()
        self._buildRulesCard()

    # ---------------------------------------------------- Erkannte Backpacks
    def _buildDetectedCard(self):
        card = Card(
            self, 'Erkannte Backpacks',
            'geoeffnete Container auf dem Screen (live gescannt)')
        card.grid(row=2, column=0, padx=(0, 6), pady=(0, 10), sticky='nsew')
        self.detectedLabel = customtkinter.CTkLabel(
            card.body, text='Noch nicht gescannt.', font=theme.font(11),
            text_color=theme.MUTED, justify='left', wraplength=320,
        )
        self.detectedLabel.grid(row=0, column=0, sticky='w', pady=(0, 6))
        buttons = customtkinter.CTkFrame(card.body, fg_color='transparent')
        buttons.grid(row=1, column=0, sticky='w')
        customtkinter.CTkButton(
            buttons, text='Jetzt scannen', height=30, corner_radius=8,
            font=theme.font(11), fg_color=theme.ELEVATED,
            hover_color=theme.ACCENT_SOFT, text_color=theme.TEXT,
            command=self._scanBackpacks,
        ).grid(row=0, column=0, padx=(0, 6))
        customtkinter.CTkButton(
            buttons, text='Vollsetup starten', height=30, corner_radius=8,
            font=theme.font(11, 'bold'), fg_color=theme.ACCENT,
            hover_color=theme.ACCENT_HOVER, command=self._runFullSetup,
        ).grid(row=0, column=1)

    def _scanBackpacks(self):
        found = self.context.scanOpenBackpacks()
        if not found:
            self.detectedLabel.configure(
                text='Keine offenen Backpacks erkannt (Bot läuft?).')
            return
        names = sorted(found)
        self.detectedLabel.configure(text='\n'.join(names))

    def _runFullSetup(self):
        ok, message = self.context.runFullSetup()
        self.detectedLabel.configure(
            text=message,
            text_color=theme.SUCCESS if ok else theme.DANGER,
        )

    # --------------------------------------------------------- Loot-Regeln
    def _buildRulesCard(self):
        card = Card(
            self, 'Loot-Regeln',
            'Item > in dieses Backpack verschieben')
        card.grid(row=2, column=1, padx=(6, 0), pady=(0, 10), sticky='nsew')
        self.rulesFrame = customtkinter.CTkFrame(
            card.body, fg_color='transparent')
        self.rulesFrame.grid(row=0, column=0, sticky='ew')
        self.ruleRows = []
        for rule in self.context.getLootRules():
            self._addRuleRow(rule)
        footer = customtkinter.CTkFrame(card.body, fg_color='transparent')
        footer.grid(row=1, column=0, sticky='ew', pady=(6, 0))
        customtkinter.CTkButton(
            footer, text='+ Regel', height=30, corner_radius=8,
            font=theme.font(11), fg_color=theme.ELEVATED,
            hover_color=theme.ACCENT_SOFT, text_color=theme.TEXT,
            command=lambda: self._addRuleRow(),
        ).grid(row=0, column=0, sticky='w')
        self.dropUnwantedSwitch = customtkinter.CTkSwitch(
            footer, progress_color=theme.ACCENT, font=theme.font(11),
            text='Alles andere wegwerfen (nicht Tränke/Coins/Regeln)',
            command=self._toggleDropUnwanted,
        )
        self.dropUnwantedSwitch.grid(row=0, column=1, sticky='w', padx=(10, 0))
        if self.context.getLootDropUnwanted():
            self.dropUnwantedSwitch.select()

    def _toggleDropUnwanted(self):
        self.context.setLootDropUnwanted(
            self.dropUnwantedSwitch.get() == 1)

    def _targetValues(self):
        detected = self.context.context.get('ng_detectedBackpacks') or {}
        names = sorted(detected) or BACKPACKS
        return ['wegwerfen'] + names

    def _addRuleRow(self, rule=None):
        rule = rule or {}
        index = len(self.ruleRows)
        frame = customtkinter.CTkFrame(
            self.rulesFrame, fg_color=theme.ELEVATED, corner_radius=8)
        frame.grid(row=index, column=0, sticky='ew', pady=2)

        itemCombo = SearchableComboBox(
            frame, values=_ITEM_NAMES, placeholder='Item …',
            command=lambda _v: self._saveRules())
        itemCombo.grid(row=0, column=0, padx=(6, 2), pady=6, sticky='ew')
        itemName = SLOT_ITEMS.get(rule.get('itemId'))
        if itemName:
            itemCombo.set(itemName)

        customtkinter.CTkLabel(
            frame, text='→', font=theme.font(12),
            text_color=theme.MUTED,
        ).grid(row=0, column=1, padx=2)

        targetCombo = SearchableComboBox(
            frame, values=self._targetValues(), placeholder='Backpack …',
            command=lambda _v: self._saveRules())
        targetCombo.grid(row=0, column=2, padx=2, pady=6, sticky='ew')
        if rule.get('drop'):
            targetCombo.set('wegwerfen')
        elif rule.get('to'):
            targetCombo.set(rule['to'])

        deleteButton = customtkinter.CTkButton(
            frame, text='✕', width=28, height=28, corner_radius=8,
            font=theme.font(11), fg_color='transparent',
            hover_color=theme.DANGER, text_color=theme.MUTED,
            command=lambda: self._deleteRuleRow(frame, entry))
        deleteButton.grid(row=0, column=3, padx=(2, 6), pady=6)

        frame.grid_columnconfigure((0, 2), weight=1)
        entry = {'frame': frame, 'item': itemCombo, 'target': targetCombo}
        self.ruleRows.append(entry)
        self._saveRules()

    def _deleteRuleRow(self, frame, entry):
        frame.destroy()
        if entry in self.ruleRows:
            self.ruleRows.remove(entry)
        self._saveRules()

    def _saveRules(self):
        rules = []
        for entry in getattr(self, 'ruleRows', []):
            itemId = _ITEM_BY_NAME.get(entry['item'].get())
            target = entry['target'].get().strip()
            if itemId is None or not target:
                continue
            if target == 'wegwerfen':
                rules.append({'itemId': itemId, 'drop': True})
            else:
                rules.append({'itemId': itemId, 'to': target})
        self.context.setLootRules(rules)

    def _validate(self):
        main, loot = self.mainPicker.get(), self.lootPicker.get()
        problems = []
        for label, value in (('Main', main), ('Loot', loot)):
            if value and value not in BACKPACKS:
                problems.append(f'"{value}" ist kein bekannter Backpack.')
        if main and loot and main == loot:
            problems.append('Main- und Loot-Backpack muessen verschieden sein.')
        self.warningLabel.configure(text=' '.join(problems))
        return not problems

    def setMainBackpack(self):
        if self.mainPicker.get() == self.lootPicker.get():
            self._validate()
            config = self.context.enabledProfile['config']['ng_backpacks']
            self.mainPicker.set(config['main'] or '')
            return
        if not self._validate():
            return
        self.context.updateMainBackpack(self.mainPicker.get())

    def setLootBackpack(self):
        if self.mainPicker.get() == self.lootPicker.get():
            self._validate()
            config = self.context.enabledProfile['config']['ng_backpacks']
            self.lootPicker.set(config['loot'] or '')
            return
        if not self._validate():
            return
        self.context.updateLootBackpack(self.lootPicker.get())
