import pyxel
import random
import math

STATE_MENU = 0
STATE_PLAYING = 1
STATE_WIN = 2
STATE_LOSE = 3
STATE_BETWEEN = 4
STATE_FINAL = 5
STATE_EATEN = 6
SCREEN_SIZE = 70
MAP_SIZE = 256
PLAYER_SIZE = 16

class Game:
    def __init__(self):
        pyxel.init(SCREEN_SIZE, SCREEN_SIZE, title="Hare Hurry")
        pyxel.load("assets.pyxres")

        # Karotte einsammeln
        pyxel.sound(1).set("c3e3g3", "p", "7", "s", 5)

        # Karotte ablegen
        pyxel.sound(2).set("g3c4e4c4", "p", "7", "s", 6)

        # Game Over
        pyxel.sound(3).set("g3 r e3 r c3", "t", "7", "n", 40)

        self.reset()
        pyxel.run(self.update, self.draw)

    def reset(self):
        self.level = 1
        self.setup_level()
        self.state = STATE_MENU
        self.gameover_played = False
        self.snowflakes = [
            (random.randint(0, SCREEN_SIZE),
             random.randint(0, SCREEN_SIZE))
            for _ in range(40)
        ]
        self.anim_counter = 0
        self.animation_frame = 0

    def setup_level(self):
        if self.level == 1:
            self.target_score = 3
            self.time_limit = 30
        elif self.level == 2:
            self.target_score = 3
            self.time_limit = 18
        elif self.level == 3:
            self.target_score = 5
            self.time_limit = 20

        self.player_x = MAP_SIZE // 2
        self.player_y = MAP_SIZE // 2
        self.direction = "right"

        self.base_x = 200
        self.base_y = 200

        self.spawn_objects()

        self.carrying = False
        self.score = 0
        self.start_frame = pyxel.frame_count

        # 🦊 FOX 
        self.fox_x = random.randint(0, MAP_SIZE - 16)
        self.fox_y = random.randint(0, MAP_SIZE - 16)
        self.fox_speed = 1.0
        self.fox_anim = 0
        self.fox_timer = 0

    def spawn_objects(self):
        self.objects = [
            (
                random.randint(0, MAP_SIZE - 16),
                random.randint(0, MAP_SIZE - 16)
            )
            for _ in range(self.target_score + 2)
        ]

    def update_snow(self):
        new = []
        for x, y in self.snowflakes:
            y += 1
            if y > SCREEN_SIZE:
                y = 0
                x = random.randint(0, SCREEN_SIZE)
            new.append((x, y))
        self.snowflakes = new

    def draw_snow(self):
        for x, y in self.snowflakes:
            pyxel.pset(x, y, 7)

    def update(self):
        
        # Musik
        if self.state == STATE_PLAYING:
            if not pyxel.play_pos(0):
                pyxel.play(0, 0, loop=True)

        # Menü
        if self.state == STATE_MENU:
            if pyxel.btnp(pyxel.KEY_RETURN):
                self.state = STATE_PLAYING
                self.start_frame = pyxel.frame_count
            return

        # Zwischenlevel
        if self.state == STATE_BETWEEN:
            self.update_snow()
            if pyxel.btnp(pyxel.KEY_RETURN):
                self.level += 1
                self.setup_level()
                self.state = STATE_PLAYING
            return

        # Final
        if self.state == STATE_FINAL:
            self.update_snow()
            if pyxel.btnp(pyxel.KEY_R):
                self.reset()
            return

        # Game Over
        if self.state == STATE_LOSE:
            self.update_snow()
            if pyxel.btnp(pyxel.KEY_R):
                self.reset()
            return
        
        if self.state == STATE_EATEN:
            self.update_snow()
            if pyxel.btnp(pyxel.KEY_R):
                self.reset()
            return

        speed = 2
        moving = False

        if pyxel.btn(pyxel.KEY_LEFT):
            self.player_x -= speed
            self.direction = "left"
            moving = True

        if pyxel.btn(pyxel.KEY_RIGHT):
            self.player_x += speed
            self.direction = "right"
            moving = True

        if pyxel.btn(pyxel.KEY_UP):
            self.player_y -= speed
            moving = True

        if pyxel.btn(pyxel.KEY_DOWN):
            self.player_y += speed
            moving = True

        if moving:
            self.anim_counter += 1
            if self.anim_counter > 8:
                self.animation_frame = (self.animation_frame + 1) % 2
                self.anim_counter = 0

        self.player_x = max(0, min(MAP_SIZE - PLAYER_SIZE, self.player_x))
        self.player_y = max(0, min(MAP_SIZE - PLAYER_SIZE, self.player_y))

        # 🦊 FOX AI (ADDED - NICHTS GELÖSCHT)
        dx = self.player_x - self.fox_x
        dy = self.player_y - self.fox_y
        dist = math.sqrt(dx * dx + dy * dy)

        if dist > 0:
            self.fox_x += (dx / dist) * self.fox_speed
            self.fox_y += (dy / dist) * self.fox_speed

        self.fox_timer += 1
        if self.fox_timer > 10:
            self.fox_anim = (self.fox_anim + 1) % 2
            self.fox_timer = 0

        # 💀 COLLISION
        if abs(self.player_x - self.fox_x) < 12 and abs(self.player_y - self.fox_y) < 12:
            if not self.gameover_played:
                pyxel.play(3, 3)
                self.gameover_played = True
            self.state = STATE_EATEN

        # Karotte einsammeln
        if not self.carrying:
            for obj in self.objects:
                if (
                    abs(self.player_x - obj[0]) < 12
                    and abs(self.player_y - obj[1]) < 12
                ):
                    self.objects.remove(obj)
                    self.carrying = True
                    pyxel.play(1, 1)
                    break

        # Karotte ablegen
        if self.carrying:
            if (
                abs(self.player_x - self.base_x) < 16
                and abs(self.player_y - self.base_y) < 16
            ):
                self.score += 1
                self.carrying = False
                pyxel.play(2, 2)

                if self.score >= self.target_score:
                    if self.level < 3:
                        self.state = STATE_BETWEEN
                    else:
                        self.state = STATE_FINAL

        elapsed = (pyxel.frame_count - self.start_frame) // 30

        if elapsed >= self.time_limit:
            if not self.gameover_played:
                pyxel.play(3, 3)
                self.gameover_played = True
            self.state = STATE_LOSE

    def draw_arrow(self, cam_x, cam_y):
        px = SCREEN_SIZE // 2
        py = SCREEN_SIZE // 2

        dx = (self.base_x - cam_x) - px
        dy = (self.base_y - cam_y) - py

        angle = math.atan2(dy, dx)

        r = SCREEN_SIZE // 2 - 10

        x = int(px + math.cos(angle) * r)
        y = int(py + math.sin(angle) * r)

        tip_x = int(x + math.cos(angle) * 6)
        tip_y = int(y + math.sin(angle) * 6)

        left_x = int(tip_x + math.cos(angle + 2.4) * 5)
        left_y = int(tip_y + math.sin(angle + 2.4) * 5)

        right_x = int(tip_x + math.cos(angle - 2.4) * 5)
        right_y = int(tip_y + math.sin(angle - 2.4) * 5)

        pyxel.line(x, y, tip_x, tip_y, 0)
        pyxel.tri(tip_x, tip_y, left_x, left_y, right_x, right_y, 0)

    def draw(self):
        pyxel.cls(0)

        if self.state == STATE_MENU:
            pyxel.text(5, 20, "HARE HURRY", 7)
            pyxel.text(5, 30, "PRESS ENTER", 7)
            pyxel.text(5, 40, "TO PLAY", 7)
            return

        if self.state == STATE_BETWEEN:
            pyxel.cls(1)
            self.draw_snow()
            pyxel.text(2, 20, "YOU SURVIVED", 7)
            pyxel.text(2, 30, "WINTER", 7)
            pyxel.text(2, 40, "PRESS ENTER", 7)
            pyxel.text(2, 50, "TO CONTINUE", 7)
            return

        if self.state == STATE_FINAL:
            pyxel.cls(1)
            self.draw_snow()
            pyxel.text(2, 20, "YOU SURVIVED", 7)
            pyxel.text(2, 30, "YOUR FINAL WINTER", 7)
            pyxel.text(2, 40, "PRESS R", 7)
            pyxel.text(2, 60, "TO REPLAY", 7)
            return

        if self.state == STATE_EATEN:
            pyxel.cls(1)
            self.draw_snow()
            pyxel.text(2, 20, "YOU WERE EATEN", 7)
            pyxel.text(2, 30, "PRESS R", 7)
            pyxel.text(2, 40, "TO RETRY", 7)
            return
        
        if self.state == STATE_LOSE:
            pyxel.cls(1)
            self.draw_snow()
            pyxel.text(2, 20, "YOU STARVED", 7)
            pyxel.text(2, 30, "PRESS R", 7)
            pyxel.text(2, 40, "TO RETRY", 7)
            return

        cam_x = self.player_x - SCREEN_SIZE // 2
        cam_y = self.player_y - SCREEN_SIZE // 2

        cam_x = max(0, min(MAP_SIZE - SCREEN_SIZE, cam_x))
        cam_y = max(0, min(MAP_SIZE - SCREEN_SIZE, cam_y))

        pyxel.blt(0 - cam_x, 0 - cam_y, 2, 0, 0, MAP_SIZE, MAP_SIZE, 8)

        pyxel.blt(self.base_x - cam_x, self.base_y - cam_y, 0, 0, 32, 32, 16, 8)

        for x, y in self.objects:
            pyxel.blt(x - cam_x, y - cam_y, 1, 0, 16, 16, 16, 8)

        # 🦊 FOX DRAW (ADDED)
        fox_x = self.fox_x - cam_x
        fox_y = self.fox_y - cam_y

        if self.player_x < self.fox_x:
            x_off = 0 if self.fox_anim == 0 else 16
            y_off = 48
        else:
            x_off = 0 if self.fox_anim == 0 else 16
            y_off = 32

        pyxel.blt(fox_x, fox_y, 1, x_off, y_off, 16, 16, 8)

        px = SCREEN_SIZE // 2
        py = SCREEN_SIZE // 2

        if not self.carrying:
            if self.direction == "right":
                x_off = 16 + self.animation_frame * 16
                y_off = 16
            else:
                x_off = 0
                y_off = 16 if self.animation_frame == 0 else 48
        else:
            if self.direction == "right":
                x_off = 16 if self.animation_frame == 0 else 32
                y_off = 0
            else:
                x_off = 0 if self.animation_frame == 0 else 16
                y_off = 64

        pyxel.blt(px, py, 0, x_off, y_off, 16, 16, 8)

        self.draw_arrow(cam_x, cam_y)

        elapsed = (pyxel.frame_count - self.start_frame) // 30
        remaining = max(0, self.time_limit - elapsed)

        pyxel.text(0, 60, f"{self.score}/{self.target_score}", 7)
        pyxel.text(40, 60, f"{remaining}", 7)

Game()