#include "core/resources/asset_integrated.hpp"

#include <filesystem>
#include <fstream>
#include <iostream>

bool AssetIntegrated::resource_pack_enabled = false;

void AssetIntegrated::initWithResourcePack(const std::string& executable_path,
    const std::string& resource_pack_path) {
    // Inicializar Asset normal
    Asset::init(executable_path);

    // Inicializar ResourceLoader
    auto& loader = ResourceLoader::getInstance();
    resource_pack_enabled = loader.initialize(resource_pack_path, true);
    if (resource_pack_enabled) {
        std::cout << "Asset system initialized with resource pack: " << resource_pack_path << '\n';
    } else {
        std::cout << "Asset system initialized in fallback mode (filesystem)" << '\n';
    }
}

auto AssetIntegrated::loadFile(const std::string& filename) -> std::vector<uint8_t> {
    if (shouldUseResourcePack(filename) && resource_pack_enabled) {
        // Intentar cargar del pack de recursos
        auto& loader = ResourceLoader::getInstance();

        // Convertir ruta completa a ruta relativa para el pack
        std::string relative_path = filename;

        // Si la ruta contiene "data/", extraer la parte relativa
        size_t data_pos = filename.find("data/");
        if (data_pos != std::string::npos) {
            relative_path = filename.substr(data_pos + 5);  // +5 para saltar "data/"
        }

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

    // Fallback: cargar del filesystem
    std::ifstream file(filename, std::ios::binary | std::ios::ate);
    if (!file) {
        std::cerr << "Error: Could not open file: " << filename << '\n';
        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)) {
        std::cerr << "Error: Could not read file: " << filename << '\n';
        return {};
    }

    return data;
}

auto AssetIntegrated::fileExists(const std::string& filename) -> bool {
    if (shouldUseResourcePack(filename) && resource_pack_enabled) {
        auto& loader = ResourceLoader::getInstance();

        // Convertir ruta completa a ruta relativa para el pack
        std::string relative_path = filename;
        size_t data_pos = filename.find("data/");
        if (data_pos != std::string::npos) {
            relative_path = filename.substr(data_pos + 5);
        }

        if (loader.resourceExists(relative_path)) {
            return true;
        }
    }

    // Verificar en filesystem
    return std::filesystem::exists(filename);
}

auto AssetIntegrated::getSystemPath(const std::string& filename) -> std::string {
    // Los archivos de sistema/config siempre van al filesystem
    return filename;
}

auto AssetIntegrated::shouldUseResourcePack(const std::string& filepath) -> bool {
    // Los archivos que NO van al pack:
    // - Archivos de config/ (ahora están fuera de data/)
    // - Archivos con absolute=true en assets.txt
    // - Archivos de sistema (${SYSTEM_FOLDER})

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

    if (filepath.find("/data/") != std::string::npos ||
        filepath.starts_with("data/")) {
        return true;
    }

    return false;
}