"""
AWOOOI Structured Logging
=========================
structlog configuration for production-grade logging

Features:
- JSON output in production
- Pretty console output in development
- Request ID propagation
- Async-safe
"""

import logging
import re
import sys
from typing import Any

import structlog
from structlog.types import Processor

from src.core.config import settings

_TELEGRAM_BOT_URL_RE = re.compile(r"(api\.telegram\.org/bot)[^/\s]+")


def _redact_sensitive_log_text(text: str) -> str:
    """遮蔽可能出現在第三方 logger 訊息中的敏感 URL。"""
    return _TELEGRAM_BOT_URL_RE.sub(r"\1<redacted>", text)


class SensitiveURLRedactionFilter(logging.Filter):
    """標準 logging filter：避免 httpx 等第三方 logger 把 token URL 打進 log。"""

    def filter(self, record: logging.LogRecord) -> bool:
        record.msg = _redact_sensitive_log_text(str(record.msg))
        if isinstance(record.args, tuple):
            record.args = tuple(_redact_sensitive_log_text(str(arg)) for arg in record.args)
        elif isinstance(record.args, dict):
            record.args = {
                key: _redact_sensitive_log_text(str(value))
                for key, value in record.args.items()
            }
        return True


def setup_logging() -> None:
    """Configure structlog for the application"""

    # Shared processors for all environments
    shared_processors: list[Processor] = [
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.StackInfoRenderer(),
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.CallsiteParameterAdder(
            parameters=[
                structlog.processors.CallsiteParameter.PATHNAME,
                structlog.processors.CallsiteParameter.LINENO,
            ]
        ),
    ]

    if settings.ENVIRONMENT == "dev":
        # Development: Pretty console output
        processors: list[Processor] = [
            *shared_processors,
            structlog.processors.ExceptionPrettyPrinter(),
            structlog.dev.ConsoleRenderer(colors=True),
        ]
    else:
        # Production: JSON output for log aggregation
        processors = [
            *shared_processors,
            structlog.processors.format_exc_info,
            structlog.processors.JSONRenderer(),
        ]

    structlog.configure(
        processors=processors,
        wrapper_class=structlog.make_filtering_bound_logger(
            logging.getLevelName(settings.LOG_LEVEL)
        ),
        context_class=dict,
        logger_factory=structlog.PrintLoggerFactory(),
        cache_logger_on_first_use=True,
    )

    # Configure standard library logging to use structlog
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=logging.getLevelName(settings.LOG_LEVEL),
    )
    redaction_filter = SensitiveURLRedactionFilter()
    root_logger = logging.getLogger()
    root_logger.addFilter(redaction_filter)
    for handler in root_logger.handlers:
        handler.addFilter(redaction_filter)

    # httpx INFO 會輸出完整 request URL；Telegram Bot API URL 內含 token。
    logging.getLogger("httpx").setLevel(logging.WARNING)
    logging.getLogger("httpcore").setLevel(logging.WARNING)


def get_logger(name: str | None = None, **initial_context: Any) -> structlog.BoundLogger:
    """Get a configured logger instance"""
    logger = structlog.get_logger(name)
    if initial_context:
        logger = logger.bind(**initial_context)
    return logger
