#ifndef KMFORMATTER_H
#define KMFORMATTER_H

#include <iostream>
#include <iomanip>
#include <vector>
#include <regex>
#include <locale>
#include <codecvt>
#include <string>

typedef struct KMEntry
{
    std::string id;
    std::string name;
    std::string version;
    std::string arch;
    std::string channel;
    std::string module;
    std::string description;
    std::string size;
} KMEntry;

class KMFormatter
{
public:
    KMFormatter();
    ~KMFormatter();

    /**
     * @brief 截断字符串，如果宽度超出则截断并添加 "..." 
     * 
     * @param str 待截断的字符串
     * @param width 截断宽度
     * @return std::string 截断后的字符串
     */
    static std::string truncate(const std::string &str, size_t width);

    /**
     * @brief 填充字符串，如果宽度超出则截断并添加 "..." 
     * 
     * @param str 待填充的字符串
     * @param width 填充宽度
     * @return std::string 填充后的字符串
     */
    static std::string pad(const std::string &str, size_t width);
    

    /**
     * @brief 设置列宽度
     * 
     * @param idW id 列宽度
     * @param nameW name 列宽度
     * @param versionW version 列宽度
     * @param archW arch 列宽度
     * @param channelW channel 列宽度
     * @param moduleW module 列宽度
     * @param descriptionW description 列宽度
     */
    void 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);

    /**
     * @brief 获取列头
     * 
     * @param column 列名
     * @return std::string 列头
     */
    std::string getColumnHead(const std::string &column);

    /**
     * @brief 打印表头
     */
    void printHeader();

    /**
     * @brief 打印单个条目
     * 
     * @param entry 条目
     */
    void printEntry(const KMEntry &entry);

    /**
     * @brief 打印多个条目
     * 
     * @param entries 条目列表
     */
    void printEntries(const std::vector<KMEntry> &entries);

    /**
     * @brief 设置是否显示 channel 列
     * 
     * @param show 是否显示
     */ 
    void setShowChannel(bool show);

    /**
     * @brief 设置是否显示 arch 列
     * 
     * @param show 是否显示
     */
    void setShowArch(bool show);

    /**
     * @brief 设置是否显示 size 列
     * 
     * @param show 是否显示
     */
    void setShowSize(bool show);

    /**
     * @brief 打印表尾
     * 
     */
    void printFooter();

private:
    size_t idWidth = 35;          // id 列宽度
    size_t nameWidth = 35;        // name 列宽度
    size_t versionWidth = 15;     // version 列宽度
    size_t archWidth = 10;        // arch 列宽度
    size_t channelWidth = 15;     // channel 列宽度
    size_t moduleWidth = 12;      // module 列宽度
    size_t descriptionWidth = 30; // description 列宽度
    size_t sizeWidth = 10;        // size 列宽度

    bool showChannel = true; // 是否显示 channel 列
    bool showArch = true;    // 是否显示 arch 列
    bool showSize = true;    // 是否显示 size 列
};

#endif