#include "core/resources/resource_helper.hpp"

#include <algorithm>  // Para replace
#include <cstddef>    // Para size_t
#include <fstream>    // Para basic_ifstream, basic_ostream, basic_ios, operator<<, ios, basic_istream, endl, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
#include <iostream>   // Para cout

#include "core/resources/resource_loader.hpp"  // Para ResourceLoader

namespace ResourceHelper {
    static bool resource_system_initialized = false;

    auto initializeResourceSystem(const std::string& pack_file, bool enable_fallback) -> bool {
        auto& loader = ResourceLoader::getInstance();
        resource_system_initialized = loader.initialize(pack_file, enable_fallback);

        if (resource_system_initialized) {
            std::cout << "Resource system initialized with pack: " << pack_file << '\n';
        } else {
            std::cout << "Resource system using fallback mode (filesystem only)" << '\n';
        }

        return true;  // Always return true as fallback is acceptable
    }

    void shutdownResourceSystem() {
        if (resource_system_initialized) {
            ResourceLoader::getInstance().shutdown();
            resource_system_initialized = false;
        }
    }

    auto loadFile(const std::string& filepath) -> std::vector<uint8_t> {
        if (resource_system_initialized && shouldUseResourcePack(filepath)) {
            auto& loader = ResourceLoader::getInstance();
            std::string pack_path = getPackPath(filepath);

            auto data = loader.loadResource(pack_path);
            if (!data.empty()) {
                return data;
            }
        }

        // Fallback a filesystem
        std::ifstream file(filepath, std::ios::binary | std::ios::ate);
        if (!file) {
            return {};
        }

        std::streamsize file_size = file.tellg();
        file.seekg(0, std::ios::beg);

        std::vector<uint8_t> data(file_size);
        if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
            return {};
        }

        return data;
    }

    auto shouldUseResourcePack(const std::string& filepath) -> bool {
        // Archivos que NO van al pack:
        // - config/ (ahora está fuera de data/)
        // - archivos absolutos del sistema

        if (filepath.find("config/") != std::string::npos) {
            return false;
        }

        // Si contiene "data/" es candidato para el pack
        if (filepath.find("data/") != std::string::npos) {
            return true;
        }

        return false;
    }

    auto getPackPath(const std::string& asset_path) -> std::string {
        std::string pack_path = asset_path;

        // Normalizar separadores de path a '/'
        std::ranges::replace(pack_path, '\\', '/');

        // Remover prefijo "data/" si existe
        size_t data_pos = pack_path.find("data/");
        if (data_pos != std::string::npos) {
            pack_path = pack_path.substr(data_pos + 5);  // +5 para saltar "data/"
        }

        // Remover cualquier prefijo de path absoluto
        size_t last_data = pack_path.rfind("data/");
        if (last_data != std::string::npos) {
            pack_path = pack_path.substr(last_data + 5);
        }

        return pack_path;
    }
}  // namespace ResourceHelper