"""Alle einsammelbaren Gegenstände im Spiel."""
import pyxel
import math
import random
from constants import (
    COL_YELLOW, COL_LBLUE, COL_BLUE, COL_WHITE, COL_GOLD,
    COL_DARK, COL_BROWN, COL_RED, COL_PINK, KEY_U, KEY_V,
    rect_overlap
)


# ═══════════════════════════════════════════════════════════════════════════════
#  BASISKLASSE
# ═══════════════════════════════════════════════════════════════════════════════
class Collectible:
    """Basisklasse für alle einsammelbaren Objekte."""

    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        # Originalposition für Respawn
        self.orig_x = x
        self.orig_y = y
        self.collected = False
        self.anim_tick = random.randint(0, 60)

    @property
    def name(self):
        return "Item"

    @property
    def points(self):
        return 0

    @property
    def is_required(self):
        return False

    def check_pickup(self, player):
        if self.collected:
            return False
        if player.collides_with(self.x, self.y, self.w, self.h):
            self.collected = True
            return True
        return False

    def apply_effect(self, game):
        """Sofort-Effekt beim Aufsammeln (z.B. Uhr, Rüstung)."""
        pass

    def respawn(self):
        """Setzt das Item an seine Originalposition zurück (nach Treffer-Verlust)."""
        self.x = self.orig_x
        self.y = self.orig_y
        self.collected = False

    def update(self):
        if not self.collected:
            self.anim_tick += 1

    def draw(self, has_res):
        if not self.collected:
            self._draw_sprite(has_res)

    def _draw_sprite(self, has_res):
        pass


# ═══════════════════════════════════════════════════════════════════════════════
#  KEY – Schlüssel (Pflicht, 100P)
# ═══════════════════════════════════════════════════════════════════════════════
class Key(Collectible):
    """Schlüssel – Pflicht zum Öffnen der Truhe. 100 Punkte."""

    def __init__(self, x, y):
        super().__init__(x, y, 8, 8)

    @property
    def name(self):
        return "Schluessel"

    @property
    def points(self):
        return 100

    @property
    def is_required(self):
        return True

    def _draw_sprite(self, has_res):
        offset_y = int(math.sin(self.anim_tick * 0.1) * 2)
        dy = self.y + offset_y
        if has_res:
            pyxel.blt(self.x, dy, 0, KEY_U, KEY_V, 8, 8, 0)
        else:
            pyxel.circ(self.x + 2, dy + 2, 2, COL_YELLOW)
            pyxel.rect(self.x + 3, dy + 3, 4, 2, COL_YELLOW)
            pyxel.pset(self.x + 5, dy + 5, COL_YELLOW)
            pyxel.pset(self.x + 7, dy + 5, COL_YELLOW)


