#pragma once
#include <string>
#include <vector>
#include <windows.h>
#include <winhttp.h>

#pragma comment(lib, "winhttp.lib")

// ─── Server URL Configuration ─────────────────────────
// Change SERVER_HOST to your server's IP/domain before building.
#define SERVER_HOST  L"202.60.232.225"
#define SERVER_PORT  3000
#define SERVER_USE_SSL  FALSE   // TRUE when you have HTTPS
// ───────────────────────────────────────────────────────

struct LoginResult {
    bool success = false;
    std::string accessToken;
    std::string refreshToken;
    std::string username;
    double matchRate = 0.0;
    std::string errorCode;
    std::string errorMessage;
    int retryAfter = 0;
};

struct StatusResult {
    bool online = false;
    std::string errorMessage;
};

struct RefreshResult {
    bool success = false;
    std::string accessToken;
    std::string refreshToken;
    std::string errorCode;
};

/**
 * NetworkClient — WinHTTP-based HTTPS client.
 * All methods are synchronous and should be called from a detached thread.
 * Integrates with CertPinner for SPKI public key pinning.
 */
class NetworkClient
{
public:
    static NetworkClient* Get();

    /// Check server reachability (GET /api/status)
    StatusResult CheckStatus();

    /// Login (POST /api/login) — sends SHA-256(password) + HWID components
    LoginResult Login(const std::string& username,
                      const std::string& passwordHash,
                      const std::string& cpuHash,
                      const std::string& boardHash,
                      const std::string& diskHash,
                      const std::string& macHash);

    /// Refresh access token (POST /api/refresh)
    RefreshResult RefreshToken(const std::string& refreshToken,
                               const std::string& cpuHash,
                               const std::string& boardHash,
                               const std::string& diskHash,
                               const std::string& macHash);

private:
    NetworkClient() = default;
    ~NetworkClient() = default;

    struct HttpResponse {
        DWORD statusCode = 0;
        std::string body;
    };

    /// Open WinHTTP session + connect
    HINTERNET Connect();
    void Close(HINTERNET hSession, HINTERNET hConnect);

    /// Send a POST JSON request and get response
    HttpResponse SendRequest(const std::wstring& endpoint,
                             const std::string& jsonBody,
                             const std::string& bearerToken = "");

    /// Build JSON body for login
    std::string BuildLoginBody(const std::string& username,
                               const std::string& passwordHash,
                               const std::string& cpuHash,
                               const std::string& boardHash,
                               const std::string& diskHash,
                               const std::string& macHash);

    static constexpr int TIMEOUT_MS = 10000;
};
