#ifndef QFORMATTER_H
#define QFORMATTER_H

#include <fmt/chrono.h>
#include <fmt/format.h>
#include <fmt/ranges.h>

#include <QByteArray>
#include <QColor>
#include <QDate>
#include <QProcess>
#include <QString>
#include <QTextCodec>

namespace fmt {
template<>
struct formatter<QString>
{
    constexpr auto parse(format_parse_context& ctx)
    {
        auto it = ctx.begin();
        if (it != ctx.end() && *it == '}')
            it++;
        return it;
    }
    template<typename Context>
    auto format(const QString& str, Context& ctx) const
    {
        QTextCodec* codec = QTextCodec::codecForName("GBK"); // 日文编码
        if (codec) {
            QByteArray bytes = codec->fromUnicode(str);
            return fmt::format_to(ctx.out(), "{}", bytes);
        }
        return fmt::format_to(ctx.out(), "{}", str.toUtf8());
    }
};
template<>
struct formatter<QByteArray> : formatter<std::string>
{
    template<typename FormatContext>
    auto format(const QByteArray& a, FormatContext& ctx) const
    {
        return format_to(ctx.out(), "{}", a.constData());
    }
};
template<>
struct fmt::formatter<QDate> : fmt::formatter<std::string>
{
    static auto format(const QDate& t, fmt::format_context& ctx)
    {
        return fmt::format_to(ctx.out(), "{}", t.toString(Qt::ISODate));
    }
};
template<>
struct fmt::formatter<QTime> : fmt::formatter<std::string>
{
    static auto format(const QTime& t, fmt::format_context& ctx)
    {
        return fmt::format_to(ctx.out(), "{}", t.toString(Qt::ISODate));
    }
};
template<>
struct fmt::formatter<QDateTime> : fmt::formatter<std::string>
{
    static auto format(const QDateTime& t, fmt::format_context& ctx)
    {
        return fmt::format_to(ctx.out(), "{}", t.toString(Qt::ISODate));
    }
};
template<>
struct fmt::formatter<QPoint> : fmt::formatter<std::string>
{
    static auto format(const QPoint& p, fmt::format_context& ctx)
    {
        return fmt::format_to(ctx.out(), "[{}, {}]", p.x(), p.y());
    }
};
template<>
struct fmt::formatter<QPointF> : fmt::formatter<std::string>
{
    static auto format(const QPointF& p, fmt::format_context& ctx)
    {
        return fmt::format_to(ctx.out(), "[{}, {}]", p.x(), p.y());
    }
};
template<>
struct fmt::formatter<QColor> : fmt::formatter<std::string>
{
    static auto format(const QColor& c, fmt::format_context& ctx)
    {
        return fmt::format_to(ctx.out(), "{}", c.name());
    }
};
} // namespace fmt

#endif // QFORMATTER_H
