#include "KMFormatter.h"

KMFormatter::KMFormatter()
{
}

KMFormatter::~KMFormatter()
{
}

std::string KMFormatter::truncate(const std::string &str, size_t width)
{
    // 判断字符宽度，如果宽度超出则截断并添加 "..."
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wstr = converter.from_bytes(str);
    size_t len = 0;
    std::wstring truncated;

    for (wchar_t ch : wstr)
    {
        // 中文字符宽度大于1, 英文宽度为1
        len += (ch > 127) ? 2 : 1;

        // 减去4，是因为中文字符占两个宽度，减去4后，可以保证中文字符不会被截断
        if (len <= width - 4)
        {
            truncated += ch;
        }
        else
        {
            truncated += L"...";
            break;
        }
    }
    return converter.to_bytes(truncated);
}

std::string KMFormatter::pad(const std::string &str, size_t width)
{
    // 获取实际宽度，考虑到中英文混排问题
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wstr = converter.from_bytes(str);
    size_t len = 0;

    for (wchar_t ch : wstr)
    {
        len += (ch > 127) ? 2 : 1; // 中文宽度2，英文宽度1
    }

    std::string padded = str;
    if (len < width)
    {
        padded.append(width - len, ' ');
    }
    return padded;
}

void KMFormatter::setColumnWidth(size_t idW, size_t nameW, size_t versionW, size_t archW, size_t channelW, size_t moduleW, size_t descriptionW, size_t sizeW)
{
    idWidth = idW;
    nameWidth = nameW;
    versionWidth = versionW;
    archWidth = archW;
    channelWidth = channelW;
    moduleWidth = moduleW;
    descriptionWidth = descriptionW;
    sizeWidth = sizeW;
}

std::string KMFormatter::getColumnHead(const std::string &column)
{
    std::string head = column;
    return head;
}

void KMFormatter::printHeader()
{
    // ANSI 转义序列，用于设置文本颜色为黄色
    const std::string yellow = "\033[1;33m";
    // ANSI 转义序列，用于重置文本颜色
    const std::string reset = "\033[0m";

    std::cout << std::left << yellow << std::setw(idWidth) << getColumnHead("id") << std::setw(nameWidth) << getColumnHead("name") << std::setw(versionWidth) << getColumnHead("version");

    if (showArch)
    {
        std::cout << std::setw(archWidth) << getColumnHead("arch");
    }

    if (showChannel)
    {
        std::cout << std::setw(channelWidth) << getColumnHead("channel");
    }

    if (showSize)
    {
        std::cout << std::setw(sizeWidth) << getColumnHead("size");
    }

    std::cout << std::setw(moduleWidth) << getColumnHead("module") << std::setw(descriptionWidth) << getColumnHead("description") << reset << std::endl;
}

void KMFormatter::printEntry(const KMEntry &entry)
{
    // 逐列输出，确保中文字符对齐
    std::cout << pad(truncate(entry.id, idWidth), idWidth) << pad(truncate(entry.name, nameWidth), nameWidth) << pad(truncate(entry.version, versionWidth), versionWidth);
    if (showArch)
    {
        std::cout << pad(truncate(entry.arch, archWidth), archWidth);
    }

    if (showChannel)
    {
        std::cout << pad(truncate(entry.channel, channelWidth), channelWidth);
    }

    if (showSize)
    {
        std::cout << pad(truncate(entry.size, sizeWidth), sizeWidth);
    }

    std::cout << pad(truncate(entry.module, moduleWidth), moduleWidth) << pad(truncate(entry.description, descriptionWidth), descriptionWidth) << std::endl;
}

void KMFormatter::printEntries(const std::vector<KMEntry> &entries)
{
    printHeader();
    for (const auto &entry : entries)
    {
        printEntry(entry);
    }
}

void KMFormatter::setShowChannel(bool show)
{
    showChannel = show;
}

void KMFormatter::setShowArch(bool show)
{
    showArch = show;
}

void KMFormatter::setShowSize(bool show)
{
    showSize = show;
}

void KMFormatter::printFooter()
{
    std::cout << std::endl;
}
