# joueur.py
"""Classe Joueur (le bûcheron) pour le jeu Bucheron - Projet NSI Première"""

import pygame
import math
from constantes import *


class Joueur:
    """Représente le bûcheron contrôlé par le joueur.

    Déplacement : Z/Q/S/D ou touches fléchées
    Action      : ESPACE ou E pour couper l'arbre le plus proche
    """

    def __init__(self, x: int, y: int):
        self.x = float(x)
        self.y = float(y)
        self.direction   = "bas"
        self._delai      = 0    # frames avant de pouvoir refrapper
        self._anim_coupe = 0    # frames de l'animation de coup

        # Hache améliorée
        self.timer_hache_amelioree = 0  # frames restantes du bonus

    # ── Accesseurs ─────────────────────────────────────────────────────
    @property
    def en_train_de_couper(self) -> bool:
        return self._anim_coupe > 0

    @property
    def hache_active(self) -> bool:
        """True si la hache améliorée est en cours d'utilisation."""
        return self.timer_hache_amelioree > 0

    @property
    def _delai_coupe_actuel(self) -> int:
        """Délai de coupe selon l'état de la hache."""
        return DELAI_COUPE_AMELIORE if self.hache_active else DELAI_COUPE

    # ── Hache améliorée ────────────────────────────────────────────────
    def activer_hache_amelioree(self) -> None:
        """Active (ou prolonge) le bonus de hache améliorée."""
        self.timer_hache_amelioree = DUREE_HACHE_AMELIOREE

    # ── Logique ────────────────────────────────────────────────────────
    def gerer_entrees(self, touches: pygame.key.ScancodeWrapper,
                      rochers: list = None) -> None:
        """Déplace le joueur en gérant les collisions avec les rochers."""
        dx, dy = 0.0, 0.0

        if touches[pygame.K_LEFT]  or touches[pygame.K_q]:
            dx = -VITESSE_JOUEUR;  self.direction = "gauche"
        if touches[pygame.K_RIGHT] or touches[pygame.K_d]:
            dx =  VITESSE_JOUEUR;  self.direction = "droite"
        if touches[pygame.K_UP]    or touches[pygame.K_z]:
            dy = -VITESSE_JOUEUR;  self.direction = "haut"
        if touches[pygame.K_DOWN]  or touches[pygame.K_s]:
            dy =  VITESSE_JOUEUR;  self.direction = "bas"

        # Normalisation diagonale
        if dx != 0 and dy != 0:
            dx *= 0.7071
            dy *= 0.7071

        # ── Déplacement avec glissement sur les rochers ──
        # On tente d'abord le déplacement complet, puis on essaie
        # de glisser le long du rocher (x seul, puis y seul)
        new_x = max(TAILLE_JOUEUR,
                    min(LARGEUR  - TAILLE_JOUEUR, self.x + dx))
        new_y = max(TAILLE_JOUEUR + HAUTEUR_HUD,
                    min(HAUTEUR  - TAILLE_JOUEUR, self.y + dy))

        if rochers:
            for rocher in rochers:
                seuil = TAILLE_JOUEUR + rocher.rayon - 4
                if math.dist((new_x, new_y), (rocher.x, rocher.y)) < seuil:
                    # Déplacement complet bloqué → essayer x seul
                    test_x = max(TAILLE_JOUEUR,
                                 min(LARGEUR  - TAILLE_JOUEUR, self.x + dx))
                    test_y = self.y
                    if math.dist((test_x, test_y),
                                  (rocher.x, rocher.y)) >= seuil:
                        new_x, new_y = test_x, test_y
                    else:
                        # Essayer y seul
                        test_x2 = self.x
                        test_y2 = max(TAILLE_JOUEUR + HAUTEUR_HUD,
                                      min(HAUTEUR  - TAILLE_JOUEUR, self.y + dy))
                        if math.dist((test_x2, test_y2),
                                      (rocher.x, rocher.y)) >= seuil:
                            new_x, new_y = test_x2, test_y2
                        else:
                            # Complètement bloqué
                            new_x, new_y = self.x, self.y

        self.x = new_x
        self.y = new_y

        # Timers
        if self._delai              > 0: self._delai              -= 1
        if self._anim_coupe         > 0: self._anim_coupe         -= 1
        if self.timer_hache_amelioree > 0: self.timer_hache_amelioree -= 1

    def essayer_couper(self, arbres: list) -> object:
        """Tente de couper l'arbre vivant le plus proche dans la portée."""
        if self._delai > 0:
            return None

        arbre_cible = None
        dist_min    = PORTEE_COUPE

        for arbre in arbres:
            if arbre.est_vivant():
                dist = math.dist((self.x, self.y), (arbre.x, arbre.y))
                if dist < dist_min:
                    dist_min    = dist
                    arbre_cible = arbre

        if arbre_cible is not None:
            self._delai      = self._delai_coupe_actuel
            self._anim_coupe = 14
        return arbre_cible

    # ── Dessin ─────────────────────────────────────────────────────────
    def dessiner(self, surface: pygame.Surface) -> None:
        cx = int(self.x)
        cy = int(self.y)

        if self.en_train_de_couper:
            if   self.direction == "droite": off =  4
            elif self.direction == "gauche": off = -4
            else:                            off =  0
        else:
            off = 0

        # Aura dorée si hache améliorée active
        if self.hache_active:
            aura = pygame.Surface((60, 60), pygame.SRCALPHA)
            pygame.draw.circle(aura, (255, 215, 0, 55), (30, 30), 28)
            surface.blit(aura, (cx - 30, cy - 30))

        # Corps
        pygame.draw.rect(surface, JEAN,    (cx - 8, cy + 2,  7, 10))
        pygame.draw.rect(surface, JEAN,    (cx + 1, cy + 2,  7, 10))
        pygame.draw.rect(surface, CHEMISE, (cx - 9, cy - 8, 18, 12))
        pygame.draw.circle(surface, PEAU,  (cx,     cy - 14),    8)

        # Chapeau de bûcheron
        pygame.draw.rect(surface, MARRON_FONCE, (cx - 10, cy - 21, 20, 4))
        pygame.draw.rect(surface, MARRON_FONCE, (cx -  6, cy - 27, 12, 7))

        self._dessiner_hache(surface, cx, cy, off)

    def _dessiner_hache(self, surface, cx, cy, off):
        """Hache normale (grise) ou améliorée (dorée)."""
        couleur_lame = JAUNE if self.hache_active else GRIS

        if self.direction in ("droite", "bas", "haut"):
            px1, py1 = cx +  8 + off, cy - 4
            px2, py2 = cx + 16 + off, cy - 17
            pygame.draw.line(surface, MARRON, (px1, py1), (px2, py2), 3)
            pygame.draw.polygon(surface, couleur_lame, [
                (px2,     py2),
                (px2 + 7, py2 + 6),
                (px2 + 3, py2 - 7),
            ])
        else:
            px1, py1 = cx -  8 + off, cy - 4
            px2, py2 = cx - 16 + off, cy - 17
            pygame.draw.line(surface, MARRON, (px1, py1), (px2, py2), 3)
            pygame.draw.polygon(surface, couleur_lame, [
                (px2,      py2),
                (px2 - 7,  py2 + 6),
                (px2 - 3,  py2 - 7),
            ])
