"""
Métriques pour le suivi des performances EDS-NLP.

Ce module fournit des compteurs et histogrammes pour monitorer
l'extraction EDS-NLP en production.
"""

import logging
import time
from collections import defaultdict
from typing import Dict

logger = logging.getLogger(__name__)


class EDSNLPMetrics:
    """Collecteur de métriques pour EDS-NLP."""

    def __init__(self):
        """Initialise le collecteur de métriques."""
        # Compteurs
        self._counters: Dict[str, int] = defaultdict(int)
        
        # Histogrammes (liste de valeurs pour calcul de percentiles)
        self._histograms: Dict[str, list] = defaultdict(list)
        
        logger.info("edsnlp_metrics_initialized")

    def increment_counter(self, metric_name: str, value: int = 1) -> None:
        """
        Incrémente un compteur.

        Args:
            metric_name: Nom de la métrique
            value: Valeur à ajouter (défaut: 1)
        """
        self._counters[metric_name] += value
        logger.debug("metric_incremented", metric=metric_name, value=value)

    def record_histogram(self, metric_name: str, value: float) -> None:
        """
        Enregistre une valeur dans un histogramme.

        Args:
            metric_name: Nom de la métrique
            value: Valeur à enregistrer
        """
        self._histograms[metric_name].append(value)
        logger.debug("metric_recorded", metric=metric_name, value=value)

    def get_counter(self, metric_name: str) -> int:
        """
        Obtient la valeur d'un compteur.

        Args:
            metric_name: Nom de la métrique

        Returns:
            Valeur du compteur
        """
        return self._counters.get(metric_name, 0)

    def get_histogram_stats(self, metric_name: str) -> Dict[str, float]:
        """
        Calcule les statistiques d'un histogramme.

        Args:
            metric_name: Nom de la métrique

        Returns:
            Dictionnaire avec min, max, mean, p50, p95, p99
        """
        values = self._histograms.get(metric_name, [])
        
        if not values:
            return {
                "count": 0,
                "min": 0.0,
                "max": 0.0,
                "mean": 0.0,
                "p50": 0.0,
                "p95": 0.0,
                "p99": 0.0,
            }

        sorted_values = sorted(values)
        count = len(sorted_values)

        return {
            "count": count,
            "min": sorted_values[0],
            "max": sorted_values[-1],
            "mean": sum(sorted_values) / count,
            "p50": sorted_values[int(count * 0.50)],
            "p95": sorted_values[int(count * 0.95)] if count > 1 else sorted_values[0],
            "p99": sorted_values[int(count * 0.99)] if count > 1 else sorted_values[0],
        }

    def get_all_metrics(self) -> Dict:
        """
        Obtient toutes les métriques.

        Returns:
            Dictionnaire avec tous les compteurs et histogrammes
        """
        return {
            "counters": dict(self._counters),
            "histograms": {
                name: self.get_histogram_stats(name)
                for name in self._histograms.keys()
            },
        }

    def reset(self) -> None:
        """Réinitialise toutes les métriques."""
        self._counters.clear()
        self._histograms.clear()
        logger.info("metrics_reset")


# Instance globale de métriques
_global_metrics = EDSNLPMetrics()


def get_metrics() -> EDSNLPMetrics:
    """
    Obtient l'instance globale de métriques.

    Returns:
        Instance EDSNLPMetrics
    """
    return _global_metrics


def track_extraction_success() -> None:
    """Incrémente le compteur de succès d'extraction."""
    _global_metrics.increment_counter("edsnlp.extraction.success")


def track_extraction_failure() -> None:
    """Incrémente le compteur d'échecs d'extraction."""
    _global_metrics.increment_counter("edsnlp.extraction.failure")


def track_extraction_fallback() -> None:
    """Incrémente le compteur d'activations de fallback."""
    _global_metrics.increment_counter("edsnlp.extraction.fallback")


def track_processing_time(duration: float) -> None:
    """
    Enregistre le temps de traitement.

    Args:
        duration: Durée en secondes
    """
    _global_metrics.record_histogram("edsnlp.processing.time", duration)


def track_entity_extracted(entity_type: str) -> None:
    """
    Incrémente le compteur d'entités extraites par type.

    Args:
        entity_type: Type d'entité (diagnostic, medication, etc.)
    """
    _global_metrics.increment_counter(f"edsnlp.entities.extracted.{entity_type}")


def track_qualifier_detected(qualifier_type: str) -> None:
    """
    Incrémente le compteur de qualificateurs détectés par type.

    Args:
        qualifier_type: Type de qualificateur (negation, hypothesis, etc.)
    """
    _global_metrics.increment_counter(f"edsnlp.qualifiers.detected.{qualifier_type}")
