"""Structured logging with secret/token redaction."""

from __future__ import annotations

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

_TOKEN_RE = re.compile(r"\b\d{5,15}:[A-Za-z0-9_-]{20,}\b")
_DEEP_LINK_RE = re.compile(r"(https://t\.me/[A-Za-z0-9_]+)\?start=[A-Za-z0-9_-]+")


def redact_text(text: str) -> str:
    """Redact bot tokens and deep-link start parameters from arbitrary text."""

    redacted = _TOKEN_RE.sub("[REDACTED_BOT_TOKEN]", text)
    return _DEEP_LINK_RE.sub(r"\1?start=[REDACTED]", redacted)


class SecretRedactionFilter(logging.Filter):
    """Best-effort redaction for accidental secret exposure in log records."""

    def filter(self, record: logging.LogRecord) -> bool:
        try:
            message = record.getMessage()
        except Exception:
            return True
        redacted = redact_text(message)
        if redacted != message:
            record.msg = redacted
            record.args = ()
        return True


class RedactingFormatter(logging.Formatter):
    """Apply redaction to the complete formatted record, including tracebacks."""

    def format(self, record: logging.LogRecord) -> str:
        return redact_text(super().format(record))


def setup_logging(level: str, log_file: Path) -> None:
    log_file.parent.mkdir(parents=True, exist_ok=True)
    root = logging.getLogger()
    root.setLevel(level)
    root.handlers.clear()

    formatter = RedactingFormatter(
        "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )
    redaction = SecretRedactionFilter()

    stream = logging.StreamHandler(sys.stdout)
    stream.setFormatter(formatter)
    stream.addFilter(redaction)
    root.addHandler(stream)

    file_handler = logging.handlers.RotatingFileHandler(
        log_file,
        maxBytes=10 * 1024 * 1024,
        backupCount=5,
        encoding="utf-8",
    )
    file_handler.setFormatter(formatter)
    file_handler.addFilter(redaction)
    root.addHandler(file_handler)

    logging.getLogger("aiogram.event").setLevel(logging.WARNING)
    logging.getLogger("apscheduler.executors.default").setLevel(logging.WARNING)
    logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
