"""Model Evolution Tracker — timeline of model changes.

Converts alteration history from ``ModelAlterationEngine`` into a
chronological ``ModelEvolutionEntry`` timeline with summary statistics.

All logic is deterministic — no LLM calls.
"""
from __future__ import annotations

from typing import Any, Dict, List, Optional

from ..contracts import ModelEvolutionEntry


class ModelEvolutionTracker:
    """Track and report on model evolution over time."""

    def __init__(self, alteration_engine=None):
        self._alteration_engine = alteration_engine

    # ------------------------------------------------------------------
    # Public API
    # ------------------------------------------------------------------

    def get_timeline(
        self,
        client_id: str = "",
        since: str = "",
    ) -> List[ModelEvolutionEntry]:
        """Return a chronological list of ``ModelEvolutionEntry`` objects.

        Parameters
        ----------
        client_id:
            Ignored for now — reserved for multi-tenant filtering.
        since:
            ISO-8601 date string.  Only entries on or after this date
            are included.  Empty string means "all".
        """
        if self._alteration_engine is None:
            return []

        try:
            alterations = self._alteration_engine.get_alterations()
        except (AttributeError, TypeError):
            return []

        entries: List[ModelEvolutionEntry] = []
        for alt in alterations:
            if hasattr(alt, "model_dump"):
                ad = alt.model_dump()
            elif isinstance(alt, dict):
                ad = alt
            else:
                continue

            entry = ModelEvolutionEntry(
                timestamp=ad.get("applied_at", ""),
                action=ad.get("action", ""),
                target=ad.get("target", ""),
                old_value=ad.get("old_value", ""),
                new_value=ad.get("new_value", ""),
                rationale=ad.get("rationale", ""),
                actor=self._infer_actor(ad),
            )
            entries.append(entry)

        # Filter by since
        if since:
            entries = [e for e in entries if e.timestamp >= since]

        # Sort chronologically
        entries.sort(key=lambda e: e.timestamp)
        return entries

    def get_summary(self, client_id: str = "") -> Dict[str, Any]:
        """Return a summary of model evolution statistics."""
        entries = self.get_timeline(client_id=client_id)
        if not entries:
            return {"total_changes": 0, "by_action": {}, "date_range": {}}

        by_action: Dict[str, int] = {}
        for e in entries:
            by_action[e.action] = by_action.get(e.action, 0) + 1

        timestamps = [e.timestamp for e in entries if e.timestamp]
        date_range: Dict[str, str] = {}
        if timestamps:
            date_range = {"earliest": min(timestamps), "latest": max(timestamps)}

        return {
            "total_changes": len(entries),
            "by_action": by_action,
            "date_range": date_range,
        }

    # ------------------------------------------------------------------
    # Internal helpers
    # ------------------------------------------------------------------

    @staticmethod
    def _infer_actor(alteration: Dict[str, Any]) -> str:
        """Infer who performed the alteration.  Default is ``"user"``."""
        # Future: inspect metadata for agent traces
        return alteration.get("actor", "user")
