#ifndef DEVICE_CTRL_STR_UTIL_H
#define DEVICE_CTRL_STR_UTIL_H
#include <iomanip>
#include <regex>
#include <sstream>
#include <string>
#include <vector>
#include <unicode/ucnv.h>
#include <unicode/ustring.h>

namespace zsy::StrUtil
{
    inline std::string toHex(const uint64_t value, const int width = 2, const bool uppercase = true)
    {
        std::stringstream ss;

        ss << std::hex;
        if (uppercase) ss << std::uppercase;
        if (width > 0) ss << std::setw(width) << std::setfill('0');

        ss << value;
        return ss.str();
    }

    inline std::string toHex(const std::vector<uint8_t> &data)
    {
        std::string dataStr;
        for (const uint8_t value: data)
        {
            dataStr += " " + toHex(value);
        }
        return dataStr;
    }

    inline std::vector<std::string> split(const std::string &str, const std::string &regex_pattern)
    {
        std::vector<std::string> result;
        if (str.empty())
        {
            return result;
        }

        const std::regex regex(regex_pattern);
        std::sregex_token_iterator it(str.begin(), str.end(), regex, -1);

        for (const std::sregex_token_iterator end; it != end; ++it)
        {
            result.emplace_back(*it);
        }

        return result;
    }

        // UTF-8字符串转宽字符串
    inline std::wstring str_a_w(const std::string &astr, const char *encode = "UTF-8")
    {
        UErrorCode status = U_ZERO_ERROR;

        // 使用unique_ptr管理转换器资源，确保异常安全
        std::unique_ptr<UConverter, decltype(&ucnv_close)> converter(
            ucnv_open(encode, &status),
            &ucnv_close
        );

        if (U_FAILURE(status))
        {
            throw std::runtime_error("Failed to open converter: " + std::to_string(status));
        }

        // 第一阶段：获取所需缓冲区大小
        status = U_ZERO_ERROR;
        int32_t targetCapacity = ucnv_toUChars(
            converter.get(), nullptr, 0, astr.c_str(),
            static_cast<int32_t>(astr.length()), &status
        );

        if (status != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(status))
        {
            throw std::runtime_error("Failed to calculate target length: " + std::to_string(status));
        }

        // 分配足够空间
        std::vector<UChar> buffer;
        try
        {
            buffer.resize(targetCapacity);
        } catch (const std::bad_alloc &)
        {
            throw std::runtime_error("Memory allocation failed");
        }

        // 第二阶段：实际转换
        status = U_ZERO_ERROR;
        int32_t actualLength = ucnv_toUChars(
            converter.get(),
            buffer.data(),
            targetCapacity,
            astr.c_str(),
            static_cast<int32_t>(astr.length()),
            &status
        );

        if (U_FAILURE(status))
        {
            throw std::runtime_error("Conversion failed: " + std::to_string(status));
        }

        // 转换为wstring，考虑平台差异
        std::wstring result;

        static_assert(sizeof(wchar_t) == sizeof(UChar), "wchar_t size mismatch on Windows");
        result.assign(reinterpret_cast<const wchar_t *>(buffer.data()), actualLength);

        return result;
    }

    // 宽字符串转UTF-8字符串
    inline std::string str_w_a(const std::wstring &wstr, const char *encode = "UTF-8")
    {
        UErrorCode status = U_ZERO_ERROR;

        // 使用unique_ptr管理转换器资源，确保异常安全
        const std::unique_ptr<UConverter, decltype(&ucnv_close)> converter(
            ucnv_open(encode, &status),
            &ucnv_close
        );

        if (U_FAILURE(status))
        {
            throw std::runtime_error("Failed to open converter");
        }

        // 安全的类型转换 - 假设wchar_t在Windows上是UTF-16，在其他平台可能需要不同处理
        static_assert(sizeof(wchar_t) == sizeof(UChar) || sizeof(wchar_t) == sizeof(UChar32),
                      "wchar_t size not compatible with ICU UChar types");

        const auto *ustr = reinterpret_cast<const UChar *>(wstr.c_str());
        const auto srcLength = static_cast<int32_t>(wstr.length());

        // 第一阶段：获取所需缓冲区大小
        status = U_ZERO_ERROR;
        int32_t targetCapacity = ucnv_fromUChars(
            converter.get(), nullptr, 0, ustr, srcLength, &status
        );

        if (status != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(status))
        {
            throw std::runtime_error("Failed to calculate target length: " + std::to_string(status));
        }

        // 分配足够空间 (+1不是必须的，因为ucnv_fromUChars不包含null终止符)
        std::string result;
        try
        {
            result.resize(targetCapacity);
        } catch (const std::bad_alloc &)
        {
            throw std::runtime_error("Memory allocation failed");
        }

        // 第二阶段：实际转换
        status = U_ZERO_ERROR;
        int32_t actualLength = ucnv_fromUChars(
            converter.get(),
            &result[0],
            targetCapacity,
            ustr,
            srcLength,
            &status
        );

        if (U_FAILURE(status))
        {
            throw std::runtime_error("Conversion failed: " + std::to_string(status));
        }

        // 调整大小为实际转换后的长度
        result.resize(actualLength);

        return result;
    }

    // UTF-8字符串转宽字符串
    inline std::shared_ptr<wchar_t[]> ch_a_w(const char *ach)
    {
        if (ach == nullptr) return nullptr;

        std::string astr(ach);
        std::wstring wstr = str_a_w(astr);

        size_t size = wstr.size() + 1;
        auto result = std::make_shared<wchar_t[]>(size);
        wcscpy_s(result.get(), size, wstr.c_str());
        return result;
    }

    // 宽字符串转UTF-8字符串
    inline std::shared_ptr<char[]> ch_w_a(const wchar_t *wch)
    {
        if (wch == nullptr) return nullptr;

        std::wstring wstr(wch);
        std::string utf8 = str_w_a(wstr);

        size_t size = utf8.size() + 1;
        auto result = std::make_shared<char[]>(size);
        strcpy_s(result.get(), size, utf8.c_str());
        return result;
    }
}
#endif // DEVICE_CTRL_STR_UTIL_H
