#include <switch.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
#include <mbedtls/md5.h>
#include <ctime>
#include <string>
// #include <vector>  // 未使用的头文件，已注释掉
// #include <iostream>  // 未使用的头文件，已注释掉

// 向前声明
std::string calculateMD5(const std::string& input);
std::string urlEncode(const std::string& str);
static size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* userp);
std::string parseTranslationResult(const std::string& jsonResponse, const std::string& text);

/**
 * @brief 计算字符串的 MD5 哈希值
 * @param input 输入字符串
 * @return MD5 哈希值（十六进制字符串）
 */
std::string calculateMD5(const std::string& input) {
    mbedtls_md5_context ctx;
    mbedtls_md5_init(&ctx);
    mbedtls_md5_starts_ret(&ctx);
    mbedtls_md5_update_ret(&ctx, (const u8*)input.c_str(), input.length());
    
    u8 hash[16];
    mbedtls_md5_finish_ret(&ctx, hash);
    mbedtls_md5_free(&ctx);
    
    char str[33]; // 16字节 * 2 + 1（终止符）
    for (u32 i = 0; i < sizeof(hash); i++) {
        std::sprintf(str + i * 2, "%02x", hash[i]);
    }
    str[32] = '\0'; // 确保终止符
    
    return std::string(str);
}

/**
 * @brief URL 编码函数
 * @param str 输入字符串
 * @return URL 编码后的字符串
 */
std::string urlEncode(const std::string& str) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        return str;
    }

    char* encoded = curl_easy_escape(curl, str.c_str(), str.length());
    std::string result;
    if (encoded) {
        result = encoded;
        curl_free(encoded);
    }
    curl_easy_cleanup(curl);

    return result;
}

/**
 * @brief libcurl 写入回调函数
 * @param contents 接收到的数据
 * @param size 数据块大小
 * @param nmemb 数据块数量
 * @param userp 用户指针，用于存储数据
 * @return 实际写入的字节数
 */
static size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
    size_t realSize = size * nmemb;
    userp->append((char*)contents, realSize);
    return realSize;
}

/**
 * @brief 解码 Unicode 转义序列
 * @param str 包含 Unicode 转义序列的字符串
 * @return 解码后的字符串
 */
std::string decodeUnicodeEscapes(const std::string& str) {
    std::string result;
    size_t pos = 0;
    while (pos < str.length()) {
        // 处理两种格式的Unicode转义: \uXXXX 和 uXXXX
        bool hasBackslash = false;
        if (pos + 5 <= str.length() && str[pos] == '\\' && str[pos+1] == 'u') {
            hasBackslash = true;
        } else if (pos + 4 <= str.length() && str[pos] == 'u') {
            hasBackslash = false;
        } else {
            // 普通字符
            result += str[pos];
            pos++;
            continue;
        }

        // 解析 Unicode 转义序列
        std::string hexStr;
        if (hasBackslash) {
            hexStr = str.substr(pos + 2, 4);
        } else {
            hexStr = str.substr(pos + 1, 4);
        }

        // 使用strtoul代替stoi以避免异常处理和新头文件
        char* endPtr;
        unsigned long codePoint = std::strtoul(hexStr.c_str(), &endPtr, 16);

        // 检查转换是否成功 (确保所有4个字符都被解析)
        if (endPtr == hexStr.c_str() + 4) {
            // 检查码点是否在有效Unicode范围内 (0-0x10FFFF)
            if (codePoint <= 0x10FFFF) {
                if (codePoint <= 0xFFFF) {
                    // BMP 字符 - 转换为 UTF-8 编码
                    if (codePoint <= 0x7F) {
                        // 1字节 UTF-8
                        result += static_cast<char>(codePoint);
                    } else if (codePoint <= 0x7FF) {
                        // 2字节 UTF-8
                        result += static_cast<char>(0xC0 | (codePoint >> 6));
                        result += static_cast<char>(0x80 | (codePoint & 0x3F));
                    } else {
                        // 3字节 UTF-8
                        result += static_cast<char>(0xE0 | (codePoint >> 12));
                        result += static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F));
                        result += static_cast<char>(0x80 | (codePoint & 0x3F));
                    }
                } else {
                    // 非 BMP 字符 - 转换为 4字节 UTF-8
                    result += static_cast<char>(0xF0 | (codePoint >> 18));
                    result += static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F));
                    result += static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F));
                    result += static_cast<char>(0x80 | (codePoint & 0x3F));
                }
            } else {
                // 码点超出Unicode范围，按解析失败处理
                result += str[pos];
                
                // 根据格式跳过相应字符
                if (hasBackslash) {
                    pos += 6; // 跳过 \uXXXX
                } else {
                    pos += 5; // 跳过 uXXXX
                }
                continue;
            }

            // 有效码点处理完成，跳过相应字符
            if (hasBackslash) {
                pos += 6; // 跳过 \uXXXX
            } else {
                pos += 5; // 跳过 uXXXX
            }
        } else {
            // 解析失败，保留原字符
            result += str[pos];
            pos++;
        }
    }
    return result;
}

/**
 * @brief 解析百度翻译 API 返回的 JSON 结果
 * @param jsonResponse JSON 响应字符串
 * @return 翻译后的文本
 */
