#pragma once

#include <SDL3/SDL.h>  // Para SDL_FRect, SDL_FlipMode

#include <cstddef>   // Para size_t
#include <iterator>  // Para pair
#include <memory>    // Para shared_ptr, unique_ptr
#include <string>    // Para basic_string, string
#include <utility>   // Para move, pair
#include <vector>    // Para vector

#include "core/input/input.hpp"                       // for Input
#include "core/rendering/sprite/animated_sprite.hpp"  // for AnimatedSprite
#include "game/entities/bullet.hpp"                   // for Bullet
#include "game/gameplay/cooldown.hpp"
#include "game/gameplay/enter_name.hpp"            // for EnterName
#include "game/gameplay/manage_hiscore_table.hpp"  // for Table
#include "game/gameplay/scoreboard.hpp"            // for Scoreboard
#include "utils/utils.hpp"                         // for Circle

class IStageInfo;
class Texture;

// --- Clase Player: jugador principal del juego ---
//
// Esta clase gestiona todos los aspectos de un jugador durante el juego,
// incluyendo movimiento, disparos, animaciones y estados especiales.
//
// Funcionalidades principales:
// • Sistema de disparo de dos líneas: funcional (cooldown) + visual (animaciones)
// • Estados de animación: normal → aiming → recoiling → threat_pose → normal
// • Movimiento time-based: compatibilidad con deltaTime para fluidez variable
// • Power-ups e invulnerabilidad: coffee machine, extra hits, parpadeos
// • Sistema de puntuación: multipliers, high scores, entrada de nombres
// • Estados de juego: playing, rolling, continue, entering_name, etc.
//
// El sistema de disparo utiliza duraciones configurables mediante constantes
// para facilitar el ajuste del gameplay y la sensación de disparo.
class Player {
   public:
    // --- Constantes ---
    static constexpr int WIDTH = 32;   // Anchura
    static constexpr int HEIGHT = 32;  // Altura

    // --- Estructuras ---
    struct BulletColorPair {
        Bullet::Color normal_color;   // Color de bala sin power-up
        Bullet::Color powered_color;  // Color de bala con power-up
    };

    // --- Enums ---
    enum class Id : int {
        NO_PLAYER = -1,    // Sin jugador
        BOTH_PLAYERS = 0,  // Ambos jugadores
        PLAYER1 = 1,       // Jugador 1
        PLAYER2 = 2        // Jugador 2
    };

    enum class State {
        // Estados de movimiento
        WALKING_LEFT,   // Caminando hacia la izquierda
        WALKING_RIGHT,  // Caminando hacia la derecha
        WALKING_STOP,   // Parado, sin moverse

        // Estados de disparo
        FIRING_UP,     // Disparando hacia arriba
        FIRING_LEFT,   // Disparando hacia la izquierda
        FIRING_RIGHT,  // Disparando hacia la derecha
        FIRING_NONE,   // No está disparando

        // Estados de retroceso tras disparar
        RECOILING_UP,     // Retroceso tras disparar hacia arriba
        RECOILING_LEFT,   // Retroceso tras disparar hacia la izquierda
        RECOILING_RIGHT,  // Retroceso tras disparar hacia la derecha

        // Estados de enfriamiento tras disparar
        COOLING_UP,     // Enfriando tras disparar hacia arriba
        COOLING_LEFT,   // Enfriando tras disparar hacia la izquierda
        COOLING_RIGHT,  // Enfriando tras disparar hacia la derecha

        // Estados generales del jugador
        PLAYING,                       // Está jugando activamente
        CONTINUE,                      // Cuenta atrás para continuar tras perder
        CONTINUE_TIME_OUT,             // Se ha terminado la cuenta atras para continuar y se retira al jugador de la zona de juego
        WAITING,                       // Esperando para entrar a jugar
        ENTERING_NAME,                 // Introduciendo nombre para la tabla de puntuaciones
        SHOWING_NAME,                  // Mostrando el nombre introducido
        ROLLING,                       // El jugador está dando vueltas y rebotando
        LYING_ON_THE_FLOOR_FOREVER,    // El jugador está inconsciente para siempre en el suelo (demo)
        GAME_OVER,                     // Fin de la partida, no puede jugar
        CELEBRATING,                   // Celebrando victoria (pose de victoria)
        ENTERING_NAME_GAME_COMPLETED,  // Introduciendo nombre tras completar el juego
        LEAVING_SCREEN,                // Saliendo de la pantalla (animación)
        ENTERING_SCREEN,               // Entrando a la pantalla (animación)
        CREDITS,                       // Estado para mostrar los créditos del juego
        TITLE_ANIMATION,               // Animacion para el titulo
        TITLE_HIDDEN,                  // Animacion para el titulo
        RECOVER,                       // Al aceptar continuar
        RESPAWNING,                    // Tras continuar y dar las gracias, otorga inmunidad y vuelve al juego
    };

