#pragma once

#include <SDL3/SDL.h>

#include <cstdint>
#include <memory>  // Para shared_ptr
#include <string>  // Para string

#include "game/entities/solid_actor.hpp"  // Para SolidActor

class AnimatedSprite;

/**
 * @brief Puerta que actúa como muro hasta que se abre con la llave correcta
 *
 * Entidad de 8x32 px (1 columna × 4 filas de tiles) con tres animaciones:
 *   - "closed":  estado inicial bloqueante (frame estático)
 *   - "opening": animación de transición que se reproduce una sola vez
 *   - "opened":  estado final no bloqueante (frame estático)
 *
 * El comportamiento de "muro" se implementa como SolidActor con flag
 * BLOCKS_PLAYER. El SolidActorManager de la Room lo consulta en los sweeps
 * del Player. Cuando la puerta termina de abrirse, se limpia el flag
 * BLOCKS_PLAYER y el sweep deja de verla como pared.
 */
class Door : public SolidActor {
   public:
    enum class State : std::uint8_t {
        CLOSED = 0,
        OPENING = 1,
        OPENED = 2
    };

    struct Data {
        std::string animation_path;  // Ruta al fichero de animación (ej. "door1.yaml")
        std::string id;              // Identificador que coincide con el id de la llave que la abre
        float x{0.0F};               // Posición X en píxeles (alineada al grid de 8 px)
        float y{0.0F};               // Posición Y en píxeles (alineada al grid de 8 px)
    };

    explicit Door(const Data& data, bool start_opened);
    ~Door() = default;

    void render();                  // Pinta la puerta en pantalla
    void update(float delta_time);  // Avanza la animación; si OPENING termina → OPENED

    auto getCollider() -> SDL_FRect& { return aabb_; }                      // Rectángulo de colisión (8x32)
    [[nodiscard]] auto getPos() const -> SDL_FPoint;                        // Posición en píxeles
    [[nodiscard]] auto getId() const -> const std::string& { return id_; }  // Identificador
    [[nodiscard]] auto getState() const -> State { return state_; }         // Estado actual

    void startOpening();        // Transición CLOSED → OPENING
    auto justOpened() -> bool;  // Flag one-shot consumido por el manager

    void setPaused(bool paused) { is_paused_ = paused; }  // Pausa/despausa la animación

#ifdef _DEBUG
    void setPosition(float x, float y);  // Mueve sprite y AABB en vivo (editor)
#endif

   private:
    std::shared_ptr<AnimatedSprite> sprite_;  // Sprite animado de la puerta
    std::string id_;                          // Identificador
    State state_{State::CLOSED};              // Estado actual
    bool just_opened_{false};                 // Flag one-shot: la puerta acaba de transicionar a OPENED
    bool is_paused_{false};                   // Indica si la puerta está pausada
};
