// 独立测试程序 - 不依赖外部库
// 使用Windows原生WinHTTP进行HTTP请求

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winhttp.h>
#pragma comment(lib, "winhttp.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#endif

#include "json.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <map>

using json = nlohmann::json;

// ============================================================================
// WinHTTP客户端
// ============================================================================
class HttpClient {
public:
    HttpClient() {
#ifdef _WIN32
        hSession_ = WinHttpOpen(L"VerifySDK/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
#endif
    }

    ~HttpClient() {
#ifdef _WIN32
        if (hConnect_) WinHttpCloseHandle(hConnect_);
        if (hSession_) WinHttpCloseHandle(hSession_);
#endif
    }

    std::string get(const std::string& url) {
        return request(url, "GET", "");
    }

    std::string post(const std::string& url, const std::string& body) {
        return request(url, "POST", body);
    }

private:
#ifdef _WIN32
    HINTERNET hSession_ = nullptr;
    HINTERNET hConnect_ = nullptr;
#endif

    std::string request(const std::string& url, const std::string& method, const std::string& body) {
        std::string result;
#ifdef _WIN32
        // 解析URL
        std::wstring wurl(url.begin(), url.end());
        URL_COMPONENTS uc = { sizeof(uc) };
        wchar_t host[256] = {0};
        wchar_t path[1024] = {0};
        uc.lpszHostName = host;
        uc.dwHostNameLength = 256;
        uc.lpszUrlPath = path;
        uc.dwUrlPathLength = 1024;

        if (!WinHttpCrackUrl(wurl.c_str(), 0, 0, &uc)) {
            throw std::runtime_error("Failed to parse URL");
        }

        // 连接服务器
        std::wstring whost(host);
        hConnect_ = WinHttpConnect(hSession_, whost.c_str(), uc.nPort, 0);
        if (!hConnect_) {
            throw std::runtime_error("Failed to connect to server");
        }

        // 创建请求
        std::wstring wpath(path);
        std::wstring wmethod(method.begin(), method.end());
        DWORD flags = (uc.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
        HINTERNET hRequest = WinHttpOpenRequest(hConnect_, wmethod.c_str(), wpath.c_str(),
                                                 nullptr, WINHTTP_NO_REFERER,
                                                 WINHTTP_DEFAULT_ACCEPT_TYPES, flags);
        if (!hRequest) {
            throw std::runtime_error("Failed to create request");
        }

        // 发送请求
        LPCWSTR headers = L"Content-Type: application/json\r\n";
        BOOL bResult = WinHttpSendRequest(hRequest, headers, -1,
                                           (LPVOID)body.c_str(), body.length(),
                                           body.length(), 0);
        if (!bResult) {
            WinHttpCloseHandle(hRequest);
            throw std::runtime_error("Failed to send request");
        }

        // 接收响应
        bResult = WinHttpReceiveResponse(hRequest, nullptr);
        if (!bResult) {
            WinHttpCloseHandle(hRequest);
            throw std::runtime_error("Failed to receive response");
        }

        // 读取数据
        DWORD dwSize = 0;
        DWORD dwDownloaded = 0;
        do {
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) break;
            if (dwSize == 0) break;

            std::vector<char> buffer(dwSize + 1);
            if (WinHttpReadData(hRequest, &buffer[0], dwSize, &dwDownloaded)) {
                result.append(buffer.data(), dwDownloaded);
            }
        } while (dwSize > 0);

        WinHttpCloseHandle(hRequest);
#else
        // Linux实现（简化版）
        result = curl_request(url, method, body);
#endif
        return result;
    }

#ifndef _WIN32
    std::string curl_request(const std::string& url, const std::string& method, const std::string& body) {
        // 简化的socket实现（仅用于演示）
        return "{\"code\": 200, \"message\": \"success\", \"data\": {}}";
    }
#endif
};

// ============================================================================
// 验证客户端
// ============================================================================
class VerifyClient {
public:
    VerifyClient(const std::string& baseUrl, const std::string& appKey)
        : baseUrl_(baseUrl), appKey_(appKey) {
        // 移除末尾斜杠
        if (!baseUrl_.empty() && baseUrl_.back() == '/') {
            baseUrl_.pop_back();
        }
    }

    void setToken(const std::string& token) {
        token_ = token;
    }

    // 获取应用信息
    json getAppInfo() {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/info";
        std::string response = http_.get(url);
        return json::parse(response);
    }

