#include "utils.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <ctime>
#include <fstream>
#include <algorithm>
#include <stdexcept>

// 实现 splitByDelimiter 方法
std::pair<std::string, std::string> StringUtils::splitByDelimiter(
    const std::string &str,
    char delimiter)
{
    size_t pos = str.find(delimiter);

    if (pos != std::string::npos)
    {
        // 找到分隔符，拆分字符串
        std::string first = str.substr(0, pos);
        std::string second = str.substr(pos + 1);
        return std::make_pair(first, second);
    }

    // 未找到分隔符，返回原始字符串和空字符串
    return std::make_pair(str, "");
}

// 实现 splitA_B 方法
std::pair<std::string, std::string> StringUtils::splitA_B(const std::string &str)
{
    return splitByDelimiter(str, '_');
}

// 实现 splitToTwoParts 方法
bool StringUtils::splitToTwoParts(
    const std::string &str,
    std::string &part1,
    std::string &part2,
    char delimiter)
{
    size_t pos = str.find(delimiter);

    if (pos != std::string::npos)
    {
        part1 = str.substr(0, pos);
        part2 = str.substr(pos + 1);
        return true; // 成功拆分
    }

    // 未找到分隔符
    part1 = str;
    part2 = "";
    return false; // 拆分失败
}

// 实现 splitStrict 方法
std::pair<std::string, std::string> StringUtils::splitStrict(
    const std::string &str,
    char delimiter)
{
    size_t pos = str.find(delimiter);

    // 检查是否找到分隔符
    if (pos == std::string::npos)
    {
        throw std::invalid_argument("Delimiter '" + std::string(1, delimiter) +
                                    "' not found in string: \"" + str + "\"");
    }

    // 检查是否有多于一个分隔符
    size_t nextPos = str.find(delimiter, pos + 1);
    if (nextPos != std::string::npos)
    {
        throw std::invalid_argument("Multiple delimiters '" + std::string(1, delimiter) +
                                    "' found in string: \"" + str + "\"");
    }

    std::string first = str.substr(0, pos);
    std::string second = str.substr(pos + 1);

    return std::make_pair(first, second);
}

namespace utils
{

    // Base64 字符表
    const std::string base64_chars =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz"
        "0123456789+/";

    // 判断字符是否为有效的 Base64 字符
    static bool is_base64(unsigned char c)
    {
        return (isalnum(c) || (c == '+') || (c == '/'));
    }

    std::string get_current_time()
    {
        auto now = std::chrono::system_clock::now();
        auto in_time_t = std::chrono::system_clock::to_time_t(now);
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                      now.time_since_epoch()) %
                  1000;

