#ifndef TLOGGER_H
#define TLOGGER_H

#include <fstream>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>

// 前向声明Qt类型，避免在头文件中包含Qt
class QString;

namespace TC {
// 日志级别枚举
enum class LogLevel { DEBUG = 0, INFO = 1, WARNING = 2, ERROR = 3 };

// 日志输出接口
class LogOutput
{
public:
    virtual ~LogOutput() = default;
    virtual void write(LogLevel level, const std::string& message) = 0;
};

// 控制台输出
class ConsoleOutput : public LogOutput
{
public:
    void write(LogLevel level, const std::string& message) override;
};

// 文件输出
class FileOutput : public LogOutput
{
public:
    explicit FileOutput(const std::string& filename);
    ~FileOutput();
    void write(LogLevel level, const std::string& message) override;

private:
    std::ofstream m_file;
    std::mutex m_mutex;
};

// 主日志类
class Logger
{
public:
    static Logger& instance();

    // 设置日志级别
    void setLevel(LogLevel level);
    LogLevel getLevel() const;

    // 添加输出目标
    void addOutput(std::unique_ptr<LogOutput> output);
    void clearOutputs();

    // 日志记录方法
    void debug(const std::string& message);
    void info(const std::string& message);
    void warning(const std::string& message);
    void error(const std::string& message);

    // 格式化日志记录
    template<typename... Args>
    void debugf(const std::string& format, Args&&... args)
    {
        if (shouldLog(LogLevel::DEBUG)) {
            log(LogLevel::DEBUG, formatString(format, std::forward<Args>(args)...));
        }
    }

    template<typename... Args>
    void infof(const std::string& format, Args&&... args)
    {
        if (shouldLog(LogLevel::INFO)) {
            log(LogLevel::INFO, formatString(format, std::forward<Args>(args)...));
        }
    }

    template<typename... Args>
    void warningf(const std::string& format, Args&&... args)
    {
        if (shouldLog(LogLevel::WARNING)) {
            log(LogLevel::WARNING, formatString(format, std::forward<Args>(args)...));
        }
    }

    template<typename... Args>
    void errorf(const std::string& format, Args&&... args)
    {
        if (shouldLog(LogLevel::ERROR)) {
            log(LogLevel::ERROR, formatString(format, std::forward<Args>(args)...));
        }
    }

#ifdef QT_CORE_LIB
    // Qt兼容接口
    void qtDebug(const QString& message);
    void qtInfo(const QString& message);
    void qtWarning(const QString& message);
    void qtError(const QString& message);
#endif

    // 初始化方法（全局初始化时调用）
    static void initialize(const std::string& logFile = "av_log.txt",
                           LogLevel level = LogLevel::INFO,
                           bool enableConsole = true,
                           bool enableQt = true);

private:
    Logger() = default;
    ~Logger() = default;
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;

    void log(LogLevel level, const std::string& message);
    bool shouldLog(LogLevel level) const;
    std::string getCurrentTime() const;
    std::string levelToString(LogLevel level) const;

    template<typename... Args>
    std::string formatString(const std::string& format, Args&&... args)
    {
        std::ostringstream oss;
        formatImpl(oss, format, std::forward<Args>(args)...);
        return oss.str();
    }

    // 处理无参数情况的formatImpl重载
    void formatImpl(std::ostringstream& oss, const std::string& format) { oss << format; }

    template<typename T>
    void formatImpl(std::ostringstream& oss, const std::string& format, T&& value)
    {
        size_t pos = format.find("{}");
        if (pos != std::string::npos) {
            oss << format.substr(0, pos) << std::forward<T>(value) << format.substr(pos + 2);
        } else {
            oss << format;
        }
    }

    template<typename T, typename... Args>
    void formatImpl(std::ostringstream& oss, const std::string& format, T&& value, Args&&... args)
    {
        size_t pos = format.find("{}");
        if (pos != std::string::npos) {
            oss << format.substr(0, pos) << std::forward<T>(value);
            formatImpl(oss, format.substr(pos + 2), std::forward<Args>(args)...);
        } else {
            oss << format;
        }
    }

    LogLevel m_level = LogLevel::INFO;
    std::vector<std::unique_ptr<LogOutput>> m_outputs;
    mutable std::mutex m_mutex;
};
} // namespace TC

#define T_LOGGER_DEBUG(msg) TC::Logger::instance().debug(msg)
#define T_LOGGER_INFO(msg) TC::Logger::instance().info(msg)
#define T_LOGGER_WARNING(msg) TC::Logger::instance().warning(msg)
#define T_LOGGER_ERROR(msg) TC::Logger::instance().error(msg)

#define T_LOGGER_DEBUGF(fmt, ...) TC::Logger::instance().debugf(fmt, __VA_ARGS__)
#define T_LOGGER_INFOF(fmt, ...) TC::Logger::instance().infof(fmt, __VA_ARGS__)
#define T_LOGGER_WARNINGF(fmt, ...) TC::Logger::instance().warningf(fmt, __VA_ARGS__)
#define T_LOGGER_ERRORF(fmt, ...) TC::Logger::instance().errorf(fmt, __VA_ARGS__)

#endif // TLOGGER_H