    // 检查更新
    json checkUpdate(const std::string& version = "") {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/check-update";
        if (!version.empty()) {
            url += "?version=" + version;
        }
        std::string response = http_.get(url);
        return json::parse(response);
    }

    // 用户登录
    json login(const std::string& username, const std::string& password,
               const std::string& deviceId) {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/login";

        json body;
        body["username"] = username;
        body["password"] = password;
        body["device_id"] = deviceId;

        std::string response = http_.post(url, body.dump());
        json result = json::parse(response);

        // 自动设置token
        if (result["code"].get_int() == 200 && result["data"].contains("token")) {
            token_ = result["data"]["token"].get_string();
        }

        return result;
    }

    // 用户注册
    json registerUser(const std::string& username, const std::string& password,
                      const std::string& deviceId) {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/register";

        json body;
        body["username"] = username;
        body["password"] = password;
        body["device_id"] = deviceId;

        std::string response = http_.post(url, body.dump());
        return json::parse(response);
    }

    // 心跳
    json heartbeat(uint64_t userId, const std::string& deviceId,
                   const std::string& instanceId = "") {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/heartbeat";

        json body;
        body["user_id"] = userId;
        body["device_id"] = deviceId;
        if (!instanceId.empty()) {
            body["instance_id"] = instanceId;
        }

        std::string response = http_.post(url, body.dump());
        return json::parse(response);
    }

    // 卡密充值
    json recharge(const std::string& username, const std::string& cardKey,
                  const std::string& deviceId) {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/recharge";

        json body;
        body["username"] = username;
        body["card_key"] = cardKey;
        body["device_id"] = deviceId;

        std::string response = http_.post(url, body.dump());
        return json::parse(response);
    }

    // 获取设备列表
    json getDevices() {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/devices";
        std::string response = http_.get(url);
        return json::parse(response);
    }

