"""
Health Check Module for BrighterTrading.

Provides health check endpoints and monitoring capabilities.
"""

import logging
from typing import Dict, Any, List, Optional
from datetime import datetime
import time

logger = logging.getLogger(__name__)


class HealthStatus:
    """Health status constants."""
    HEALTHY = 'healthy'
    DEGRADED = 'degraded'
    UNHEALTHY = 'unhealthy'


class HealthCheck:
    """
    Health check coordinator for monitoring system health.
    """

    def __init__(self):
        self._checks: Dict[str, callable] = {}
        self._last_check_time: Optional[datetime] = None
        self._cached_status: Optional[Dict[str, Any]] = None
        self._cache_ttl_seconds: float = 5.0

    def register_check(self, name: str, check_fn: callable) -> None:
        """
        Register a health check function.

        :param name: Check name.
        :param check_fn: Function that returns (status, message) tuple.
        """
        self._checks[name] = check_fn
        logger.debug(f"Registered health check: {name}")

    def unregister_check(self, name: str) -> None:
        """Unregister a health check."""
        if name in self._checks:
            del self._checks[name]

    def run_checks(self, use_cache: bool = True) -> Dict[str, Any]:
        """
        Run all health checks and return aggregated status.

        :param use_cache: Use cached results if available and fresh.
        :return: Health status dictionary.
        """
        # Check cache
        if use_cache and self._cached_status and self._last_check_time:
            age = (datetime.utcnow() - self._last_check_time).total_seconds()
            if age < self._cache_ttl_seconds:
                return self._cached_status

        start_time = time.time()
        results: Dict[str, Dict[str, Any]] = {}
        overall_status = HealthStatus.HEALTHY

        for name, check_fn in self._checks.items():
            try:
                check_start = time.time()
                status, message = check_fn()
                check_duration = time.time() - check_start

                results[name] = {
                    'status': status,
                    'message': message,
                    'duration_ms': round(check_duration * 1000, 2),
                }

                # Downgrade overall status if needed
                if status == HealthStatus.UNHEALTHY:
                    overall_status = HealthStatus.UNHEALTHY
                elif status == HealthStatus.DEGRADED and overall_status == HealthStatus.HEALTHY:
                    overall_status = HealthStatus.DEGRADED

            except Exception as e:
                logger.error(f"Health check '{name}' failed with error: {e}")
                results[name] = {
                    'status': HealthStatus.UNHEALTHY,
                    'message': str(e),
                    'error': True,
                }
                overall_status = HealthStatus.UNHEALTHY

        total_duration = time.time() - start_time

        status = {
            'status': overall_status,
            'timestamp': datetime.utcnow().isoformat() + 'Z',
            'duration_ms': round(total_duration * 1000, 2),
            'checks': results,
        }

        # Cache results
        self._cached_status = status
        self._last_check_time = datetime.utcnow()

        return status

    def get_status(self) -> str:
        """Get simple status string."""
        result = self.run_checks()
        return result['status']

    def is_healthy(self) -> bool:
        """Check if system is healthy."""
        return self.get_status() == HealthStatus.HEALTHY


# Default health check instance
_health_check = HealthCheck()


def get_health_check() -> HealthCheck:
    """Get the global health check instance."""
    return _health_check


def register_default_checks(
    data_cache: Any = None,
    exchange_interface: Any = None,
) -> None:
    """
    Register default health checks.

    :param data_cache: DataCache instance.
    :param exchange_interface: ExchangeInterface instance.
    """
    health = get_health_check()

    # Database check
    if data_cache:
        def check_database():
            try:
                # Try to query something simple
                data_cache.get_rows_from_datacache('strategies', [])
                return HealthStatus.HEALTHY, 'Database accessible'
            except Exception as e:
                return HealthStatus.UNHEALTHY, str(e)

        health.register_check('database', check_database)

    # Exchange connectivity check
    if exchange_interface:
        def check_exchange():
            try:
                # Try to connect to default exchange
                if exchange_interface.default_exchange:
                    return HealthStatus.HEALTHY, 'Exchange connected'
                return HealthStatus.DEGRADED, 'No default exchange'
            except Exception as e:
                return HealthStatus.UNHEALTHY, str(e)

        health.register_check('exchange', check_exchange)

    # Memory check
    def check_memory():
        try:
            import psutil
            memory = psutil.virtual_memory()
            if memory.percent > 90:
                return HealthStatus.UNHEALTHY, f'Memory usage critical: {memory.percent}%'
            elif memory.percent > 75:
                return HealthStatus.DEGRADED, f'Memory usage high: {memory.percent}%'
            return HealthStatus.HEALTHY, f'Memory usage: {memory.percent}%'
        except ImportError:
            return HealthStatus.HEALTHY, 'Memory check unavailable (psutil not installed)'
        except Exception as e:
            return HealthStatus.DEGRADED, str(e)

    health.register_check('memory', check_memory)

    # Heartbeat check (always healthy if reached)
    def check_heartbeat():
        return HealthStatus.HEALTHY, 'Service alive'

    health.register_check('heartbeat', check_heartbeat)

    logger.info("Default health checks registered")


def health_endpoint() -> Dict[str, Any]:
    """
    Flask/FastAPI compatible health endpoint function.

    Returns health status as JSON-serializable dict.
    """
    return get_health_check().run_checks()


def liveness_probe() -> bool:
    """Simple liveness probe for Kubernetes."""
    return True


def readiness_probe() -> bool:
    """Readiness probe checking if service is ready to accept traffic."""
    return get_health_check().is_healthy()
