"""
结构化日志配置
"""

import sys
from typing import Dict, Any, Optional
from loguru import logger
from pathlib import Path


class StructuredLogger:
    """结构化日志记录器"""

    def __init__(
        self, component: str, default_context: Optional[Dict[str, Any]] = None
    ):
        self.component = component
        self._default_context = default_context or {}

    def bind(self, **context: Any) -> "StructuredLogger":
        """返回附加默认上下文的新记录器"""
        merged = {**self._default_context, **context}
        return StructuredLogger(self.component, merged)

    def _log_with_context(self, level: str, message: str, **context):
        """带上下文的日志记录"""
        log_data = {
            "component": self.component,
            **self._default_context,
            "message": message,
            **context,
        }
        getattr(logger, level)(log_data)

    def info(self, message: str, **context):
        self._log_with_context("info", message, **context)

    def error(self, message: str, **context):
        self._log_with_context("error", message, **context)

    def warning(self, message: str, **context):
        self._log_with_context("warning", message, **context)

    def debug(self, message: str, **context):
        self._log_with_context("debug", message, **context)

    def exception(
        self, message: str, exception: Optional[BaseException] = None, **context
    ):
        """记录异常信息并输出堆栈"""
        log_data = {
            "component": self.component,
            **self._default_context,
            "message": message,
            **context,
        }
        if exception is not None:
            logger.opt(exception=exception).error(log_data)
        else:
            logger.exception(log_data)


def setup_logging(
    log_level: str = "INFO", log_file: Optional[str] = None, enable_json: bool = False
):
    """设置日志配置"""

    # 移除默认处理器
    logger.remove()

    # 日志格式
    if enable_json:
        log_format = "{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} | {extra} | {message}"
    else:
        log_format = (
            "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
            "<level>{level: <8}</level> | "
            "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | "
            "<level>{message}</level>"
        )

    # 控制台输出
    logger.add(
        sys.stdout,
        format=log_format,
        level=log_level,
        colorize=not enable_json,
        serialize=enable_json,
    )

    # 文件输出
    if log_file:
        log_path = Path(log_file)
        log_path.parent.mkdir(parents=True, exist_ok=True)

        logger.add(
            log_file,
            format=log_format,
            level=log_level,
            rotation="100 MB",
            retention="10 days",
            serialize=enable_json,
        )


def get_logger(component: str) -> StructuredLogger:
    """获取组件日志记录器"""
    return StructuredLogger(component)


# 特定组件的日志记录器
def get_worker_logger() -> StructuredLogger:
    """获取 Worker 日志记录器"""
    return get_logger("worker")


def get_api_logger() -> StructuredLogger:
    """获取 API 日志记录器"""
    return get_logger("api")


def get_db_logger() -> StructuredLogger:
    """获取数据库日志记录器"""
    return get_logger("database")