        std::stringstream ss;
        ss << std::put_time(std::gmtime(&in_time_t), "%Y-%m-%dT%H:%M:%S");
        ss << "." << std::setfill('0') << std::setw(3) << ms.count() << "Z";
        return ss.str();
    }

    std::string get_current_timestamp()
    {
        auto now = std::chrono::system_clock::now();
        auto in_time_t = std::chrono::system_clock::to_time_t(now);
        auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
                                now.time_since_epoch()) %
                            1000;

        std::stringstream ss;
        ss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %H:%M:%S");
        ss << '.' << std::setfill('0') << std::setw(3) << milliseconds.count();
        return ss.str();
    }

    // void setup_cors_headers(httplib::Response &res)
    // {
    //     res.set_header("Access-Control-Allow-Origin", "*");
    //     res.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH");
    //     res.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, X-API-Key, Accept, Origin");
    //     res.set_header("Access-Control-Expose-Headers", "Content-Length, Content-Type, X-Request-Id");
    //     res.set_header("Access-Control-Max-Age", "86400"); // 24 小时
    //     res.set_header("Vary", "Origin");
    // }

    json create_error_response(int code, const std::string &message, const std::string &details)
    {
        json response = {
            {"success", false},
            {"code", code},
            {"message", message},
            {"timestamp", get_current_time()}};

        if (!details.empty())
        {
            response["details"] = details;
        }

        return response;
    }

    json create_success_response(const json &data, const std::string &message)
    {
        return {
            {"success", true},
            {"code", 0},
            {"message", message},
            {"data", data},
            {"timestamp", get_current_time()}};
    }

    bool is_valid_utf8(const std::string &str)
    {
        for (size_t i = 0; i < str.size(); ++i)
        {
            unsigned char c = str[i];
            if (c <= 0x7F)
            {
                continue; // ASCII 字符
            }
            else if ((c & 0xE0) == 0xC0)
            {
                // 2 字节 UTF-8
                if (i + 1 >= str.size() || (str[i + 1] & 0xC0) != 0x80)
                {
                    return false;
                }
                i += 1;
            }
            else if ((c & 0xF0) == 0xE0)
            {
                // 3 字节 UTF-8
                if (i + 2 >= str.size() || (str[i + 1] & 0xC0) != 0x80 || (str[i + 2] & 0xC0) != 0x80)
                {
                    return false;
                }
                i += 2;
            }
            else if ((c & 0xF8) == 0xF0)
            {
                // 4 字节 UTF-8
                if (i + 3 >= str.size() || (str[i + 1] & 0xC0) != 0x80 ||
                    (str[i + 2] & 0xC0) != 0x80 || (str[i + 3] & 0xC0) != 0x80)
                {
                    return false;
                }
                i += 3;
            }
            else
            {
                return false; // 非法 UTF-8 字节
            }
        }
        return true;
    }

    std::string sanitize_utf8(const std::string &str)
    {
        std::string result;
        result.reserve(str.size());

        for (size_t i = 0; i < str.size(); ++i)
        {
            unsigned char c = str[i];
            if (c <= 0x7F)
            {
                result += c; // ASCII 字符
            }
            else if ((c & 0xE0) == 0xC0)
            {
                // 2 字节 UTF-8
                if (i + 1 < str.size() && (str[i + 1] & 0xC0) == 0x80)
                {
                    result += c;
                    result += str[i + 1];
                    i += 1;
                }
            }
            else if ((c & 0xF0) == 0xE0)
            {
                // 3 字节 UTF-8
                if (i + 2 < str.size() && (str[i + 1] & 0xC0) == 0x80 && (str[i + 2] & 0xC0) == 0x80)
                {
                    result += c;
                    result += str[i + 1];
                    result += str[i + 2];
                    i += 2;
                }
            }
            else if ((c & 0xF8) == 0xF0)
            {
                // 4 字节 UTF-8
                if (i + 3 < str.size() && (str[i + 1] & 0xC0) == 0x80 &&
                    (str[i + 2] & 0xC0) == 0x80 && (str[i + 3] & 0xC0) == 0x80)
                {
                    result += c;
                    result += str[i + 1];
                    result += str[i + 2];
                    result += str[i + 3];
                    i += 3;
                }
            }
            // 跳过非法 UTF-8 字节
        }
        return result;
    }

    json create_api_response(bool success, int code, const std::string &msg,
                             const std::string &req_code, const std::string &req_from,
                             const std::string &req_cmd, const json &res_data)
    {
        json response;
        response["success"] = success;
        response["code"] = code;
        response["msg"] = msg;
        response["req_code"] = req_code;
        response["req_from"] = req_from;
        response["req_cmd"] = req_cmd;
        response["timestamp"] = std::time(nullptr);

        if (!res_data.is_null())
        {
            response["res_data"] = res_data;
        }
        else
        {
            response["res_data"] = json::object();
        }

        return response;
    }

    // Base64 解码函数
    std::string base64_decode(const std::string &encoded_string)
    {
        int in_len = encoded_string.size();
        int i = 0;
        int j = 0;
        int in_ = 0;
        unsigned char char_array_4[4], char_array_3[3];
        std::string ret;

        // 去掉输入中的换行和空格
        std::string clean_encoded;
        for (char c : encoded_string)
        {
            if (c != '\n' && c != '\r' && c != ' ')
            {
                clean_encoded += c;
            }
        }
        in_len = clean_encoded.size();

        while (in_len-- && (clean_encoded[in_] != '=') && is_base64(clean_encoded[in_]))
        {
            char_array_4[i++] = clean_encoded[in_];
            in_++;
            if (i == 4)
            {
                for (i = 0; i < 4; i++)
                {
                    size_t pos = base64_chars.find(char_array_4[i]);
                    if (pos == std::string::npos)
                    {
                        throw std::runtime_error("Invalid base64 character");
                    }
                    char_array_4[i] = pos;
                }

                char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
                char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
                char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

                for (i = 0; i < 3; i++)
                {
                    ret += char_array_3[i];
                }
                i = 0;
            }
        }

        if (i)
        {
            for (j = i; j < 4; j++)
            {
                char_array_4[j] = 0;
            }

            for (j = 0; j < 4; j++)
            {
                size_t pos = base64_chars.find(char_array_4[j]);
                if (pos == std::string::npos && j >= i)
                {
                    // 补齐的占位字符按 0 处理
                    char_array_4[j] = 0;
                }
                else if (pos != std::string::npos)
                {
                    char_array_4[j] = pos;
                }
                else
                {
                    throw std::runtime_error("Invalid base64 character");
                }
            }

            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (j = 0; j < i - 1; j++)
            {
                ret += char_array_3[j];
            }
        }

        return ret;
    }

    // 将 Base64 编码的 URDF 转成字符串
    std::string base64_to_urdf(const std::string &base64_urdf)
    {
        try
        {
            std::string urdf_content = base64_decode(base64_urdf);

            // 校验解码结果是否像合法的 URDF/XML
            if (urdf_content.find("<?xml") != std::string::npos ||
                urdf_content.find("<robot") != std::string::npos)
            {
                return urdf_content;
            }
            else
            {
                throw std::runtime_error("Decoded content does not appear to be a valid URDF file");
            }
        }
        catch (const std::exception &e)
        {
            throw std::runtime_error(std::string("Failed to decode URDF: ") + e.what());
        }
    }

    // 将 Base64 编码的 URDF 保存到文件
    bool save_base64_urdf_to_file(const std::string &base64_urdf, const std::string &filename)
    {
        try
        {
            std::string urdf_content = base64_to_urdf(base64_urdf);
            return save_urdf_string_to_file(urdf_content, filename);
        }
        catch (const std::exception &e)
        {
            std::cerr << "Error saving base64 URDF to file: " << e.what() << std::endl;
            return false;
        }
    }

    // 将 URDF 字符串保存到文件
    bool save_urdf_string_to_file(const std::string &urdf_content, const std::string &filename)
    {
        try
        {
            std::ofstream out_file(filename);
            if (!out_file)
            {
                throw std::runtime_error("Cannot create output file: " + filename);
            }

            out_file << urdf_content;
            out_file.close();

            std::cout << "URDF file successfully saved to: " << filename << std::endl;
            std::cout << "File size: " << urdf_content.size() << " bytes" << std::endl;

            return true;
        }
        catch (const std::exception &e)
        {
            std::cerr << "Error saving URDF to file: " << e.what() << std::endl;
            return false;
        }
    }

    // 校验 Base64 字符串是否可解析为合法 URDF
    bool validate_urdf_base64(const std::string &base64_urdf)
    {
        try
        {
            std::string urdf_content = base64_to_urdf(base64_urdf);

            // 基础 URDF 结构校验
            bool has_xml_decl = urdf_content.find("<?xml") != std::string::npos;
            bool has_robot_tag = urdf_content.find("<robot") != std::string::npos;
            bool has_link_tag = urdf_content.find("<link") != std::string::npos;
            bool has_joint_tag = urdf_content.find("<joint") != std::string::npos;

            return has_robot_tag && (has_link_tag || has_joint_tag);
        }
        catch (...)
        {
            return false;
        }
    }

} // namespace utils
