"""
Health check endpoints for system monitoring.
"""

import logging
from typing import Dict, Any
from datetime import datetime

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

from ....shared.config import settings
from ...hardware.hardware_manager import hardware_manager
from ...recipe.recipe_controller import recipe_controller
from ...safety.safety_monitor import safety_monitor


logger = logging.getLogger(__name__)

router = APIRouter()


class HealthStatus(BaseModel):
    """Health status response model."""
    status: str  # "healthy", "degraded", "unhealthy"
    timestamp: datetime
    uptime_seconds: float
    version: str
    environment: str


class DetailedHealthStatus(BaseModel):
    """Detailed health status with component information."""
    overall_status: str
    timestamp: datetime
    uptime_seconds: float
    version: str
    environment: str
    components: Dict[str, Dict[str, Any]]


@router.get("/", response_model=HealthStatus)
async def health_check():
    """Basic health check endpoint."""
    try:
        # Quick health check
        overall_status = "healthy"
        
        # Check hardware communication
        hw_status = hardware_manager.get_hardware_status()
        if hw_status.communication_health < 80:
            overall_status = "degraded"
        
        # Check for critical alarms
        alarm_summary = safety_monitor.get_alarm_summary()
        if alarm_summary["active_by_priority"].get("critical", 0) > 0:
            overall_status = "unhealthy"
        
        return HealthStatus(
            status=overall_status,
            timestamp=datetime.now(),
            uptime_seconds=0.0,  # Would calculate actual uptime
            version=settings.app_version,
            environment=settings.environment
        )
        
    except Exception as e:
        logger.error(f"Health check failed: {e}")
        raise HTTPException(status_code=503, detail="Health check failed")


@router.get("/detailed", response_model=DetailedHealthStatus)
async def detailed_health_check():
    """Detailed health check with component status."""
    try:
        # Overall system status
        overall_status = "healthy"
        component_statuses = {}
        
        # Hardware status
        try:
            hw_status = hardware_manager.get_hardware_status()
            hw_healthy = hw_status.communication_health >= 80
            
            component_statuses["hardware"] = {
                "status": "healthy" if hw_healthy else "unhealthy",
                "communication_health": hw_status.communication_health,
                "system_status": hw_status.system_status.value,
                "last_update": hw_status.last_update.isoformat() if hw_status.last_update else None,
                "temperature_sensors": len(hw_status.temperatures),
                "motor_count": len(hw_status.motors),
            }
            
            if not hw_healthy:
                overall_status = "degraded"
                
        except Exception as e:
            logger.error(f"Hardware health check failed: {e}")
            component_statuses["hardware"] = {
                "status": "unhealthy",
                "error": str(e)
            }
            overall_status = "unhealthy"
        
        # Recipe controller status
        try:
            process_status = await recipe_controller.get_process_status()
            
            component_statuses["recipe_controller"] = {
                "status": "healthy",
                "has_active_process": process_status is not None,
                "process_status": process_status["session"]["status"] if process_status else None,
            }
            
        except Exception as e:
            logger.error(f"Recipe controller health check failed: {e}")
            component_statuses["recipe_controller"] = {
                "status": "unhealthy", 
                "error": str(e)
            }
            overall_status = "degraded"
        
        # Safety monitor status
        try:
            alarm_summary = safety_monitor.get_alarm_summary()
            critical_alarms = alarm_summary["active_by_priority"].get("critical", 0)
            
            safety_healthy = critical_alarms == 0
            
            component_statuses["safety_monitor"] = {
                "status": "healthy" if safety_healthy else "unhealthy",
                "active_alarms": alarm_summary["total_active_alarms"],
                "critical_alarms": critical_alarms,
                "emergency_stop_active": alarm_summary["emergency_stop_active"],
                "last_check": alarm_summary["last_safety_check"],
            }
            
            if not safety_healthy:
                overall_status = "unhealthy"
                
        except Exception as e:
            logger.error(f"Safety monitor health check failed: {e}")
            component_statuses["safety_monitor"] = {
                "status": "unhealthy",
                "error": str(e)
            }
            overall_status = "unhealthy"
        
        # Database status
        try:
            from ....shared.database import db_manager
            # Simple database connectivity test would go here
            component_statuses["database"] = {
                "status": "healthy",
                "connected": True,
            }
            
        except Exception as e:
            logger.error(f"Database health check failed: {e}")
            component_statuses["database"] = {
                "status": "unhealthy",
                "error": str(e)
            }
            overall_status = "unhealthy"
        
        return DetailedHealthStatus(
            overall_status=overall_status,
            timestamp=datetime.now(),
            uptime_seconds=0.0,  # Would calculate actual uptime
            version=settings.app_version,
            environment=settings.environment,
            components=component_statuses
        )
        
    except Exception as e:
        logger.error(f"Detailed health check failed: {e}")
        raise HTTPException(status_code=503, detail="Detailed health check failed")


@router.get("/ready")
async def readiness_check():
    """Kubernetes readiness probe endpoint."""
    try:
        # Check if all critical services are ready
        hw_status = hardware_manager.get_hardware_status()
        
        if hw_status.communication_health < 50:
            raise HTTPException(status_code=503, detail="Hardware communication not ready")
        
        return {"status": "ready", "timestamp": datetime.now()}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Readiness check failed: {e}")
        raise HTTPException(status_code=503, detail="Service not ready")


@router.get("/live")
async def liveness_check():
    """Kubernetes liveness probe endpoint."""
    # Simple liveness check - if this endpoint responds, service is alive
    return {"status": "alive", "timestamp": datetime.now()}


@router.get("/metrics")
async def metrics():
    """Prometheus-compatible metrics endpoint."""
    try:
        # Get hardware stats
        hw_status = hardware_manager.get_hardware_status()
        comm_stats = hardware_manager.get_communication_statistics()
        
        # Get safety stats
        alarm_summary = safety_monitor.get_alarm_summary()
        
        # Format as Prometheus metrics
        metrics_text = f"""
# HELP tempering_machine_communication_health_percent Hardware communication health percentage
# TYPE tempering_machine_communication_health_percent gauge
tempering_machine_communication_health_percent {hw_status.communication_health}

# HELP tempering_machine_temperature_celsius Current temperature readings
# TYPE tempering_machine_temperature_celsius gauge
"""
        
        # Add temperature metrics
        for sensor_name, reading in hw_status.temperatures.items():
            if reading.is_valid:
                metrics_text += f'tempering_machine_temperature_celsius{{sensor="{sensor_name}"}} {reading.value}\n'
        
        # Add communication metrics
        if comm_stats:
            metrics_text += f"""
# HELP tempering_machine_requests_total Total number of communication requests
# TYPE tempering_machine_requests_total counter
tempering_machine_requests_total {comm_stats.get("total_requests", 0)}

# HELP tempering_machine_request_failures_total Total number of failed requests
# TYPE tempering_machine_request_failures_total counter
tempering_machine_request_failures_total {comm_stats.get("failed_requests", 0)}
"""
        
        # Add alarm metrics
        metrics_text += f"""
# HELP tempering_machine_active_alarms Total number of active alarms
# TYPE tempering_machine_active_alarms gauge
tempering_machine_active_alarms {alarm_summary["total_active_alarms"]}

# HELP tempering_machine_critical_alarms Total number of critical alarms
# TYPE tempering_machine_critical_alarms gauge
tempering_machine_critical_alarms {alarm_summary["active_by_priority"].get("critical", 0)}
"""
        
        return metrics_text.strip()
        
    except Exception as e:
        logger.error(f"Metrics collection failed: {e}")
        raise HTTPException(status_code=500, detail="Metrics collection failed")