/*
 * ============================================================
 *  Ejemplo 06 — Loader completo (flujo real de producción)
 *
 *  Orden de ejecución recomendado:
 *    1. Verificar status de la app (¿está online?)
 *    2. Leer notices (anuncios de mantenimiento, updates)
 *    3. Autenticar la key
 *    4. Mostrar anuncio global si existe
 *    5. Verificar versión y ofrecer update
 *    6. Cargar features del panel
 *    7. Iniciar el programa principal
 * ============================================================
 */
#include "SaoAuth.hpp"
#include <iostream>
#include <thread>
#include <chrono>

// ── Configuración ─────────────────────────────────────────────────────────────
const std::wstring PANEL_HOST    = L"saoauth.com";
const std::string  STATUS_SLUG   = "miapp";       // slug del status en el panel
const std::string  NOTICE_SLUG   = "loader";      // slug del notice en el panel
const std::string  LOCAL_VERSION = "1.0";         // versión de este exe

SaoAuth::api SaoAuthApp(
    "MiApp",
    "TU_OWNERID_AQUI",
    "TU_SECRET_AQUI",
    LOCAL_VERSION,
    "https://saoauth.com/api/client/auth"
);

// ── Helpers ───────────────────────────────────────────────────────────────────
bool CheckStatus() {
    std::wstring path = L"/api/status/" + std::wstring(STATUS_SLUG.begin(), STATUS_SLUG.end());
    std::string raw = SaoAuth::HttpGet(PANEL_HOST, path);
    if (raw.empty()) {
        MessageBoxA(nullptr, "Sin conexión al servidor.", "Error", MB_ICONERROR);
        return false;
    }
    try {
        auto j = json::parse(raw);
        if (!j.value("success", false)) return true; // si no existe el slug, continuar
        bool online = j["status"].value("is_active", true);
        if (!online) {
            // Obtener anuncio del status
            std::wstring annPath = L"/api/status/" +
                std::wstring(STATUS_SLUG.begin(), STATUS_SLUG.end()) + L"/announcement";
            std::string annRaw = SaoAuth::HttpGet(PANEL_HOST, annPath);
            std::string ann = "";
            try {
                auto aj = json::parse(annRaw);
                ann = aj.value("announcement", "");
            } catch (...) {}

            std::string msg = "El servicio está temporalmente fuera de línea.";
            if (!ann.empty()) msg += "\n\n" + ann;
            MessageBoxA(nullptr, msg.c_str(), "Servicio no disponible", MB_ICONWARNING);
            return false;
        }
    } catch (...) {}
    return true;
}

void CheckNotices() {
    std::wstring path = L"/api/notices/" + std::wstring(NOTICE_SLUG.begin(), NOTICE_SLUG.end());
    std::string raw = SaoAuth::HttpGet(PANEL_HOST, path);
    if (raw.empty()) return;
    try {
        auto j = json::parse(raw);
        if (!j.value("success", false)) return;
        auto& n = j["notice"];
        if (!n.value("is_active", false)) return;

        std::string title   = n.value("title",   "Aviso");
        std::string message = n.value("message", "");
        std::string type    = n.value("type",    "info");
        if (message.empty()) return;

        UINT icon = MB_ICONINFORMATION;
        if (type == "warning") icon = MB_ICONWARNING;
        if (type == "danger")  icon = MB_ICONERROR;
        MessageBoxA(nullptr, message.c_str(), title.c_str(), icon);
    } catch (...) {}
}

std::map<int, SaoAuth::Feature> g_features; // features globales

void LoadFeatures() {
    std::string raw = SaoAuth::HttpGet(PANEL_HOST, L"/api/client_features");
    if (raw.empty()) return;
    try {
        auto j = json::parse(raw);
        if (!j.value("success", false)) return;
        for (auto& [tid_str, f] : j["flat"].items()) {
            SaoAuth::Feature feat;
            feat.tid     = std::stoi(tid_str);
            feat.name    = f.value("name", "");
            feat.type    = f.value("type", "toggle");
            feat.enabled = f.value("default", 0) != 0;
            feat.value   = f.value("default", 0.0f);
            feat.min_val = f.value("min", 0.0f);
            feat.max_val = f.value("max", 100.0f);
            feat.step    = f.value("step", 1.0f);
            feat.unit    = f.value("unit", "");
            g_features[feat.tid] = feat;
        }
    } catch (...) {}
}

