"""
统一日志管理系统
提供结构化日志记录功能，支持不同日志级别、文件输出、轮转等
"""
import logging
import os
import sys
from datetime import datetime
from pathlib import Path
from logging.handlers import RotatingFileHandler
import json


class LoggerSetup:
    """日志系统配置类"""

    def __init__(self, name: str = "ai-chat-server", log_level: str = "INFO",
                 log_dir: str = "logs", max_bytes: int = 10 * 1024 * 1024, backup_count: int = 5):
        """
        初始化日志系统

        Args:
            name: 日志记录器名称
            log_level: 日志级别 ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
            log_dir: 日志文件存储目录
            max_bytes: 单个日志文件最大大小（字节）
            backup_count: 保留的备份文件数量
        """
        self.name = name
        self.log_level = getattr(logging, log_level.upper(), logging.INFO)
        self.log_dir = Path(log_dir)
        self.max_bytes = max_bytes
        self.backup_count = backup_count

        # 创建日志目录
        self.log_dir.mkdir(exist_ok=True)

        # 设置日志格式（去掉 funcName:lineno，保持人类可读性）
        self.formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )

        # 创建logger实例
        self.logger = self._setup_logger()

    def _setup_logger(self):
        """设置logger实例"""
        logger = logging.getLogger(self.name)
        logger.setLevel(self.log_level)

        # 避免重复添加处理器
        if logger.handlers:
            logger.handlers.clear()

        # 控制台处理器
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(self.log_level)
        console_handler.setFormatter(self.formatter)
        logger.addHandler(console_handler)

        # 文件处理器 - 按日期分割
        date_str = datetime.now().strftime("%Y-%m-%d")
        log_file = self.log_dir / f"{self.name}_{date_str}.log"

        file_handler = RotatingFileHandler(
            str(log_file),
            maxBytes=self.max_bytes,
            backupCount=self.backup_count,
            encoding='utf-8'
        )
        file_handler.setLevel(self.log_level)
        file_handler.setFormatter(self.formatter)
        logger.addHandler(file_handler)

        return logger

    def get_logger(self):
        """获取配置好的logger实例"""
        return self.logger


# 全局日志实例
_logger_instance = None


def setup_global_logger(name: str = "ai-chat-server", log_level: str = "INFO",
                       log_dir: str = "logs", max_bytes: int = 10 * 1024 * 1024,
                       backup_count: int = 5):
    """
    设置全局日志系统

    Args:
        name: 日志记录器名称
        log_level: 日志级别
        log_dir: 日志文件目录
        max_bytes: 最大文件大小
        backup_count: 备份文件数
    """
    global _logger_instance
    logger_setup = LoggerSetup(name, log_level, log_dir, max_bytes, backup_count)
    _logger_instance = logger_setup.get_logger()
    return _logger_instance


def get_logger(name: str = None):
    """
    获取日志记录器实例

    Args:
        name: 如果提供，返回子记录器；否则返回全局记录器
    """
    global _logger_instance
    if _logger_instance is None:
        # 如果没有初始化，默认创建一个
        _logger_instance = setup_global_logger()

    if name and name != _logger_instance.name:
        return _logger_instance.getChild(name)
    return _logger_instance


# 便捷的日志记录函数
def log_debug(message: str, *args, **kwargs):
    """记录DEBUG级别日志"""
    logger = get_logger()
    logger.debug(message, *args, **kwargs)


def log_info(message: str, *args, **kwargs):
    """记录INFO级别日志"""
    logger = get_logger()
    logger.info(message, *args, **kwargs)


def log_warning(message: str, *args, **kwargs):
    """记录WARNING级别日志"""
    logger = get_logger()
    logger.warning(message, *args, **kwargs)


def log_error(message: str, *args, **kwargs):
    """记录ERROR级别日志"""
    logger = get_logger()
    logger.error(message, *args, **kwargs)


def log_critical(message: str, *args, **kwargs):
    """记录CRITICAL级别日志"""
    logger = get_logger()
    logger.critical(message, *args, **kwargs)


def log_exception(message: str = ""):
    """记录异常信息"""
    logger = get_logger()
    logger.exception(message)


def log_structured(level: str, message: str, **details):
    """
    记录结构化日志

    Args:
        level: 日志级别
        message: 日志消息
        **details: 额外的结构化数据
    """
    logger = get_logger()
    # 为了开发时的可读性，不再使用单行 JSON 打印全结构
    # 转换为更易读的格式
    detail_str = ", ".join(f"{k}={v}" for k, v in details.items() if v)
    formatted_msg = f"[{message}] {detail_str}"
    
    getattr(logger, level.lower())(formatted_msg)


def log_request_info(method: str, path: str, client_ip: str = "unknown",
                     user_agent: str = "", referer: str = ""):
    """记录请求信息日志"""
    log_structured(
        "info",
        "API Request",
        method=method,
        path=path,
        client_ip=client_ip,
        user_agent=user_agent,
        referer=referer
    )


def log_response_info(status_code: int, process_time: float, path: str = "",
                      method: str = "", client_ip: str = ""):
    """记录响应信息日志"""
    log_structured(
        "info",
        "API Response",
        status_code=status_code,
        process_time_ms=process_time,
        path=path,
        method=method,
        client_ip=client_ip
    )


def log_error_detail(error_type: str, error_message: str, traceback_info: str = "",
                     context: dict = None):
    """记录详细的错误信息"""
    log_structured(
        "error",
        f"{error_type}: {error_message}",
        traceback=traceback_info,
        context=context or {}
    )


def log_chat_interaction(user_input: str, ai_response: str, model: str = "",
                         conversation_id: str = "", tokens_used: dict = None):
    """记录聊天交互日志"""
    log_structured(
        "info",
        "Chat Interaction",
        user_input=user_input[:100] + "..." if len(user_input) > 100 else user_input,  # 截断长输入
        ai_response=ai_response[:100] + "..." if len(ai_response) > 100 else ai_response,
        model=model,
        conversation_id=conversation_id,
        tokens_used=tokens_used
    )


def log_system_status(status: str, uptime: float = 0, cpu_usage: float = 0,
                      memory_usage: float = 0, disk_usage: float = 0):
    """记录系统状态日志"""
    log_structured(
        "info",
        "System Status",
        status=status,
        uptime_seconds=uptime,
        cpu_percent=cpu_usage,
        memory_percent=memory_usage,
        disk_percent=disk_usage
    )