"""
Monitoring de santé du service Motion
"""

import time
import threading
import psutil
from typing import Dict, Any, Optional
from .utils import get_monotonic_ms, setup_json_logger


class HealthMonitor:
    """Moniteur de santé du service"""

    def __init__(self):
        self.logger = setup_json_logger("/opt/Skull/logs/motion.log")
        self._loop_count = 0
        self._loop_start_ms = get_monotonic_ms()
        self._last_health_ms = 0
        self._health_interval_ms = 2000  # 2 secondes

        # Compteurs de performance
        self._fps_counter = 0
        self._fps_start_time = time.time()
        self._current_fps = 0.0

    def tick_loop(self) -> None:
        """Enregistre un tick de boucle principale"""
        self._loop_count += 1

        # Calcul FPS toutes les secondes
        current_time = time.time()
        if current_time - self._fps_start_time >= 1.0:
            self._current_fps = self._fps_counter / (
                current_time - self._fps_start_time
            )
            self._fps_counter = 0
            self._fps_start_time = current_time
        else:
            self._fps_counter += 1

    def should_publish_health(self) -> bool:
        """Vérifie s'il faut publier la santé"""
        current_ms = get_monotonic_ms()
        if current_ms - self._last_health_ms >= self._health_interval_ms:
            self._last_health_ms = current_ms
            return True
        return False

    def get_health_data(self, components_status: Dict[str, bool]) -> Dict[str, Any]:
        """Retourne les données de santé"""
        try:
            # Température CPU (Linux)
            temp_c = None
            try:
                with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
                    temp_millidegrees = int(f.read().strip())
                    temp_c = temp_millidegrees / 1000.0
            except:
                # Fallback psutil si disponible
                try:
                    temps = psutil.sensors_temperatures()
                    if "cpu_thermal" in temps:
                        temp_c = temps["cpu_thermal"][0].current
                except:
                    pass

            # Status global : OK si tous les composants sont OK
            global_ok = all(components_status.values()) if components_status else False

            health_data = {
                "ok": global_ok,
                "ts_ms": get_monotonic_ms(),
                "loop_hz": round(self._current_fps, 1),
                "components": components_status,
            }

            if temp_c is not None:
                health_data["temp_c"] = round(temp_c, 1)

            # Mémoire et CPU
            try:
                process = psutil.Process()
                health_data["memory_mb"] = round(
                    process.memory_info().rss / 1024 / 1024, 1
                )
                health_data["cpu_percent"] = round(process.cpu_percent(), 1)
            except:
                pass

            return health_data

        except Exception as e:
            self.logger.error(f"Erreur collecte santé: {e}")
            return {"ok": False, "ts_ms": get_monotonic_ms(), "error": str(e)}
