#include <curl/curl.h>
#include <cctype>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>

/*
=============================================================
  查询账户点数 Demo (C++版)

  功能说明：
  查询账户剩余点数（余额）

  使用方法：
  1. 确保已安装 g++ 和 libcurl 开发库
  2. 将下方的 APPKEY 替换为你自己的用户密钥
  3. 编译运行：
       g++ -std=c++11 QueryPoints.cpp -lcurl -o query_points
       ./query_points
=============================================================
*/

const std::string APPKEY = "你的appkey";
const std::string API_BASE = "http://api.ttocr.com/api";

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    size_t total = size * nmemb;
    static_cast<std::string*>(userp)->append(static_cast<char*>(contents), total);
    return total;
}

std::string Trim(const std::string& input) {
    size_t start = 0;
    while (start < input.size() && std::isspace(static_cast<unsigned char>(input[start]))) {
        ++start;
    }

    size_t end = input.size();
    while (end > start && std::isspace(static_cast<unsigned char>(input[end - 1]))) {
        --end;
    }

    return input.substr(start, end - start);
}

std::string StripQuotes(const std::string& input) {
    if (input.size() >= 2 && input.front() == '"' && input.back() == '"') {
        return input.substr(1, input.size() - 2);
    }
    return input;
}

std::string ExtractJsonValue(const std::string& json, const std::string& key) {
    std::string needle = "\"" + key + "\"";
    size_t keyPos = json.find(needle);
    if (keyPos == std::string::npos) {
        return "";
    }

    size_t colon = json.find(':', keyPos + needle.size());
    if (colon == std::string::npos) {
        return "";
    }

    size_t pos = colon + 1;
    while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
        ++pos;
    }

    bool inString = false;
    bool escaped = false;
    int braceDepth = 0;
    int bracketDepth = 0;
    size_t end = pos;

    for (; end < json.size(); ++end) {
        char ch = json[end];
        if (inString) {
            if (escaped) {
                escaped = false;
                continue;
            }
            if (ch == '\\') {
                escaped = true;
                continue;
            }
            if (ch == '"') {
                inString = false;
            }
            continue;
        }

        if (ch == '"') {
            inString = true;
            continue;
        }
        if (ch == '{') {
            ++braceDepth;
            continue;
        }
        if (ch == '}') {
            if (braceDepth == 0 && bracketDepth == 0) {
                break;
            }
            --braceDepth;
            continue;
        }
        if (ch == '[') {
            ++bracketDepth;
            continue;
        }
        if (ch == ']') {
            --bracketDepth;
            continue;
        }
        if (ch == ',' && braceDepth == 0 && bracketDepth == 0) {
            break;
        }
    }

    return Trim(json.substr(pos, end - pos));
}

bool IsSuccessStatus(const std::string& json) {
    return ExtractJsonValue(json, "status") == "1";
}

std::string HttpGet(const std::string& url) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        throw std::runtime_error("初始化 CURL 失败");
    }

    std::string response;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    CURLcode code = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    if (code != CURLE_OK) {
        throw std::runtime_error(curl_easy_strerror(code));
    }

    return response;
}

int main() {
    std::cout << "************************************************************" << std::endl;
    std::cout << "  查询账户点数 Demo (C++版)" << std::endl;
    std::cout << "************************************************************" << std::endl;

    if (APPKEY == "你的appkey") {
        std::cout << "\n[错误] 请先在代码顶部的配置区域填写你的 APPKEY" << std::endl;
        return 1;
    }

    curl_global_init(CURL_GLOBAL_DEFAULT);

    std::cout << "==================================================" << std::endl;
    std::cout << "[查询点数] 正在查询账户剩余点数..." << std::endl;
    std::cout << "==================================================" << std::endl;

    try {
        CURL* encoder = curl_easy_init();
        char* escaped = curl_easy_escape(encoder, APPKEY.c_str(), static_cast<int>(APPKEY.size()));
        std::string url = API_BASE + "/points?appkey=" + (escaped ? escaped : "");
        if (escaped) {
            curl_free(escaped);
        }
        curl_easy_cleanup(encoder);

        std::string result = HttpGet(url);
        if (IsSuccessStatus(result)) {
            std::cout << "[成功] 查询成功！当前可用点数：" << StripQuotes(ExtractJsonValue(result, "points")) << std::endl;
        } else {
            std::cout << "[失败] 查询失败，错误信息：" << StripQuotes(ExtractJsonValue(result, "msg")) << std::endl;
            std::cout << "[提示] 错误状态码：" << ExtractJsonValue(result, "status") << "，请参考错误代码表排查" << std::endl;
        }
        std::cout << "[完整响应] " << result << std::endl;
    } catch (const std::exception& error) {
        std::cout << "[异常] 网络请求出错：" << error.what() << std::endl;
        curl_global_cleanup();
        return 1;
    }

    curl_global_cleanup();

    std::cout << "\n==================================================" << std::endl;
    std::cout << "[完成] 查询执行完毕" << std::endl;
    std::cout << "==================================================" << std::endl;
    return 0;
}