    // 获取云端变量
    json getVariables() {
        std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/variables";
        std::string response = http_.get(url);
        return json::parse(response);
    }

private:
    std::string baseUrl_;
    std::string appKey_;
    std::string token_;
    HttpClient http_;
};

// ============================================================================
// 测试函数
// ============================================================================
void printSeparator(const std::string& title) {
    std::cout << "\n";
    std::cout << "========================================\n";
    std::cout << title << "\n";
    std::cout << "========================================\n";
}

void testJson() {
    printSeparator("JSON功能测试");

    // 创建JSON对象
    json obj = json::object();
    obj["name"] = "测试应用";
    obj["version"] = "1.0.0";
    obj["active"] = true;
    obj["count"] = 100;

    std::cout << "[创建对象] ";
    std::cout << obj.dump() << "\n";

    // 创建数组
    json arr = json::array();
    arr.push_back("item1");
    arr.push_back("item2");
    arr.push_back(123);

    std::cout << "[创建数组] ";
    std::cout << arr.dump() << "\n";

    // 解析JSON
    std::string jsonStr = R"({"code":200,"message":"success","data":{"user_id":1,"token":"abc123"}})";
    json parsed = json::parse(jsonStr);

    std::cout << "[解析结果]\n";
    std::cout << "  code: " << parsed["code"].get_int() << "\n";
    std::cout << "  message: " << parsed["message"].get_string() << "\n";
    std::cout << "  user_id: " << parsed["data"]["user_id"].get_uint64() << "\n";

    std::cout << "\nJSON测试通过!\n";
}

void testApi(const std::string& baseUrl, const std::string& appKey) {
    printSeparator("API测试");

    std::cout << "服务器: " << baseUrl << "\n";
    std::cout << "AppKey: " << appKey << "\n\n";

    VerifyClient client(baseUrl, appKey);

    // 测试获取应用信息
    std::cout << "[测试] 获取应用信息...\n";
    try {
        json info = client.getAppInfo();
        if (info["code"].get_int() == 200) {
            std::cout << "  [成功] 应用名称: " << info["data"]["name"].get_string() << "\n";
            std::cout << "  [成功] 状态: " << info["data"]["status"].get_string() << "\n";
        } else {
            std::cout << "  [错误] " << info["message"].get_string() << "\n";
        }
    } catch (const std::exception& e) {
        std::cout << "  [异常] " << e.what() << "\n";
    }

    // 测试检查更新
    std::cout << "\n[测试] 检查更新...\n";
    try {
        json update = client.checkUpdate("1.0.0");
        if (update["code"].get_int() == 200) {
            std::cout << "  [成功] 最新版本: " << update["data"]["latest_version"].get_string() << "\n";
            std::cout << "  [成功] 有更新: " << (update["data"]["has_update"].get_bool() ? "是" : "否") << "\n";
        } else {
            std::cout << "  [错误] " << update["message"].get_string() << "\n";
        }
    } catch (const std::exception& e) {
        std::cout << "  [异常] " << e.what() << "\n";
    }

    // 测试不存在的版本
    std::cout << "\n[测试] 检查不存在的版本...\n";
    try {
        json update = client.checkUpdate("99.99.99");
        if (update["code"].get_int() == 200) {
            std::cout << "  [意外成功]\n";
        } else {
            std::cout << "  [预期错误] " << update["message"].get_string() << "\n";
        }
    } catch (const std::exception& e) {
        std::cout << "  [预期异常] " << e.what() << "\n";
    }

    // 测试登录
    std::cout << "\n[测试] 用户登录...\n";
    try {
        // 使用测试用户
        json loginResult = client.login("test_cpp_user", "test123456", "cpp_test_device");
        if (loginResult["code"].get_int() == 200) {
            std::cout << "  [成功] 用户ID: " << loginResult["data"]["user_id"].get_uint64() << "\n";
            std::cout << "  [成功] Token已获取\n";

            uint64_t userId = loginResult["data"]["user_id"].get_uint64();

            // 测试心跳
            std::cout << "\n[测试] 心跳上报...\n";
            json heartbeat = client.heartbeat(userId, "cpp_test_device", "instance_001");
            if (heartbeat["code"].get_int() == 200) {
                std::cout << "  [成功] 心跳成功\n";
                if (heartbeat["data"].contains("balance")) {
                    std::cout << "  [信息] 余额: " << heartbeat["data"]["balance"].get_double() << "\n";
                }
            }
        } else {
            std::cout << "  [错误] " << loginResult["message"].get_string() << "\n";
        }
    } catch (const std::exception& e) {
        std::cout << "  [异常] " << e.what() << "\n";
    }

    // 测试卡密充值（预期失败）
    std::cout << "\n[测试] 卡密充值（无效卡密）...\n";
    try {
        json recharge = client.recharge("admin", "invalid_card_key", "cpp_test_device");
        if (recharge["code"].get_int() == 200) {
            std::cout << "  [意外成功] 充值成功\n";
        } else {
            std::cout << "  [预期错误] " << recharge["message"].get_string() << "\n";
        }
    } catch (const std::exception& e) {
        std::cout << "  [预期异常] " << e.what() << "\n";
    }
}

// ============================================================================
// 主函数
// ============================================================================
int main(int argc, char* argv[]) {
    std::cout << R"(
╔════════════════════════════════════════════════════════════╗
║         验证平台 SDK C++ 独立测试                          ║
║         Verify Platform SDK C++ Test                       ║
╚════════════════════════════════════════════════════════════╝
)" << "\n";

    // 配置
    std::string baseUrl = "https://gendan.xyz";
    std::string appKey = "your_app_key";  // 替换为实际的appKey

    // 解析命令行参数
    for (int i = 1; i < argc; ++i) {
        std::string arg = argv[i];
        if (arg == "--help" || arg == "-h") {
            std::cout << "用法: " << argv[0] << " [选项]\n";
            std::cout << "选项:\n";
            std::cout << "  --help, -h       显示帮助信息\n";
            std::cout << "  --url <URL>      设置服务器URL\n";
            std::cout << "  --key <APPKEY>   设置应用密钥\n";
            std::cout << "  --json-only      仅测试JSON功能\n";
            return 0;
        } else if (arg == "--url" && i + 1 < argc) {
            baseUrl = argv[++i];
        } else if (arg == "--key" && i + 1 < argc) {
            appKey = argv[++i];
        } else if (arg == "--json-only") {
            testJson();
            return 0;
        }
    }

    try {
        // JSON测试
        testJson();

        // API测试
        testApi(baseUrl, appKey);

        std::cout << "\n========================================\n";
        std::cout << "所有测试完成!\n";
        std::cout << "========================================\n";

    } catch (const std::exception& e) {
        std::cerr << "\n错误: " << e.what() << "\n";
        return 1;
    }

    return 0;
}
