"""Health events — structured events from watchdog and diagnostics."""
from __future__ import annotations

import enum
import time
import uuid
from collections import deque
from typing import Any

from pydantic import BaseModel, Field


class Severity(str, enum.Enum):
    info = "info"
    warning = "warning"
    critical = "critical"
    resolved = "resolved"


class HealthEvent(BaseModel):
    """Jedno zdarzenie zdrowia systemu."""
    id: str = Field(default_factory=lambda: f"evt-{uuid.uuid4().hex[:8]}")
    timestamp: float = Field(default_factory=time.time)
    severity: Severity
    source: str                # "proxy", "vscode", "provider:anthropic", "budget"
    title: str                 # krótki opis
    detail: str = ""           # traceback, error message
    resolved: bool = False
    resolved_at: float | None = None
    resolved_by: str | None = None    # "watchdog", "repair-agent", "manual"
    repair_attempted: bool = False
    repair_result: str | None = None  # "success", "failed", "skipped"


class HealthEventStore:
    """In-memory store zdarzeń z persystencją opcjonalną."""

    def __init__(self, max_events: int = 500) -> None:
        self._events: deque[HealthEvent] = deque(maxlen=max_events)
        self._active: dict[str, HealthEvent] = {}  # source → last unresolved

    def emit(
        self, severity: Severity, source: str, title: str, detail: str = "",
    ) -> HealthEvent:
        event = HealthEvent(
            severity=severity, source=source, title=title, detail=detail,
        )
        self._events.append(event)

        # Track active issues per source
        if severity in (Severity.critical, Severity.warning):
            self._active[source] = event
        elif severity == Severity.resolved and source in self._active:
            old = self._active.pop(source)
            old.resolved = True
            old.resolved_at = time.time()

        return event

    def resolve(self, source: str, resolved_by: str = "watchdog") -> None:
        if source in self._active:
            evt = self._active.pop(source)
            evt.resolved = True
            evt.resolved_at = time.time()
            evt.resolved_by = resolved_by
            self.emit(Severity.resolved, source, f"Resolved: {evt.title}")

    def get_active(self) -> list[HealthEvent]:
        return [e for e in self._active.values() if not e.resolved]

    def get_history(self, limit: int = 50, severity: str | None = None) -> list[dict]:
        items = list(self._events)
        if severity:
            items = [e for e in items if e.severity == severity]
        return [e.model_dump() for e in items[-limit:]]

    def get_summary(self) -> dict[str, Any]:
        active = self.get_active()
        return {
            "total_events": len(self._events),
            "active_issues": len(active),
            "critical": sum(1 for e in active if e.severity == Severity.critical),
            "warnings": sum(1 for e in active if e.severity == Severity.warning),
            "recent": [e.model_dump() for e in list(self._events)[-5:]],
        }


# Singleton
_store = HealthEventStore()


def get_health_store() -> HealthEventStore:
    return _store