    // --- Estructuras ---
    struct Config {
        Id id;                                             // Identificador del jugador
        float x;                                           // Posición X inicial
        int y;                                             // Posición Y inicial
        bool demo;                                         // Modo demo
        SDL_FRect* play_area;                              // Área de juego (puntero para mantener referencia)
        std::vector<std::shared_ptr<Texture>> texture;     // Texturas del jugador
        std::vector<std::vector<std::string>> animations;  // Animaciones del jugador
        Table* hi_score_table;                             // Tabla de puntuaciones (puntero para referencia)
        int* glowing_entry;                                // Entrada brillante (puntero para mantener referencia)
        IStageInfo* stage_info;                            // Gestor de pantallas (puntero)
    };

    // --- Constructor y destructor ---
    Player(const Config& config);
    ~Player() = default;

    // --- Inicialización y ciclo de vida ---
    void init();                    // Inicializa el jugador
    void update(float delta_time);  // Actualiza estado, animación y contadores (time-based)
    void render();                  // Dibuja el jugador en pantalla

    // --- Entrada y control ---
    void setInput(Input::Action action);              // Procesa entrada general
    void setInputPlaying(Input::Action action);       // Procesa entrada en modo jugando
    void setInputEnteringName(Input::Action action);  // Procesa entrada al introducir nombre

    // --- Movimiento y animación ---
    void move(float delta_time);          // Mueve el jugador (time-based)
    void setAnimation(float delta_time);  // Establece la animación según el estado (time-based)

    // --- Texturas y animaciones ---
    void setPlayerTextures(const std::vector<std::shared_ptr<Texture>>& texture);  // NOLINT(readability-avoid-const-params-in-decls) Cambia las texturas del jugador

    // --- Gameplay: Puntuación y power-ups ---
    void addScore(int score, int lowest_hi_score_entry);  // Añade puntos
    void incScoreMultiplier();                            // Incrementa el multiplicador
    void decScoreMultiplier();                            // Decrementa el multiplicador

    // --- Estados de juego ---
    void setPlayingState(State state);                                            // Cambia el estado de juego
    void setInvulnerable(bool value);                                             // Establece el valor del estado de invulnerabilidad
    void setPowerUp();                                                            // Activa el modo PowerUp
    void updatePowerUp(float delta_time);                                         // Actualiza el valor de PowerUp
    void giveExtraHit();                                                          // Concede un toque extra al jugador
    void removeExtraHit();                                                        // Quita el toque extra al jugador
    void decContinueCounter();                                                    // Decrementa el contador de continuar
    void setWalkingState(State state) { walking_state_ = state; }                 // Establece el estado de caminar
    void startFiringSystem(int cooldown_frames);                                  // Inicia el sistema de disparo
    void setScoreBoardPanel(Scoreboard::Id panel) { scoreboard_panel_ = panel; }  // Establece el panel del marcador
    void addCredit();
    void passShowingName();

