"""
Centralised, opinionated logging helpers.

Every log record gets the fields:
    req_id   – UUID v4 per HTTP/WebSocket request
    user     – authenticated user (or "-")
    method   – HTTP verb (or "-")
    path     – request path (or "-")
"""

from __future__ import annotations

import logging
import logging.config
import os
import uuid
from importlib import import_module
from typing import Any

from flask import g, has_request_context, request


def _get_cfg() -> dict[str, Any]:
    """
    Import backend.config **lazily** to dodge circular imports.
    Returns {} if import fails (very early bootstrap).
    """
    try:
        cfg_mod = import_module("backend.config")
        return cfg_mod.get_config()  # type: ignore[attr-defined]
    except Exception as e:
        print(f"Exception layzy loading module backend.config {e}")
        return {}


class _RequestContextFilter(logging.Filter):
    def filter(self, record: logging.LogRecord) -> bool:  # noqa: D401
        """Injects request-level context into `record` in-place."""

        if has_request_context():
            record.req_id = getattr(g, "request_id", "-")
            record.user = getattr(g, "authIdentifier", "-")
            record.method = request.method
            record.path = request.path
        else:
            record.req_id = record.user = record.method = record.path = "-"
        return True


def configure_logging() -> None:
    cfg = _get_cfg()
    cfg_level: str = str(cfg.get("logLevel", "")).upper()
    log_level = (cfg_level or "INFO").upper()

    fmt = "[%(asctime)s.%(msecs)03d] [%(threadName)s] [%(levelname)s] [%(name)s] user=%(user)s - %(message)s"
    datefmt = "%Y/%m/%d-%H:%M:%S"
    formatter = {"format": fmt, "datefmt": datefmt}
    logging.config.dictConfig(
        {
            "version": 1,
            "disable_existing_loggers": False,
            "filters": {"ctx": {"()": _RequestContextFilter}},
            "formatters": {"default": formatter},
            "handlers": {
                "console": {
                    "class": "logging.StreamHandler",
                    "formatter": "default",
                    "filters": ["ctx"],
                    "level": log_level,
                }
            },
            "root": {"handlers": ["console"], "level": log_level},
        }
    )


def get_logger(name: str) -> logging.Logger:
    """Uniform helper – **always** import this instead of `logging.getLogger`."""

    return logging.getLogger(name)


def set_request_id() -> None:
    """
    Ensure `g.request_id` exists (UUID4).
    Call once in *every* Flask/SocketIO entry-point.
    """

    if has_request_context() and not hasattr(g, "request_id"):
        g.request_id = str(uuid.uuid4())