# ═══════════════════════════════════════════════════════════════════════════════
#  GEM – Edelstein (200P Bonus)
# ═══════════════════════════════════════════════════════════════════════════════
class Gem(Collectible):
    """Edelstein – optionaler Bonus. 200 Punkte."""

    def __init__(self, x, y):
        super().__init__(x, y, 8, 8)

    @property
    def name(self):
        return "Edelstein"

    @property
    def points(self):
        return 200

    def _draw_sprite(self, has_res):
        colors = [COL_LBLUE, COL_BLUE, COL_LBLUE, COL_WHITE]
        col = colors[(self.anim_tick // 8) % len(colors)]
        x, y = self.x, self.y
        pyxel.pset(x + 3, y, col)
        pyxel.pset(x + 4, y, col)
        pyxel.line(x + 2, y + 1, x + 5, y + 1, col)
        pyxel.line(x + 1, y + 2, x + 6, y + 2, col)
        pyxel.line(x + 1, y + 3, x + 6, y + 3, col)
        pyxel.line(x + 2, y + 4, x + 5, y + 4, col)
        pyxel.line(x + 3, y + 5, x + 4, y + 5, col)
        pyxel.pset(x + 3, y + 6, col)
        pyxel.pset(x + 4, y + 6, col)
        pyxel.pset(x + 2, y + 2, COL_WHITE)


# ═══════════════════════════════════════════════════════════════════════════════
#  CLOCK – Uhr (+5 Sekunden) – SOFORT-EFFEKT
# ═══════════════════════════════════════════════════════════════════════════════
class Clock(Collectible):
    """Uhr – gibt sofort 5 Sekunden Extra-Zeit. Wird NICHT getragen."""

    BONUS_SECONDS = 5

    def __init__(self, x, y):
        super().__init__(x, y, 8, 8)

    @property
    def name(self):
        return "Uhr"

    @property
    def points(self):
        return 0

    @property
    def is_instant(self):
        """Sofort-Items werden nicht ins Inventar gelegt."""
        return True

    def apply_effect(self, game):
        bonus_frames = self.BONUS_SECONDS * 30
        game.round_time = max(0, game.round_time - bonus_frames)

    def _draw_sprite(self, has_res):
        x, y = self.x, self.y
        pyxel.circb(x + 3, y + 4, 3, COL_GOLD)
        pyxel.circ(x + 3, y + 4, 2, COL_YELLOW)
        angle = self.anim_tick * 0.15
        zx = int(x + 3 + math.cos(angle) * 2)
        zy = int(y + 4 + math.sin(angle) * 2)
        pyxel.line(x + 3, y + 4, zx, zy, COL_DARK)
        pyxel.pset(x + 3, y + 1, COL_GOLD)


# ═══════════════════════════════════════════════════════════════════════════════
#  STAR – Stern (500P Mega-Bonus)
# ═══════════════════════════════════════════════════════════════════════════════
class Star(Collectible):
    """Stern – seltener Mega-Bonus. 500 Punkte."""

    def __init__(self, x, y):
        super().__init__(x, y, 10, 10)

    @property
    def name(self):
        return "Stern"

    @property
    def points(self):
        return 500

    def _draw_sprite(self, has_res):
        x, y = self.x, self.y
        pulse = 1 if (self.anim_tick // 10) % 2 == 0 else 0
        col1 = COL_YELLOW
        cx, cy = x + 4, y + 4
        pyxel.pset(cx, cy - 4 - pulse, col1)
        pyxel.pset(cx - 4 - pulse, cy, col1)
        pyxel.pset(cx + 4 + pulse, cy, col1)
        pyxel.pset(cx - 2, cy + 3 + pulse, col1)
        pyxel.pset(cx + 2, cy + 3 + pulse, col1)
        pyxel.rect(cx - 1, cy - 1, 3, 3, COL_GOLD)
        pyxel.pset(cx, cy, COL_WHITE)
        pyxel.line(cx, cy - 3, cx, cy - 1, col1)
        pyxel.line(cx - 3, cy, cx - 1, cy, col1)
        pyxel.line(cx + 1, cy, cx + 3, cy, col1)
        pyxel.line(cx, cy + 1, cx, cy + 2, col1)


# ═══════════════════════════════════════════════════════════════════════════════
#  ARMOR – Rüstung (Sofort-Schild) – SOFORT-EFFEKT
# ═══════════════════════════════════════════════════════════════════════════════
class Armor(Collectible):
    """Rüstung – gibt sofort ein Schutzschild. Wird NICHT getragen."""

    SHIELD_FRAMES = 90

    def __init__(self, x, y):
        super().__init__(x, y, 10, 10)

    @property
    def name(self):
        return "Ruestung"

    @property
    def points(self):
        return 50

    @property
    def is_instant(self):
        return True

    def apply_effect(self, game):
        game.player.hit_cooldown = max(game.player.hit_cooldown, self.SHIELD_FRAMES)

    def _draw_sprite(self, has_res):
        x, y = self.x, self.y
        col = COL_LBLUE if (self.anim_tick // 12) % 2 == 0 else COL_BLUE
        pyxel.line(x + 2, y, x + 6, y, col)
        pyxel.line(x + 1, y + 1, x + 7, y + 1, col)
        pyxel.rect(x + 1, y + 2, 7, 3, col)
        pyxel.line(x + 2, y + 5, x + 6, y + 5, col)
        pyxel.line(x + 3, y + 6, x + 5, y + 6, col)
        pyxel.pset(x + 4, y + 7, col)
        pyxel.pset(x + 3, y + 2, COL_WHITE)


# ═══════════════════════════════════════════════════════════════════════════════
#  POTION – Heiltrank (Strafe weg) – SOFORT-EFFEKT
# ═══════════════════════════════════════════════════════════════════════════════
class Potion(Collectible):
    """Heiltrank – setzt Treffer-Strafen auf 0. Wird NICHT getragen."""

    def __init__(self, x, y):
        super().__init__(x, y, 8, 10)

    @property
    def name(self):
        return "Heiltrank"

    @property
    def points(self):
        return 0

    @property
    def is_instant(self):
        return True

    def apply_effect(self, game):
        game.player.hit_penalty = 0

    def _draw_sprite(self, has_res):
        x, y = self.x, self.y
        bubble_offset = int(math.sin(self.anim_tick * 0.2) * 1)
        pyxel.pset(x + 3, y, COL_BROWN)
        pyxel.pset(x + 4, y, COL_BROWN)
        pyxel.rect(x + 3, y + 1, 2, 2, COL_WHITE)
        pyxel.pset(x + 2, y + 2, COL_WHITE)
        pyxel.pset(x + 5, y + 2, COL_WHITE)
        pyxel.rect(x + 1, y + 3, 6, 6, COL_RED)
        pyxel.rect(x + 2, y + 3, 4, 6, COL_RED)
        pyxel.pset(x + 2, y + 4, COL_PINK)
        pyxel.pset(x + 2, y + 5, COL_PINK)
        pyxel.pset(x + 4, y + 5 + bubble_offset, COL_PINK)
        if (self.anim_tick // 15) % 3 == 0:
            pyxel.pset(x + 5, y + 3, COL_WHITE)


# ─── Item-Registry ────────────────────────────────────────────────────────────
ITEM_MAP = {
    'K': Key,
    'G': Gem,
    'T': Clock,
    'S': Star,
    'A': Armor,
    'H': Potion,
}

# Items die NICHT getragen werden (Sofort-Effekt)
INSTANT_ITEMS = (Clock, Armor, Potion)
