import logging
import os
from datetime import datetime
from logging.handlers import TimedRotatingFileHandler

from utils.config_helper import ConfigHelper


class LoggerHelper:
    """
    日志辅助类，用于创建和提供日志记录器实例
    该类实现了单例模式，确保在整个应用程序中只有一个日志记录器实例被创建和使用
    """

    _instance = None
    config = ConfigHelper()
    _log_file_name = f"{config.get("logger.file_name", "log")}.log"
    _log_file_path = config.get("logger.file_path", "./logs")
    _log_level_string = config.get("logger.level", "INFO")

    def __new__(cls, *args, **kwargs):
        """
        实现单例模式，确保日志记录器仅被创建一次
        如果尚未创建实例，则创建并初始化日志记录器
        """
        if not cls._instance:
            cls._instance = super(LoggerHelper, cls).__new__(cls, *args, **kwargs)
            try:
                cls._instance._initialize_logger()
            except Exception as e:
                raise Exception(f"配置logger出错: {e}")
        return cls._instance

    @property
    def logger(self):
        return self._logger

    def _initialize_logger(self):
        """
        初始化日志记录器，包括设置日志级别、创建处理器和格式化器，并将它们组合起来
        """
        log_level = self._get_log_level()
        self._logger = logging.getLogger("app_logger")
        self._logger.setLevel(log_level)

        if not os.path.exists(self._log_file_path):
            os.makedirs(self._log_file_path)

        # 创建按日期分割的文件处理器
        file_handler = TimedRotatingFileHandler(
            os.path.join(self._log_file_path, self._log_file_name),
            when="midnight",
            interval=1,
            backupCount=7,
            encoding="utf-8",
        )
        file_handler.setLevel(log_level)

        # 创建控制台处理器
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.DEBUG)

        # 创建格式化器
        formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")

        # 将格式化器添加到处理器
        file_handler.setFormatter(formatter)
        console_handler.setFormatter(formatter)

        # 将处理器添加到日志记录器
        self._logger.addHandler(file_handler)
        self._logger.addHandler(console_handler)

    def _get_log_level(self):
        try:
            # 尝试将字符串转换为 logging 模块中的日志级别常量
            log_level = getattr(logging, self._log_level_string.upper())
            if not isinstance(log_level, int):
                raise ValueError
            return log_level
        except (AttributeError, ValueError):
            raise ValueError(
                f"配置logger出错: Unknown level: '{self._log_level_string}'"
            )

    @classmethod
    def get_logger(cls):
        """
        提供初始化后的日志记录器实例
        :return: 初始化后的日志记录器实例
        """
        if not cls._instance:
            cls._instance = cls()
        return cls._instance._logger

    @classmethod
    def clean_log_file(cls, day: int):
        if not os.path.exists(cls._log_file_path):
            return
        for filename in os.listdir(cls._log_file_path):
            if filename != cls._log_file_name and filename.startswith(
                cls._log_file_name
            ):
                try:
                    file_path = os.path.join(cls._log_file_path, filename)
                    file_time = datetime.strptime(
                        filename.replace(f"{cls._log_file_name}.", ""), "%Y-%m-%d"
                    )
                    if (datetime.now() - file_time).days > day:
                        os.remove(file_path)
                        cls.get_logger().info(f"  删除日志文件: {file_path}")
                except Exception as e:
                    cls.get_logger().error(f"删除日志文件出错: {filename} {e}")
