#pragma once

#include <SDL3/SDL.h>

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

#include "game/entities/enemy.hpp"       // Para EnemyData
#include "game/entities/item.hpp"        // Para ItemData
#include "game/gameplay/scoreboard.hpp"  // Para Scoreboard::Data
#include "utils/defines.hpp"             // Para Tile::SIZE, Map::WIDTH, Map::HEIGHT
class Surface;
class EnemyManager;
class ItemManager;
class CollisionMap;
class TileCollider;
class TilemapRenderer;

class Room {
   public:
    // -- Enumeraciones y estructuras ---
    enum class Border : int {
        TOP = 0,
        RIGHT = 1,
        BOTTOM = 2,
        LEFT = 3,
        NONE = 4
    };

    struct Data {
        std::string number;
        Uint8 bg_color{0};
        Uint8 item_color1{12};
        Uint8 item_color2{6};
        std::string upper_room;
        std::string lower_room;
        std::string left_room;
        std::string right_room;
        std::string tile_set_file;
        int conveyor_belt_direction{0};
        std::vector<int> tile_map;
        std::vector<int> collision_tile_map;
        std::vector<Enemy::Data> enemies;
        std::vector<Item::Data> items;
    };

    // Constructor y destructor
    Room(const std::string& room_path, std::shared_ptr<Scoreboard::Data> data);
    ~Room();  // NOLINT(modernize-use-equals-default, performance-trivially-destructible)

    // --- Funciones ---
    [[nodiscard]] auto getNumber() const -> const std::string& { return number_; }
    [[nodiscard]] auto getBGColor() const -> Uint8 { return bg_color_; }
    void renderMap();
    void renderEnemies();
    void renderItems();
#ifdef _DEBUG
    void redrawMap();
    void updateEditorMode(float delta_time);
    void resetEnemyPositions(const std::vector<Enemy::Data>& enemy_data);
    auto getEnemyManager() -> EnemyManager* { return enemy_manager_.get(); }
    auto getItemManager() -> ItemManager* { return item_manager_.get(); }
    void setBgColor(Uint8 color);
    void setItemColors(Uint8 color1, Uint8 color2);
    void setTile(int index, int tile_value);
    [[nodiscard]] auto getTileSetFile() const -> const std::string& { return tile_set_file_; }
    [[nodiscard]] auto getTileSetWidth() const -> int { return tile_set_width_; }
#endif
    void update(float delta_time);
    auto getRoom(Border border) -> std::string;
    auto enemyCollision(SDL_FRect& rect) -> bool;
    auto itemCollision(SDL_FRect& rect) -> bool;
    void setPaused(bool value);
    [[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; }
    [[nodiscard]] auto getTileCollider() const -> const TileCollider&;

    // Método de carga de archivos YAML (delegado a RoomLoader)
    static auto loadYAML(const std::string& file_path, bool verbose = false) -> Data;

   private:
    static constexpr int TILE_SIZE = ::Tile::SIZE;
    static constexpr int MAP_WIDTH = ::Map::WIDTH;
    static constexpr int MAP_HEIGHT = ::Map::HEIGHT;

    std::unique_ptr<EnemyManager> enemy_manager_;
    std::unique_ptr<ItemManager> item_manager_;
    std::unique_ptr<CollisionMap> collision_map_;
    std::unique_ptr<TilemapRenderer> tilemap_renderer_;
    std::shared_ptr<Surface> surface_;
    std::shared_ptr<Scoreboard::Data> data_;

    std::string number_;
    Uint8 bg_color_{0};
    Uint8 item_color1_{12};
    Uint8 item_color2_{6};
    std::string upper_room_;
    std::string lower_room_;
    std::string left_room_;
    std::string right_room_;
    std::string tile_set_file_;
    std::vector<int> tile_map_;
    int conveyor_belt_direction_{0};
    bool is_paused_{false};
    int tile_set_width_{0};

    void initializeRoom(const Data& room);
};
