#include "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();
    if (loader.initialize(resource_pack_path, true)) {
        resource_pack_enabled_ = true;
        std::cout << "Asset system initialized with resource pack: " << resource_pack_path << std::endl;
    } else {
        resource_pack_enabled_ = false;
        std::cout << "Asset system initialized in fallback mode (filesystem)" << std::endl;
    }
}

std::vector<uint8_t> AssetIntegrated::loadFile(const std::string& filename) {
    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 relativePath = filename;

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

        auto data = loader.loadResource(relativePath);
        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 << std::endl;
        return {};
    }

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

    std::vector<uint8_t> data(fileSize);
    if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
        std::cerr << "Error: Could not read file: " << filename << std::endl;
        return {};
    }

    return data;
}

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

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

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

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

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

bool AssetIntegrated::shouldUseResourcePack(const std::string& filepath) const {
    // 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.find("config/") == 0) {
        return false;
    }

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

    return false;
}