"""Vorrats-Waechter-Dialog: Regeln fuer automatische Refill-Spruenge.

Jede Regel prueft eine Quelle (Trank aus der Item-Datenbank, Cap oder
Stamina) gegen eine Schwelle und springt bei Treffer zum gewaehlten
Wegpunkt-Label. Gespeichert wird ueber context.setSupplies, der
Loop-Hook `gameplay.supplies.watchSupplies` wertet die Regeln aus.
"""
import customtkinter

from src.repositories.actionBar.slotIcons import SLOT_ITEMS
from src.ui import theme
from src.ui.widgets import FormModal, SearchableComboBox, positiveInt

SOURCES = (
    ('item', 'Trank'),
    ('capacity', 'Cap'),
    ('stamina', 'Stamina'),
)
OPERATORS = ('<', '<=', '>', '>=', '==')
_SOURCE_LABELS = dict(SOURCES)
_SOURCE_BY_LABEL = {label: key for key, label in SOURCES}
_ITEM_BY_NAME = {name: itemId for itemId, name in SLOT_ITEMS.items()}
_ITEM_NAMES = list(_ITEM_BY_NAME)


class SuppliesModal(FormModal):
    def __init__(self, parent, context, waypointsLabels):
        super().__init__(parent, 'Vorrats-Wächter', confirm_label='Speichern')
        self.context = context
        self.waypointsLabels = list(waypointsLabels)
        self.rows = []
        supplies = self.context.getSupplies()

        self.enabledSwitch = customtkinter.CTkSwitch(
            self.body, text='Vorrats-Wächter aktiviert',
            progress_color=theme.ACCENT, font=theme.font(12, 'bold'),
        )
        self.enabledSwitch.grid(
            row=0, column=0, columnspan=2, sticky='w', pady=(4, 8))
        if supplies.get('enabled'):
            self.enabledSwitch.select()

        self.rowsFrame = customtkinter.CTkFrame(
            self.body, fg_color='transparent')
        self.rowsFrame.grid(row=1, column=0, columnspan=2, sticky='ew')

        customtkinter.CTkButton(
            self.body, 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._addRow(),
        ).grid(row=2, column=0, sticky='w', pady=(6, 2))

        for rule in supplies.get('rules', []):
            self._addRow(rule)
        if not supplies.get('rules'):
            self._addRow()

    def _addRow(self, rule=None):
        rule = rule or {
            'source': 'item', 'itemId': 266, 'operator': '<', 'target': 25,
            'label': self.waypointsLabels[0] if self.waypointsLabels else '',
            'enabled': True,
        }
        index = len(self.rows)
        frame = customtkinter.CTkFrame(
            self.rowsFrame, fg_color=theme.ELEVATED, corner_radius=8)
        frame.grid(row=index, column=0, sticky='ew', pady=3)
        frame.grid_columnconfigure(1, weight=1)

        sourceCombo = SearchableComboBox(
            frame, values=[label for _k, label in SOURCES],
            placeholder='Quelle …')
        sourceCombo.grid(row=0, column=0, padx=(6, 2), pady=6)
        sourceCombo.set(_SOURCE_LABELS[rule['source']])

        itemCombo = SearchableComboBox(
            frame, values=_ITEM_NAMES, placeholder='Trank …')
        itemCombo.grid(row=0, column=1, padx=2, pady=6, sticky='ew')
        if rule.get('itemId') in SLOT_ITEMS:
            itemCombo.set(SLOT_ITEMS[rule['itemId']])

        operatorCombo = SearchableComboBox(frame, values=list(OPERATORS))
        operatorCombo.grid(row=0, column=2, padx=2, pady=6)
        operatorCombo.set(rule.get('operator', '<'))

        targetEntry = customtkinter.CTkEntry(
            frame, width=60, validate='key',
            validatecommand=(self.register(positiveInt), '%P'))
        targetEntry.grid(row=0, column=3, padx=2, pady=6)
        targetEntry.insert(0, str(rule.get('target', 25)))

        labelCombo = SearchableComboBox(
            frame, values=self.waypointsLabels, placeholder='Label …')
        labelCombo.grid(row=0, column=4, padx=2, pady=6, sticky='ew')
        if rule.get('label'):
            labelCombo.set(rule['label'])

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

        entry = {
            'frame': frame, 'source': sourceCombo, 'item': itemCombo,
            'operator': operatorCombo, 'target': targetEntry,
            'label': labelCombo,
        }
        self.rows.append(entry)

    def _deleteRow(self, frame, entry):
        frame.destroy()
        if entry in self.rows:
            self.rows.remove(entry)

    def confirm(self):
        rules = []
        for entry in self.rows:
            source = _SOURCE_BY_LABEL.get(entry['source'].get(), 'item')
            targetText = entry['target'].get()
            if not targetText.isdigit():
                return self.fail('Jede Regel braucht einen Zahlenwert.')
            label = entry['label'].get().strip()
            if not label:
                return self.fail('Jede Regel braucht ein Ziel-Label.')
            rule = {
                'source': source,
                'operator': entry['operator'].get() or '<',
                'target': int(targetText),
                'label': label,
                'enabled': True,
            }
            if source == 'item':
                itemId = _ITEM_BY_NAME.get(entry['item'].get())
                if itemId is None:
                    return self.fail('Bitte einen Trank aus der Liste wählen.')
                rule['itemId'] = itemId
            rules.append(rule)
        self.context.setSupplies({
            'enabled': self.enabledSwitch.get() == 1,
            'rules': rules,
        })
        self.destroy()
