#include "game/gameplay/zone_manager.hpp"

#include <exception>  // Para exception
#include <iostream>   // Para cerr, cout
#include <string>     // Para string

#include "core/resources/resource_helper.hpp"  // Para Resource::Helper::loadFile
#include "external/fkyaml_node.hpp"            // Para fkyaml::node

// [SINGLETON]
ZoneManager* ZoneManager::zone_manager = nullptr;

// [SINGLETON] Inicialización: crea la instancia y carga el yaml de zonas
void ZoneManager::init() {
    if (ZoneManager::zone_manager != nullptr) { return; }
    ZoneManager::zone_manager = new ZoneManager();
    ZoneManager::zone_manager->loadFromFile("data/zones/zones.yaml");
}

// [SINGLETON]
void ZoneManager::destroy() {
    delete ZoneManager::zone_manager;
    ZoneManager::zone_manager = nullptr;
}

// [SINGLETON]
auto ZoneManager::get() -> ZoneManager* {
    return ZoneManager::zone_manager;
}

// Carga zones.yaml usando Resource::Helper (soporta pack + filesystem)
void ZoneManager::loadFromFile(const std::string& file_path) {
    auto file_data = Resource::Helper::loadFile(file_path);
    if (file_data.empty()) {
        std::cerr << "ZoneManager: Unable to load " << file_path << "\n";
        return;
    }

    try {
        const std::string YAML_CONTENT(file_data.begin(), file_data.end());
        auto yaml = fkyaml::node::deserialize(YAML_CONTENT);

        if (!yaml.contains("zones") || yaml["zones"].is_null()) {
            std::cerr << "ZoneManager: " << file_path << " has no 'zones' section\n";
            return;
        }

        for (const auto& zone_node : yaml["zones"]) {
            Zone::Data zone;

            if (zone_node.contains("name")) {
                zone.name = zone_node["name"].get_value<std::string>();
            }
            if (zone_node.contains("tileSetFile")) {
                zone.tile_set_file = zone_node["tileSetFile"].get_value<std::string>();
            }
            if (zone_node.contains("music")) {
                zone.music = zone_node["music"].get_value<std::string>();
            }
            if (zone_node.contains("bgColor")) {
                zone.bg_color = static_cast<Uint8>(zone_node["bgColor"].get_value<int>());
            }

            if (zone.name.empty()) {
                std::cerr << "ZoneManager: skipping zone without name\n";
                continue;
            }

            zones_.push_back(zone);
        }

        std::cout << "ZoneManager: loaded " << zones_.size() << " zones from " << file_path << "\n";
    } catch (const fkyaml::exception& e) {
        std::cerr << "ZoneManager: YAML parsing error in " << file_path << ": " << e.what() << "\n";
    } catch (const std::exception& e) {
        std::cerr << "ZoneManager: Error loading " << file_path << ": " << e.what() << "\n";
    }
}

auto ZoneManager::getZone(const std::string& name) const -> const Zone::Data* {
    for (const auto& zone : zones_) {
        if (zone.name == name) {
            return &zone;
        }
    }
    return nullptr;
}

auto ZoneManager::getDefaultZone() const -> const Zone::Data* {
    if (zones_.empty()) { return nullptr; }
    return &zones_.front();
}

auto ZoneManager::getZoneNames() const -> std::vector<std::string> {
    std::vector<std::string> names;
    names.reserve(zones_.size());
    for (const auto& zone : zones_) {
        names.push_back(zone.name);
    }
    return names;
}
