"""Performance metrics and caching for Alexa Media Player.

Provides boot time tracking and intelligent data caching.
"""

from __future__ import annotations

from dataclasses import dataclass, field
import logging
import time
from typing import Any

from homeassistant.core import HomeAssistant

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)


@dataclass
class BootMetrics:
    """Track boot performance metrics."""

    start_time: float = field(default_factory=time.monotonic)
    stages: dict[str, float] = field(default_factory=dict)

    def record_stage(self, stage_name: str) -> None:
        """Record a boot stage completion."""
        elapsed = time.monotonic() - self.start_time
        self.stages[stage_name] = elapsed
        _LOGGER.debug(
            "[BOOT METRICS] %s completed in %.3fs",
            stage_name,
            elapsed,
        )

    def get_summary(self) -> dict[str, Any]:
        """Get boot metrics summary."""
        total = time.monotonic() - self.start_time
        return {
            "total_time_seconds": round(total, 3),
            "stages": {k: round(v, 3) for k, v in self.stages.items()},
        }


class DataCache:
    """Simple TTL cache for API responses.

    Reduces redundant API calls during startup and normal operation.
    """

    def __init__(self, ttl_seconds: float = 30.0, max_entries: int = 128) -> None:
        """Initialize cache with TTL.

        Args:
            ttl_seconds: Time-to-live for cached entries
            max_entries: Maximum number of entries before evicting oldest
        """
        self._cache: dict[str, tuple[Any, float]] = {}
        self._ttl = ttl_seconds
        self._max_entries = max_entries
        self._hits = 0
        self._misses = 0

    def get(self, key: str) -> Any | None:
        """Get value from cache if not expired.

        Args:
            key: Cache key

        Returns:
            Cached value or None if expired/missing
        """
        if key not in self._cache:
            self._misses += 1
            return None

        value, timestamp = self._cache[key]
        if time.monotonic() - timestamp > self._ttl:
            # Expired
            del self._cache[key]
            self._misses += 1
            return None

        self._hits += 1
        return value

    def cache_set(self, key: str, value: Any) -> None:
        """Store value in cache.

        Note: Stores a direct reference (not a copy) for performance.
        Callers should treat cached values as read-only unless the caller created
        the cached object, is solely responsible for all mutations, and intentionally
        enriches it in-place (e.g., the device-dict refresh in async_update_data).

        Args:
            key: Cache key
            value: Value to cache
        """
        if len(self._cache) >= self._max_entries and key not in self._cache:
            oldest_key = min(self._cache, key=lambda k: self._cache[k][1])
            del self._cache[oldest_key]
        self._cache[key] = (value, time.monotonic())

    def invalidate(self, key: str) -> None:
        """Remove key from cache."""
        self._cache.pop(key, None)

    def clear(self) -> None:
        """Clear all cached entries."""
        self._cache.clear()
        self._hits = 0
        self._misses = 0

    def get_stats(self) -> dict[str, int]:
        """Get cache statistics."""
        total = self._hits + self._misses
        hit_rate = (self._hits / total * 100) if total > 0 else 0
        return {
            "entries": len(self._cache),
            "hits": self._hits,
            "misses": self._misses,
            "hit_rate_percent": round(hit_rate, 1),
        }


class AlexaMetrics:
    """Central metrics collector for Alexa Media Player."""

    def __init__(self, hass: HomeAssistant) -> None:
        """Initialize metrics collector."""
        self.hass = hass
        self.boot_metrics: BootMetrics | None = None
        self.api_cache = DataCache(ttl_seconds=30.0)
        self._api_calls: dict[str, tuple[int, float]] = {}  # count, total_time

    def start_boot_tracking(self) -> None:
        """Start tracking boot performance."""
        self.boot_metrics = BootMetrics()
        _LOGGER.debug("[BOOT METRICS] Started tracking")

    def record_boot_stage(self, stage_name: str) -> None:
        """Record a boot stage completion."""
        if self.boot_metrics:
            self.boot_metrics.record_stage(stage_name)

    def record_api_call(self, endpoint: str, duration: float) -> None:
        """Record API call metrics.

        Args:
            endpoint: API endpoint name
            duration: Call duration in seconds
        """
        if endpoint not in self._api_calls:
            self._api_calls[endpoint] = (0, 0.0)

        count, total = self._api_calls[endpoint]
        self._api_calls[endpoint] = (count + 1, total + duration)

    def get_api_stats(self) -> dict[str, Any]:
        """Get API call statistics."""
        stats = {}
        for endpoint, (count, total) in self._api_calls.items():
            stats[endpoint] = {
                "calls": count,
                "total_time": round(total, 3),
                "avg_time": round(total / count, 3) if count > 0 else 0,
            }
        return stats

    def get_full_report(self) -> dict[str, Any]:
        """Get complete metrics report."""
        return {
            "boot": self.boot_metrics.get_summary() if self.boot_metrics else None,
            "cache": self.api_cache.get_stats(),
            "api_calls": self.get_api_stats(),
        }


def get_metrics(hass: HomeAssistant) -> AlexaMetrics | None:
    """Get metrics instance from hass data.

    Args:
        hass: Home Assistant instance

    Returns:
        AlexaMetrics instance or None if not initialized
    """
    if DOMAIN in hass.data and "metrics" in hass.data[DOMAIN]:
        return hass.data[DOMAIN]["metrics"]
    return None
