"""
Structured logging configuration.

Why JSON logs: on a production VPS, you (or a log aggregator like Loki/
Grafana) need to filter and search logs reliably. Plain text logs are fine
for local dev (human-readable), but production needs machine-parseable
fields: timestamp, level, request_id, latency_ms, etc.

Every request gets a request_id that flows through all log lines for that
request — this is what lets you trace a single farmer's query through
validation -> models -> LLM -> response in the logs.
"""

import logging
import sys
from contextvars import ContextVar
from pythonjsonlogger import jsonlogger

from app.core.config import get_settings

settings = get_settings()

# Holds the current request's ID so every log line in that request's
# lifecycle can be tagged with it, without passing it through every
# function signature manually.
request_id_ctx: ContextVar[str] = ContextVar("request_id", default="-")


class RequestIdFilter(logging.Filter):
    def filter(self, record: logging.LogRecord) -> bool:
        record.request_id = request_id_ctx.get()
        return True


def setup_logging() -> None:
    root_logger = logging.getLogger()
    root_logger.setLevel(settings.LOG_LEVEL)

    # Remove default handlers to avoid duplicate log lines
    root_logger.handlers.clear()

    handler = logging.StreamHandler(sys.stdout)
    handler.addFilter(RequestIdFilter())

    if settings.LOG_JSON:
        formatter = jsonlogger.JsonFormatter(
            "%(asctime)s %(levelname)s %(name)s %(request_id)s %(message)s",
            rename_fields={"asctime": "timestamp", "levelname": "level"},
        )
    else:
        formatter = logging.Formatter(
            "%(asctime)s | %(levelname)-8s | %(request_id)s | %(name)s | %(message)s"
        )

    handler.setFormatter(formatter)
    root_logger.addHandler(handler)

    # Quiet down noisy third-party loggers
    logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
    logging.getLogger("httpx").setLevel(logging.WARNING)


def get_logger(name: str) -> logging.Logger:
    return logging.getLogger(name)