// ── Programa principal (se ejecuta después de auth exitosa) ───────────────────
void RunMain(const SaoAuth::AuthResult& auth) {
    std::cout << "\n=== PROGRAMA INICIADO ===\n";
    std::cout << "Usuario autenticado\n";
    std::cout << "Expira: " << (auth.expires_at.empty() ? "Permanente" : auth.expires_at) << "\n";
    std::cout << "Sub: " << (auth.sub.empty() ? "default" : auth.sub)
              << " (nivel " << auth.sub_level << ")\n";

    // Usar features cargadas
    bool feat1 = g_features.count(1) ? g_features[1].enabled : false;
    float feat2 = g_features.count(2) ? g_features[2].value : 0.0f;

    std::cout << "Feature 1 (toggle): " << (feat1 ? "ON" : "OFF") << "\n";
    std::cout << "Feature 2 (slider): " << feat2 << "\n";

    // Loop principal...
    std::cout << "Presiona Enter para salir...\n";
    std::cin.get();
}

// ── Entry point ───────────────────────────────────────────────────────────────
int main() {
    std::cout << "=== LOADER v" << LOCAL_VERSION << " ===\n\n";

    // PASO 1: Verificar status
    std::cout << "[1/5] Verificando estado del servidor...\n";
    if (!CheckStatus()) return 1;
    std::cout << "      OK\n";

    // PASO 2: Notices
    std::cout << "[2/5] Cargando anuncios...\n";
    CheckNotices();
    std::cout << "      OK\n";

    // PASO 3: Pedir key y autenticar
    std::cout << "[3/5] Autenticacion\n";
    std::string key;
    std::cout << "      Ingresa tu licencia: ";
    std::cin >> key;
    std::cin.ignore();

    auto auth = SaoAuthApp.login(key);

    if (!auth.success) {
        // Manejar cada error con mensaje amigable
        std::string msg = auth.error;
        if (auth.error == "invalid_key")          msg = "Licencia invalida o no encontrada.";
        else if (auth.error == "key_expired")     msg = "Tu licencia ha expirado. Renuevala en nuestro Discord.";
        else if (auth.error == "key_banned")      msg = "Tu licencia ha sido suspendida.";
        else if (auth.error == "device_limit_reached") msg = "Maximo de dispositivos alcanzado. Contacta soporte.";
        else if (auth.error == "outdated_version") msg = "Actualiza el loader a la ultima version.";
        else if (auth.error == "app_disabled")    msg = "El servicio esta desactivado temporalmente.";
        else if (auth.error == "network_error")   msg = "Error de conexion. Verifica tu internet.";

        MessageBoxA(nullptr, msg.c_str(), "Error de autenticacion", MB_ICONERROR);
        return 1;
    }
    std::cout << "      OK — Autenticado\n";

    // PASO 4: Anuncio global
    if (!auth.announcement.empty()) {
        MessageBoxA(nullptr, auth.announcement.c_str(), "Aviso del sistema", MB_ICONINFORMATION);
    }

    // PASO 5: Verificar versión
    std::cout << "[4/5] Verificando version...\n";
    if (auth.version != LOCAL_VERSION) {
        std::string msg = "Nueva version disponible: " + auth.version +
                          "\nTu version: " + LOCAL_VERSION + "\n\n";
        if (!auth.file_url.empty())
            msg += "Descarga: " + auth.file_url;
        else
            msg += "Descarga la nueva version desde nuestro Discord.";

        int resp = MessageBoxA(nullptr, msg.c_str(),
                               "Actualizacion disponible", MB_YESNO | MB_ICONINFORMATION);
        if (resp == IDYES && !auth.file_url.empty()) {
            ShellExecuteA(nullptr, "open", auth.file_url.c_str(), nullptr, nullptr, SW_SHOW);
            return 0;
        }
    }
    std::cout << "      OK\n";

    // PASO 6: Cargar features
    std::cout << "[5/5] Cargando configuracion...\n";
    LoadFeatures();
    std::cout << "      OK — " << g_features.size() << " features cargadas\n";

    // PASO 7: Iniciar programa
    RunMain(auth);

    return 0;
}
