"""
Centralized logging system for MyRX AI Service.

Usage:
    from src.utils.logger import get_logger, set_request_context, clear_request_context

    logger = get_logger(__name__)
    logger.info("Something happened")

    # In middleware — sets context for all logs within this request
    set_request_context(request_id="abc-123", client_id="client_1")

Log output (console + file):
    2026-04-01 12:00:00 | INFO    | src.api.main | [req:abc-123 client:client_1] Processing 2 medications

Log file:
    logs/myrx_ai_service.log  (hourly rotation, 24 backups, cleanup after 10 days)
"""

import logging
import sys
import os
import time
from pathlib import Path
from logging.handlers import TimedRotatingFileHandler
from contextvars import ContextVar

# ── Request-scoped context (async-safe via contextvars) ──
_request_id_var: ContextVar[str] = ContextVar("request_id", default="-")
_client_id_var: ContextVar[str] = ContextVar("client_id", default="-")


def set_request_context(request_id: str = "-", client_id: str = "-") -> None:
    """Set request context for the current async task. Called by middleware."""
    _request_id_var.set(request_id)
    _client_id_var.set(client_id)


def clear_request_context() -> None:
    """Clear request context after request completes."""
    _request_id_var.set("-")
    _client_id_var.set("-")


def get_request_id() -> str:
    return _request_id_var.get()


def get_client_id() -> str:
    return _client_id_var.get()


class RequestContextFormatter(logging.Formatter):
    """Custom formatter that injects request_id and client_id into every log line."""

    def format(self, record: logging.LogRecord) -> str:
        record.request_id = _request_id_var.get()
        record.client_id = _client_id_var.get()
        return super().format(record)


def cleanup_old_logs(log_directory: Path, days_to_keep: int = 10) -> None:
    """Delete log files older than days_to_keep days."""
    logger = logging.getLogger(__name__)
    current_time = time.time()
    for log_file in log_directory.iterdir():
        if log_file.is_file():
            file_age = current_time - log_file.stat().st_mtime
            if file_age > days_to_keep * 86400:
                os.remove(log_file)
                logger.info(f"Deleted old log file: {log_file}")


# ── Singleton setup ──
_initialized = False


def setup_logging(level: str = None) -> None:
    """
    Configure logging once for the entire application.
    Call this early in app startup (e.g. before FastAPI app creation).

    Sets up:
    - Console handler (stdout)
    - File handler (TimedRotatingFileHandler, hourly, 24 backups)
    - Log cleanup (deletes files older than 10 days)
    """
    global _initialized
    if _initialized:
        return
    _initialized = True

    log_level = (level or os.getenv("LOG_LEVEL", "INFO")).upper()

    formatter = RequestContextFormatter(
        fmt="%(asctime)s [%(levelname)s:%(process)d] %(name)s | [req:%(request_id)s client:%(client_id)s] %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )

    # Clear all handlers to prevent duplication
    root = logging.getLogger()
    root.handlers.clear()
    root.setLevel(getattr(logging, log_level, logging.INFO))

    # Console handler
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setLevel(getattr(logging, log_level, logging.INFO))
    console_handler.setFormatter(formatter)
    root.addHandler(console_handler)

    # File handler — hourly rotation, keep 24 backups
    log_dir = Path(__file__).parent.parent.parent / "logs"
    log_dir.mkdir(exist_ok=True)
    log_file = log_dir / "myrx_ai_service.log"

    file_handler = TimedRotatingFileHandler(
        log_file,
        when="H",
        interval=1,
        backupCount=24,
    )
    file_handler.setLevel(getattr(logging, log_level, logging.INFO))
    file_handler.setFormatter(formatter)
    root.addHandler(file_handler)

    # Clean up old log files
    cleanup_old_logs(log_dir, days_to_keep=10)

    # Quiet noisy third-party loggers
    for noisy in ("httpx", "httpcore", "urllib3", "google_genai", "google_genai.models"):
        logging.getLogger(noisy).setLevel(logging.WARNING)


def get_logger(name: str) -> logging.Logger:
    """
    Get a logger. Ensures logging is initialized.
    This is the only function modules need to import.
    """
    setup_logging()
    return logging.getLogger(name)
