"""Logging setup with correlation IDs and secret redaction."""

from __future__ import annotations

import logging
import re
from logging.handlers import RotatingFileHandler
from pathlib import Path

_TOKEN_PATTERN = re.compile(r"\b\d{5,15}:[A-Za-z0-9_-]{20,}\b")
_SECRET_QUERY_PATTERN = re.compile(
    r"(?i)([?&](?:token|access_token|api_key|apikey|key|auth|signature|sig|password|"
    r"secret|session|cookie)=)[^&\s]+"
)
_BEARER_PATTERN = re.compile(r"(?i)(authorization:\s*bearer\s+)\S+")


class RedactingFilter(logging.Filter):
    """Add a default job correlation field and redact common secret shapes."""

    def filter(self, record: logging.LogRecord) -> bool:
        if not hasattr(record, "job_id"):
            record.job_id = "-"
        try:
            message = record.getMessage()
        except Exception:  # pragma: no cover - defensive
            return True
        redacted = _TOKEN_PATTERN.sub("<redacted-token>", message)
        redacted = _SECRET_QUERY_PATTERN.sub(r"\1<redacted>", redacted)
        redacted = _BEARER_PATTERN.sub(r"\1<redacted>", redacted)
        if redacted != message:
            record.msg = redacted
            record.args = ()
        return True


def setup_logging(level: str = "INFO", log_file: Path | None = None) -> None:
    root = logging.getLogger()
    root.setLevel(level.upper())
    for handler in list(root.handlers):
        root.removeHandler(handler)
        handler.close()

    formatter = logging.Formatter(
        "%(asctime)s %(levelname)-8s %(name)s [job=%(job_id)s] %(message)s",
        datefmt="%Y-%m-%dT%H:%M:%S%z",
    )
    redactor = RedactingFilter()

    console = logging.StreamHandler()
    console.setFormatter(formatter)
    console.addFilter(redactor)
    root.addHandler(console)

    if log_file is not None:
        log_file.parent.mkdir(parents=True, exist_ok=True)
        file_handler = RotatingFileHandler(
            log_file, maxBytes=5 * 1024 * 1024, backupCount=5, encoding="utf-8"
        )
        file_handler.setFormatter(formatter)
        file_handler.addFilter(redactor)
        root.addHandler(file_handler)

    logging.getLogger("aiogram.event").setLevel(logging.WARNING)
    logging.getLogger("aiohttp.access").setLevel(logging.WARNING)
    logging.getLogger("aiohttp.client").setLevel(logging.WARNING)
    logging.getLogger("asyncio").setLevel(logging.WARNING)
    logging.getLogger("PIL").setLevel(logging.WARNING)
