"""Configuration structlog — rich console (dev) + JSON file (prod)."""

from __future__ import annotations

import logging
import sys
from datetime import datetime
from pathlib import Path
from typing import Any

import structlog

from src.config import DATA_DIR

LOGS_DIR = DATA_DIR / "logs"


def get_json_log_path(run_date: str) -> Path:
    """Retourne le chemin du fichier de log JSON pour une date de run."""
    LOGS_DIR.mkdir(parents=True, exist_ok=True)
    return LOGS_DIR / f"pipeline-{run_date}.jsonl"


class FileLogProcessor:
    """Processor structlog qui écrit les logs dans un fichier JSONL."""

    def __init__(self, log_file: Path) -> None:
        self.file = log_file.open("a", encoding="utf-8")
        self.json_renderer = structlog.processors.JSONRenderer()

    def __call__(
        self, logger: Any, name: str, event_dict: structlog.types.EventDict
    ) -> structlog.types.EventDict:
        # Render en JSON (sans modifier event_dict)
        line = self.json_renderer(logger, name, event_dict)
        self.file.write(line + "\n")
        self.file.flush()
        return event_dict


def cleanup_old_logs(max_age_days: int = 3) -> None:
    """Supprime les fichiers de logs plus vieux que max_age_days."""
    if not LOGS_DIR.exists():
        return
    cutoff = datetime.now().timestamp() - (max_age_days * 86400)
    for log_file in LOGS_DIR.glob("pipeline-*.jsonl"):
        if log_file.stat().st_mtime < cutoff:
            log_file.unlink()


def configure_logging(log_level: str = "DEBUG") -> None:
    """Configure structlog avec double output : console rich + fichier JSON."""
    LOGS_DIR.mkdir(parents=True, exist_ok=True)
    cleanup_old_logs()

    # Déterminer le fichier de log du jour
    run_date = datetime.now().strftime("%Y-%m-%d")
    log_file = get_json_log_path(run_date)

    # Processors communs
    shared_processors: list[structlog.types.Processor] = [
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
    ]

    # Console : format rich lisible
    structlog.configure(
        processors=[
            *shared_processors,
            FileLogProcessor(log_file),  # Ajout du logging fichier
            structlog.dev.ConsoleRenderer(),
        ],
        wrapper_class=structlog.make_filtering_bound_logger(
            getattr(logging, log_level.upper()),
        ),
        context_class=dict,
        logger_factory=structlog.PrintLoggerFactory(file=sys.stderr),
        cache_logger_on_first_use=True,
    )
