import logging
import logging.handlers
from pathlib import Path

from app.core.config import get_settings

_configured: set[str] = set()


def configure_logging(component: str) -> None:
    """Adds a rotating file handler (10MB x 5 backups) for the given component
    ('backend' or 'worker') on top of whatever console logging the framework
    (uvicorn/celery) already set up. Idempotent per component per process."""
    if component in _configured:
        return
    _configured.add(component)

    settings = get_settings()
    log_dir = Path(settings.log_dir)
    log_dir.mkdir(parents=True, exist_ok=True)

    handler = logging.handlers.RotatingFileHandler(
        log_dir / f"{component}.log", maxBytes=10 * 1024 * 1024, backupCount=5
    )

    if settings.log_json:
        from pythonjsonlogger import jsonlogger

        formatter = jsonlogger.JsonFormatter(
            "%(asctime)s %(levelname)s %(name)s %(message)s", rename_fields={"asctime": "timestamp", "levelname": "level"}
        )
    else:
        formatter = logging.Formatter("%(asctime)s %(levelname)s [%(name)s] %(message)s")

    handler.setFormatter(formatter)

    # uvicorn and celery both configure their own loggers with propagate=False, so
    # attaching only to root would silently miss request/task logs — attach directly
    # to every logger namespace that matters for each component.
    # Root gets the handler so any plain `logging.getLogger(__name__)` call in our own
    # code is captured. Framework loggers (uvicorn/celery) get it too but with
    # propagate disabled afterward, since they'd otherwise bubble up to root and log
    # every line twice.
    framework_loggers: list[str] = []
    if component == "backend":
        framework_loggers = ["uvicorn.error", "uvicorn.access"]
    elif component == "worker":
        framework_loggers = ["celery", "celery.task", "celery.worker"]

    for name in [""] + framework_loggers:
        logger = logging.getLogger(name)
        logger.addHandler(handler)
        logger.setLevel(logging.INFO)

    for name in framework_loggers:
        logging.getLogger(name).propagate = False
