#ifndef ASYNC_LOGGER_H
#define ASYNC_LOGGER_H

// 定义 _WIN32_WINNT 以支持 Windows 10/11 API
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#endif

#include <spdlog/spdlog.h>
#include <spdlog/async.h>                      // 异步日志支持
#include <spdlog/sinks/stdout_color_sinks.h>     // 彩色终端输出
#include <memory>
#include <chrono>

// --------------------------------------------------------------------
// 为 Boost 类型提供自定义格式化器
#include <boost/asio/ip/basic_endpoint.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/system/error_code.hpp>
#include <boost/beast/core.hpp> // 包含 boost::beast::error_code

namespace fmt {
    template<typename Protocol>
    struct formatter<boost::asio::ip::basic_endpoint<Protocol>> {
        // 无需额外格式说明符
        constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
        template<typename FormatContext>
        auto format(const boost::asio::ip::basic_endpoint<Protocol>& ep, FormatContext& ctx) {
            return format_to(ctx.out(), "{}:{}", ep.address().to_string(), ep.port());
        }
    };
}
// --------------------------------------------------------------------

namespace logger {

    inline void init_async_logger() {
        // 使用 spdlog 官方推荐方法初始化全局线程池（队列大小 8192，线程数 1）
        spdlog::init_thread_pool(8192, 1);

        // 创建终端输出的 sink，并设置日志格式
        // 格式说明：
        //   %Y-%m-%d %H:%M:%S.%e  => 时间戳（毫秒级精度）
        //   [%5l]                => 日志级别（固定宽度 5，如 [INFO ]）
        //   [%n]                 => logger 名称（本例设为 "main"）
        //   %v                   => 日志内容
        // 输出示例：
        //   2025-03-11 16:00:20.043 [INFO ] [main]  com.incubator.game.GameServerStart - 正在启动游戏服务器...
        auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
        console_sink->set_pattern("%Y-%m-%d %H:%M:%S.%e [%5l] [%t] [%s %!:%#]  %v");

        // 使用 spdlog::thread_pool() 获取全局线程池
        auto async_logger = std::make_shared<spdlog::async_logger>(
            "main",                               // logger 名称
            console_sink,                         // 输出 sink
            spdlog::thread_pool(),                // 使用全局线程池
            spdlog::async_overflow_policy::block  // 队列满时阻塞，保证日志不丢失
        );

        // 将异步 logger 设为默认 logger，并设置日志等级及自动刷新策略
        spdlog::set_default_logger(async_logger);
        spdlog::set_level(spdlog::level::info);
        spdlog::flush_every(std::chrono::seconds(3));
    }

    // 在 main() 退出前手动调用，确保日志系统干净关闭
    inline void shutdown_logger() {
        spdlog::shutdown();
        spdlog::thread_pool().reset();  // 显式释放线程池
    }

} // namespace logger

#endif // ASYNC_LOGGER_H