    // --- Estado del juego: Consultas (is* methods) ---
    [[nodiscard]] auto isLyingOnTheFloorForever() const -> bool { return playing_state_ == State::LYING_ON_THE_FLOOR_FOREVER; }
    [[nodiscard]] auto isCelebrating() const -> bool { return playing_state_ == State::CELEBRATING; }
    [[nodiscard]] auto isContinue() const -> bool { return playing_state_ == State::CONTINUE; }
    [[nodiscard]] auto isDying() const -> bool { return playing_state_ == State::ROLLING; }
    [[nodiscard]] auto isEnteringName() const -> bool { return playing_state_ == State::ENTERING_NAME; }
    [[nodiscard]] auto isShowingName() const -> bool { return playing_state_ == State::SHOWING_NAME; }
    [[nodiscard]] auto isEnteringNameGameCompleted() const -> bool { return playing_state_ == State::ENTERING_NAME_GAME_COMPLETED; }
    [[nodiscard]] auto isLeavingScreen() const -> bool { return playing_state_ == State::LEAVING_SCREEN; }
    [[nodiscard]] auto isGameOver() const -> bool { return playing_state_ == State::GAME_OVER; }
    [[nodiscard]] auto isPlaying() const -> bool { return playing_state_ == State::PLAYING; }
    [[nodiscard]] auto isWaiting() const -> bool { return playing_state_ == State::WAITING; }
    [[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == State::TITLE_HIDDEN; }

    // --- Estados específicos: Consultas adicionales ---
    [[nodiscard]] auto canFire() const -> bool { return can_fire_new_system_; }  // Usa nuevo sistema
    [[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
    [[nodiscard]] auto isCooling() const -> bool { return firing_state_ == State::COOLING_LEFT || firing_state_ == State::COOLING_UP || firing_state_ == State::COOLING_RIGHT; }
    [[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == State::RECOILING_LEFT || firing_state_ == State::RECOILING_UP || firing_state_ == State::RECOILING_RIGHT; }
    [[nodiscard]] auto qualifiesForHighScore() const -> bool { return qualifies_for_high_score_; }
    [[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
    [[nodiscard]] auto isPowerUp() const -> bool { return power_up_; }
    [[nodiscard]] auto isInBulletColorToggleMode() const -> bool { return in_power_up_ending_phase_; }

    // --- Getters: Propiedades y valores ---
    // Posición y dimensiones
    [[nodiscard]] auto getPosX() const -> int { return static_cast<int>(pos_x_); }
    [[nodiscard]] auto getPosY() const -> int { return pos_y_; }
    [[nodiscard]] static auto getWidth() -> int { return WIDTH; }
    [[nodiscard]] static auto getHeight() -> int { return HEIGHT; }
    // Jugador y identificación
    [[nodiscard]] auto getId() const -> Player::Id { return id_; }
    [[nodiscard]] auto getName() const -> const std::string& { return name_; }
    [[nodiscard]] auto getPlayingState() const -> State { return playing_state_; }
    auto getCollider() -> Circle& { return collider_; }
    [[nodiscard]] auto getZOrder() const -> size_t { return z_order_; }
    void setZOrder(size_t z_order) { z_order_ = z_order; }

    // Puntuación y juego
    [[nodiscard]] auto getScore() const -> int { return score_; }
    [[nodiscard]] auto getScoreMultiplier() const -> float { return score_multiplier_; }
    [[nodiscard]] auto get1CC() const -> bool { return game_completed_ && credits_used_ <= 1; }
    [[nodiscard]] auto getScoreBoardPanel() const -> Scoreboard::Id { return scoreboard_panel_; }

    // Power-ups y estado especial
    [[nodiscard]] auto getCoffees() const -> int { return coffees_; }
    [[nodiscard]] auto getPowerUpCounter() const -> int { return power_up_counter_; }
    [[nodiscard]] auto getInvulnerableCounter() const -> int { return invulnerable_counter_; }
    [[nodiscard]] auto getBulletColor() const -> Bullet::Color;                                  // Devuelve el color actual de bala según el estado
    auto getNextBulletColor() -> Bullet::Color;                                                  // Devuelve el color para la próxima bala (alterna si está en modo toggle)
    void setBulletColors(Bullet::Color normal, Bullet::Color powered);                           // Establece los colores de bala para este jugador
    [[nodiscard]] auto getBulletSoundFile() const -> std::string { return bullet_sound_file_; }  // Devuelve el archivo de sonido de bala
    void setBulletSoundFile(const std::string& filename);                                        // Establece el archivo de sonido de bala para este jugador

    // Contadores y timers
    [[nodiscard]] auto getContinueCounter() const -> int { return continue_counter_; }
    [[nodiscard]] auto getRecordName() const -> std::string { return enter_name_ ? enter_name_->getFinalName() : "xxx"; }
    [[nodiscard]] auto getLastEnterName() const -> std::string { return last_enter_name_; }

    // --- Configuración e interfaz externa ---
    void setName(const std::string& name) { name_ = name; }
    void setGamepad(std::shared_ptr<Input::Gamepad> gamepad) { gamepad_ = std::move(gamepad); }
    [[nodiscard]] auto getGamepad() const -> std::shared_ptr<Input::Gamepad> { return gamepad_; }
    void setUsesKeyboard(bool value) { uses_keyboard_ = value; }
    [[nodiscard]] auto getUsesKeyboard() const -> bool { return uses_keyboard_; }
    [[nodiscard]] auto getController() const -> int { return controller_index_; }

    // Demo file management
    [[nodiscard]] auto getDemoFile() const -> size_t { return demo_file_; }
    void setDemoFile(size_t demo_file) { demo_file_ = demo_file; }

   private:
    // --- Constantes de física y movimiento ---
    static constexpr float BASE_SPEED = 90.0F;  // Velocidad base del jugador (pixels/segundo)

    // --- Constantes de power-ups y estados especiales ---
    static constexpr int POWERUP_COUNTER = 1500;       // Duración del estado PowerUp (frames)
    static constexpr int INVULNERABLE_COUNTER = 200;   // Duración del estado invulnerable (frames)
    static constexpr size_t INVULNERABLE_TEXTURE = 3;  // Textura usada durante invulnerabilidad

    // --- Constantes del sistema de disparo (obsoletas - usar nuevo sistema) ---
    static constexpr int COOLING_DURATION = 50;  // Duración del enfriamiento tras disparar
    static constexpr int COOLING_COMPLETE = 0;   // Valor que indica enfriamiento completado

    // --- Constantes de estados de espera ---
    static constexpr int WAITING_COUNTER = 1000;  // Tiempo de espera en estado de espera

    // --- Constantes del nuevo sistema de disparo de dos líneas ---
    static constexpr float AIMING_DURATION_FACTOR = 0.5F;            // 50% del cooldown funcional
    static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0F;     // 4 veces la duración de aiming
    static constexpr float THREAT_POSE_DURATION = 50.0F / 60.0F;     // 50 frames = ~0.833s (duración base)
    static constexpr float MIN_THREAT_POSE_DURATION = 6.0F / 60.0F;  // 6 frames = ~0.1s (duración mínima)

    // --- Objetos y punteros ---
    std::unique_ptr<AnimatedSprite> player_sprite_;      // Sprite para dibujar el jugador
    std::unique_ptr<AnimatedSprite> power_sprite_;       // Sprite para dibujar el aura del jugador con el poder a tope
    std::unique_ptr<EnterName> enter_name_;              // Clase utilizada para introducir el nombre
    std::unique_ptr<Cooldown> cooldown_ = nullptr;       // Objeto para gestionar cooldowns de teclado
    std::shared_ptr<Input::Gamepad> gamepad_ = nullptr;  // Dispositivo asociado
    Table* hi_score_table_ = nullptr;                    // Tabla de máximas puntuaciones
    int* glowing_entry_ = nullptr;                       // Entrada de la tabla de puntuaciones para hacerla brillar
    IStageInfo* stage_info_;                             // Informacion de la pantalla actual

    // --- Variables de estado ---
    SDL_FRect play_area_;                                                                                             // Rectángulo con la zona de juego
    Circle collider_ = Circle(0, 0, 9);                                                                               // Círculo de colisión del jugador
    std::string name_;                                                                                                // Nombre del jugador
    std::string last_enter_name_;                                                                                     // Último nombre introducido en la tabla de puntuaciones
    Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT;                                                          // Panel del marcador asociado al jugador
    Id id_;                                                                                                           // Identificador para el jugador
    State walking_state_ = State::WALKING_STOP;                                                                       // Estado del jugador al moverse
    State firing_state_ = State::FIRING_NONE;                                                                         // Estado del jugador al disparar
    State playing_state_ = State::WAITING;                                                                            // Estado del jugador en el juego
    BulletColorPair bullet_colors_ = {.normal_color = Bullet::Color::YELLOW, .powered_color = Bullet::Color::GREEN};  // Par de colores de balas para este jugador
    std::string bullet_sound_file_ = "bullet1p.wav";                                                                  // Archivo de sonido de bala para este jugador

    float pos_x_ = 0.0F;                          // Posición en el eje X
    float default_pos_x_;                         // Posición inicial para el jugador
    float vel_x_ = 0.0F;                          // Cantidad de píxeles a desplazarse en el eje X
    float score_multiplier_ = 1.0F;               // Multiplicador de puntos
    int pos_y_ = 0;                               // Posición en el eje Y
    int default_pos_y_;                           // Posición inicial para el jugador
    int vel_y_ = 0;                               // Cantidad de píxeles a desplazarse en el eje Y
    float invulnerable_time_accumulator_ = 0.0F;  // Acumulador de tiempo para invulnerabilidad (time-based)
    float power_up_time_accumulator_ = 0.0F;      // Acumulador de tiempo para power-up (time-based)
    float continue_time_accumulator_ = 0.0F;      // Acumulador de tiempo para continue counter (time-based)
    float name_entry_time_accumulator_ = 0.0F;    // Acumulador de tiempo para name entry counter (time-based)
    float showing_name_time_accumulator_ = 0.0F;  // Acumulador de tiempo para showing name (time-based)
    float waiting_time_accumulator_ = 0.0F;       // Acumulador de tiempo para waiting movement (time-based)
    float step_time_accumulator_ = 0.0F;          // Acumulador de tiempo para step counter (time-based)

    // ========================================
    // NUEVO SISTEMA DE DISPARO DE DOS LÍNEAS
    // ========================================

    // LÍNEA 1: SISTEMA FUNCIONAL (CanFire)
    float fire_cooldown_timer_ = 0.0F;  // Tiempo restante hasta poder disparar otra vez
    bool can_fire_new_system_ = true;   // true si puede disparar ahora mismo

    // LÍNEA 2: SISTEMA VISUAL (Animaciones)
    enum class VisualFireState {
        NORMAL,      // Brazo en posición neutral
        AIMING,      // Brazo alzado (disparando)
        RECOILING,   // Brazo en retroceso
        THREAT_POSE  // Posición amenazante
    };

    VisualFireState visual_fire_state_ = VisualFireState::NORMAL;
    float visual_state_timer_ = 0.0F;  // Tiempo en el estado visual actual
    float aiming_duration_ = 0.0F;     // Duración del estado AIMING
    float recoiling_duration_ = 0.0F;  // Duración del estado RECOILING

    int invulnerable_counter_ = INVULNERABLE_COUNTER;  // Contador para la invulnerabilidad
    int score_ = 0;                                    // Puntos del jugador
    int coffees_ = 0;                                  // Indica cuántos cafés lleva acumulados
    int power_up_counter_ = POWERUP_COUNTER;           // Temporizador para el modo PowerUp
    int power_up_x_offset_ = 0;                        // Desplazamiento del sprite de PowerUp respecto al sprite del jugador
    int continue_counter_ = 10;                        // Contador para poder continuar
    int controller_index_ = 0;                         // Índice del array de mandos que utilizará para moverse
    size_t demo_file_ = 0;                             // Indice del fichero de datos para el modo demo
    size_t z_order_ = 0;                               // Orden de dibujado en la pantalla
    float name_entry_idle_time_accumulator_ = 0.0F;    // Tiempo idle acumulado para poner nombre (milisegundos)
    float name_entry_total_time_accumulator_ = 0.0F;   // Tiempo total acumulado poniendo nombre (milisegundos)
    int step_counter_ = 0;                             // Cuenta los pasos para los estados en los que camina automáticamente
    int credits_used_ = 0;                             // Indica el número de veces que ha continuado
    int waiting_counter_ = 0;                          // Contador para el estado de espera
    bool qualifies_for_high_score_ = false;            // Indica si tiene una puntuación que le permite entrar en la tabla de records
    bool invulnerable_ = true;                         // Indica si el jugador es invulnerable
    bool extra_hit_ = false;                           // Indica si el jugador tiene un toque extra
    bool power_up_ = false;                            // Indica si el jugador tiene activo el modo PowerUp
    bool power_sprite_visible_ = false;                // Indica si el sprite de power-up debe ser visible
    bool in_power_up_ending_phase_ = false;            // Indica si está en la fase final del power-up (alternando colores)
    bool bullet_color_toggle_ = false;                 // Para alternar entre verde y amarillo en fase final
    bool demo_ = false;                                // Para que el jugador sepa si está en el modo demostración
    bool game_completed_ = false;                      // Indica si ha completado el juego
    bool uses_keyboard_ = false;                       // Indica si usa el teclado como dispositivo de control
    bool recover_sound_triggered_ = false;             // Indica si ya ha sonado el sonido en el estado RECOVER

    // --- Métodos internos ---
    void shiftColliders();  // Actualiza el círculo de colisión a la posición del jugador
    void shiftSprite();     // Recoloca el sprite

    // --- Setters internos ---
    void setController(int index) { controller_index_ = index; }
    void setFiringState(State state) { firing_state_ = state; }
    void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
    void setPowerUpCounter(int value) { power_up_counter_ = value; }
    void setScore(int score) { score_ = score; }
    void setScoreMultiplier(float value) { score_multiplier_ = value; }

    // --- Actualizadores de estado (time-based) ---
    void updateInvulnerable(float delta_time);      // Monitoriza el estado de invulnerabilidad
    void updateContinueCounter(float delta_time);   // Actualiza el contador de continue
    void updateEnterNameCounter(float delta_time);  // Actualiza el contador de entrar nombre
    void updateShowingName(float delta_time);       // Actualiza el estado SHOWING_NAME
    void decNameEntryCounter();                     // Decrementa el contador de entrar nombre

    // --- Utilidades generales ---
    void updateScoreboard();                              // Actualiza el panel del marcador
    void setScoreboardMode(Scoreboard::Mode mode) const;  // Cambia el modo del marcador
    void playSound(const std::string& name) const;        // Hace sonar un sonido
    [[nodiscard]] auto isRenderable() const -> bool;      // Indica si se puede dibujar el objeto
    void addScoreToScoreBoard() const;                    // Añade una puntuación a la tabla de records

    // --- Sistema de disparo (nuevo - dos líneas) ---
    void updateFireSystem(float delta_time);      // Método principal del nuevo sistema de disparo
    void updateFunctionalLine(float delta_time);  // Actualiza la línea funcional (CanFire)
    void updateVisualLine(float delta_time);      // Actualiza la línea visual (Animaciones)
    void updateFiringStateFromVisual();           // Sincroniza firing_state_ con visual_fire_state_
    void transitionToRecoilingNew();              // Transición AIMING → RECOILING
    void transitionToThreatPose();                // Transición RECOILING → THREAT_POSE
    void transitionToNormalNew();                 // Transición THREAT_POSE → NORMAL

    // --- Manejadores de movimiento ---
    void handlePlayingMovement(float delta_time);  // Gestiona el movimiento durante el juego
    void handleRecoverMovement();                  // Comprueba si ha acabado la animación de recuperación
    void updateStepCounter(float delta_time);      // Incrementa o ajusta el contador de pasos
    void setInputBasedOnPlayerId();                // Asocia las entradas de control según el jugador

    // --- Manejadores de estados especiales ---
    void handleRollingMovement();           // Actualiza la lógica de movimiento de "rodar"
    void handleRollingBoundaryCollision();  // Detecta colisiones con límites durante rodamiento
    void handleRollingGroundCollision();    // Gestiona interacción con el suelo durante rodamiento
    void handleRollingStop();               // Detiene el movimiento del objeto rodante
    void handleRollingBounce();             // Aplica lógica de rebote durante rodamiento
    void handleContinueTimeOut();           // Gestiona tiempo de espera en pantalla "Continuar"

    // --- Manejadores de transiciones de pantalla ---
    void handleTitleAnimation(float delta_time);   // Ejecuta animación del título
    void handleLeavingScreen(float delta_time);    // Lógica para salir de pantalla
    void handleEnteringScreen(float delta_time);   // Lógica para entrar en pantalla
    void handlePlayer1Entering(float delta_time);  // Entrada del Jugador 1
    void handlePlayer2Entering(float delta_time);  // Entrada del Jugador 2

    // --- Manejadores de pantallas especiales ---
    void handleCreditsMovement(float delta_time);  // Movimiento en pantalla de créditos
    void handleCreditsRightMovement();             // Movimiento hacia la derecha en créditos
    void handleCreditsLeftMovement();              // Movimiento hacia la izquierda en créditos
    void handleWaitingMovement(float delta_time);  // Animación del jugador saludando
    void updateWalkingStateForCredits();           // Actualiza estado de caminata en créditos

    // --- Introducción de nombre ---
    void handleNameCharacterAddition();
    void handleNameCharacterRemoval();
    void handleNameSelectionMove(Input::Action action);
    void confirmNameEntry();

    // --- Utilidades de animación ---
    [[nodiscard]] auto computeAnimation() const -> std::pair<std::string, SDL_FlipMode>;  // Calcula animación de movimiento y disparo
};