std::string parseTranslationResult(const std::string& jsonResponse, const std::string& text) {
    // 简单解析 JSON，实际项目中应该使用 JSON 库
    // 查找翻译结果的位置
    size_t transStart = jsonResponse.find("\"dst\":\"", 0);
    if (transStart == std::string::npos) {
        return "翻译失败: 无法找到翻译结果\n" + text;
    }

    transStart += 7; // 跳过 "dst":"" (正确跳过7个字符，避免丢失第一个翻译字符)
    size_t transEnd = jsonResponse.find("\"", transStart);
    if (transEnd == std::string::npos) {
        return "翻译失败: 翻译结果格式不正确\n" + text;
    }

    // 提取翻译结果
    std::string encodedResult = jsonResponse.substr(transStart, transEnd - transStart);

    // 合并处理：移除换行符前的反斜杠和替换 \/ 为"\"
    size_t pos = 0;
    while (true) {
        // 查找需要处理的特殊模式
        size_t newLinePos = encodedResult.find('\n', pos);
        size_t escapedNewLinePos = encodedResult.find('\\n', pos);
        size_t slashPos = encodedResult.find("\\/", pos);

        // 确定哪个模式最先出现
        size_t nextPos = std::string::npos;
        if (newLinePos != std::string::npos) nextPos = newLinePos;
        if (escapedNewLinePos != std::string::npos && (nextPos == std::string::npos || escapedNewLinePos < nextPos)) nextPos = escapedNewLinePos;
        if (slashPos != std::string::npos && (nextPos == std::string::npos || slashPos < nextPos)) nextPos = slashPos;

        if (nextPos == std::string::npos) {
            break; // 没有找到更多需要处理的模式
        }

        pos = nextPos;

        // 处理找到的模式
        if (pos == newLinePos || pos == escapedNewLinePos) {
            // 处理换行符前的反斜杠
            bool deletedBackslash = false;
            if (pos > 0 && encodedResult[pos - 1] == '\\') {
                encodedResult.erase(pos - 1, 1);
                pos--; // 调整pos位置，因为我们删除了一个字符
                deletedBackslash = true;
            }
            // 移动到下一个位置
            if (pos == newLinePos) {
                pos += 1; // 普通换行符，跳过1个字符
            } else {
                // 转义换行符(\\n)，确保不会丢失'n'
                if (deletedBackslash && pos < encodedResult.length() && encodedResult[pos] == 'n') {
                    pos += 1; // 只跳过'n'字符
                } else {
                    pos += 2; // 未删除反斜杠，跳过两个字符
                }
            }
        } else if (pos == slashPos) {
            // 处理 \/ 替换为 \“
            encodedResult.replace(pos, 2, "\\");
            pos += 1; // 移动到替换后的位置
        }
    }

    // 移除字符串末尾可能的反斜杠
    if (!encodedResult.empty() && encodedResult.back() == '\\') {
        encodedResult.pop_back();
    }

    // 解码 Unicode 转义序列
    return decodeUnicodeEscapes(encodedResult);
}

/**
 * @brief 使用百度翻译 API 翻译文本
 * @param appid 百度翻译 API 的 AppID
 * @param secretKey 百度翻译 API 的 密钥
 * @param text 要翻译的文本（英文）
 * @return 翻译后的文本（中文）
 */
// 原代码: std::string translateText(const std::string& appid, const std::string& secretKey, const std::string& text) {
std::string translateText(const std::string& appid1, const std::string& secretkey1, const std::string& text) {
    // 生成随机 salt
    srand(time(nullptr));
    int salt = rand();
    std::string saltStr = std::to_string(salt);

    // 计算签名
    // 原代码: std::string signStr = appid + text + saltStr + secretKey;
    std::string signStr = appid1 + text + saltStr + secretkey1;
    std::string sign = calculateMD5(signStr);

    // 构建 URL
    std::string baseUrl = "http://api.fanyi.baidu.com/api/trans/vip/translate?";
    std::string encodedText = urlEncode(text);

    std::string url = baseUrl +
                      // 原代码: "appid=" + appid +
                      "appid=" + appid1 +
                      "&q=" + encodedText +
                      "&from=en" +
                      "&to=zh" +
                      "&salt=" + saltStr +
                      "&sign=" + sign;

    // 初始化 libcurl
    CURL* curl = curl_easy_init();
    if (!curl) {
        return "翻译失败: 无法初始化 curl\n" + text;
    }

    // 设置 curl 选项
    std::string responseString;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseString);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); // 设置超时时间为 5 秒

    // 执行请求
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        curl_easy_cleanup(curl);
        // 如果是超时错误，返回原文
        if (res == CURLE_OPERATION_TIMEDOUT) {
            return "翻译失败（网络超时）:\n " + text;
        }
        std::string error = "翻译失败（未知原因）:\n " + std::string(curl_easy_strerror(res)) + "\n" + text;
        return error;
    }

    // 清理 curl
    curl_easy_cleanup(curl);

    // 解析结果
    return parseTranslationResult(responseString, text);
}

/**
 * @brief 翻译功能的简单包装
 * @param appid1 百度翻译 API 的 AppID
 * @param secretkey1 百度翻译 API 的 密钥
 * @param text 要翻译的英文文本
 * @return 翻译后的中文文本
 */
// 原代码：std::string translate(const std::string& text) {
std::string translate(const std::string& appid1, const std::string& secretkey1, const std::string& text) {
    // 检测文本是否包含中文 (只检查前20个字节，不足20字节则检查全部)
    size_t checkLength = std::min(text.length(), static_cast<size_t>(20));
    for (size_t i = 0; i < checkLength; ++i) {
        char c = text[i];
        if ((unsigned char)c >= 0xE0) {
            // 检测到可能是中文字符的起始字节，直接返回原文本
            return text;
        }
    }

    // 未检测到中文字符，继续翻译流程

    return translateText(appid1, secretkey1, text);
}