/*
 * ============================================================
 *  Ejemplo 11 — Feature Flags en Tiempo Real (polling)
 *
 *  Endpoint: GET /api/feat/{slug}
 *
 *  A diferencia del ejemplo 05 (Client Features con estructura
 *  completa de toggles/sliders), este ejemplo usa el endpoint
 *  de Feature Flags que retorna un mapa simple de ID → bool.
 *
 *  Desde el panel (Funciones → Feature Flags) creas un combo
 *  con un slug y defines flags numericos (1, 2, 3...).
 *  Tu C++ los lee en tiempo real y activa/desactiva funciones
 *  sin recompilar.
 *
 *  JSON del endpoint:
 *    { "1": true, "2": false, "3": true, ... }
 *
 *  Casos de uso:
 *    - Activar/desactivar features remotamente al instante
 *    - Kill switch de emergencia para features individuales
 *    - A/B testing de funcionalidades
 *    - Despliegue gradual de features nuevas
 * ============================================================
 */
#include <string>
#include <iostream>
#include <thread>
#include <chrono>
#include <unordered_map>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")

// ── Helper HTTP GET ──────────────────────────────────────────────────────────
std::string HttpGet(const std::string& url) {
    HINTERNET hInternet = InternetOpenA("SAO", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (!hInternet) return "";
    HINTERNET hUrl = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
    if (!hUrl) { InternetCloseHandle(hInternet); return ""; }
    std::string result;
    char buf[1024];
    DWORD read = 0;
    while (InternetReadFile(hUrl, buf, sizeof(buf), &read) && read > 0)
        result.append(buf, read);
    InternetCloseHandle(hUrl);
    InternetCloseHandle(hInternet);
    return result;
}

// ── Estado global de feature flags ───────────────────────────────────────────
std::unordered_map<int, bool> g_featureFlags;
bool g_featureFlagsLoaded = false;

// ── Parser simple de JSON { "1": true, "2": false } ─────────────────────────
static std::unordered_map<int, bool> parseFeatureFlags(const std::string& json) {
    std::unordered_map<int, bool> flags;
    size_t pos = 0;

    while ((pos = json.find("\"", pos)) != std::string::npos) {
        pos++; // saltar comilla de apertura
        size_t keyEnd = json.find("\"", pos);
        if (keyEnd == std::string::npos) break;

        std::string keyStr = json.substr(pos, keyEnd - pos);
        pos = keyEnd + 1;

        // buscar ":"
        size_t colonPos = json.find(":", pos);
        if (colonPos == std::string::npos) break;
        pos = colonPos + 1;

        // saltar espacios
        while (pos < json.size() && json[pos] == ' ') pos++;

        bool val = json.substr(pos, 4) == "true";

        try {
            int id = std::stoi(keyStr);
            flags[id] = val;
        } catch (...) {}
    }

    return flags;
}

// ── Thread de polling — corre en background ──────────────────────────────────
// Reemplaza "sao-combo-funciones" con el slug de tu combo en el panel
void FetchFeatureFlags() {
    while (true) {
        std::string json = HttpGet("https://saoauth.com/api/feat/sao-combo-funciones");

        if (!json.empty()) {
            g_featureFlags = parseFeatureFlags(json);
            g_featureFlagsLoaded = true;
        }

        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

// ── Helper: verificar si un flag esta activo ─────────────────────────────────
bool IsFeatureEnabled(int flagId) {
    auto it = g_featureFlags.find(flagId);
    return (it != g_featureFlags.end()) ? it->second : false;
}

// ── Ejemplo de uso ───────────────────────────────────────────────────────────
int main() {
    // Lanzar thread de polling
    std::thread(FetchFeatureFlags).detach();

    // Esperar a que carguen los flags
    std::cout << "Cargando feature flags...\n";
    while (!g_featureFlagsLoaded) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    std::cout << "[Feature Flags] Cargados: " << g_featureFlags.size() << " flags\n\n";

    // Mostrar todos los flags
    for (auto& [id, enabled] : g_featureFlags) {
        std::cout << "  Flag " << id << " = " << (enabled ? "ON" : "OFF") << "\n";
    }

    // ── Usar flags por ID en tu codigo ───────────────────────────────────────
    // Los IDs los defines en el panel al crear cada flag
    //
    // Ejemplo: flag 1 = Aimbot, flag 2 = ESP, flag 3 = Speed
    //
    //   if (IsFeatureEnabled(1)) {
    //       // Ejecutar logica de aimbot
    //   }
    //   if (IsFeatureEnabled(2)) {
    //       // Ejecutar logica de ESP
    //   }

    std::cout << "\nEjemplo de verificacion:\n";
    std::cout << "  Aimbot (1): " << (IsFeatureEnabled(1) ? "Activado" : "Desactivado") << "\n";
    std::cout << "  ESP    (2): " << (IsFeatureEnabled(2) ? "Activado" : "Desactivado") << "\n";
    std::cout << "  Speed  (3): " << (IsFeatureEnabled(3) ? "Activado" : "Desactivado") << "\n";

    // ── Monitorear cambios en tiempo real ────────────────────────────────────
    std::cout << "\nMonitoreando cambios... (Ctrl+C para salir)\n";
    auto lastFlags = g_featureFlags;

    while (true) {
        for (auto& [id, enabled] : g_featureFlags) {
            auto it = lastFlags.find(id);
            if (it == lastFlags.end() || it->second != enabled) {
                std::cout << "[UPDATE] Flag " << id << ": " << (enabled ? "ON" : "OFF") << "\n";
            }
        }
        lastFlags = g_featureFlags;

        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return 0;
}
