"""
Advanced health monitoring example with notifications and custom logic.

This example demonstrates advanced features including:
- Multiple notification channels
- Custom alerting logic
- Service dependencies
- Business hours monitoring
"""

import json
import time
from datetime import datetime, time as dt_time
from openHealth import HealthChecker


def create_advanced_config():
    """Create an advanced configuration with all features enabled."""
    config = {
        "services": [
            {
                "name": "Main API",
                "url": "https://httpbin.org",
                "health_endpoint": "/status/200",
                "interval": 30,
                "timeout": 10,
                "max_retries": 3,
                "expected_status_code": 200,
                "web_interface": {
                    "enabled": True
                },
                "email_alert": {
                    "enabled": True,
                    "recipients": [
                        "admin@example.com",
                        "ops@example.com",
                        "dev@example.com"
                    ],
                    "smtp_server": "smtp.gmail.com",
                    "smtp_port": 587,
                    "username": "alerts@example.com",
                    "app_password": "your-app-password"
                },
                "slack_integration": {
                    "enabled": True,
                    "channel": "#production-alerts",
                    "api_key": "xoxb-your-slack-api-key",
                    "message_template": "🚨 CRITICAL ALERT: {name} is {status}\nURL: {url}\nError: {error}\nTime: {timestamp}"
                }
            },
            {
                "name": "Database API",
                "url": "https://httpbin.org",
                "health_endpoint": "/status/500",
                "interval": 15,
                "timeout": 5,
                "max_retries": 5,
                "expected_status_code": 500,  # Simulating a failing service
                "web_interface": {
                    "enabled": True
                },
                "email_alert": {
                    "enabled": True,
                    "recipients": ["dba@example.com"],
                    "smtp_server": "smtp.gmail.com",
                    "smtp_port": 587,
                    "username": "alerts@example.com",
                    "app_password": "your-app-password"
                },
                "slack_integration": {
                    "enabled": True,
                    "channel": "#database-alerts",
                    "api_key": "xoxb-your-slack-api-key",
                    "message_template": "🔴 DATABASE ISSUE: {name} is {status}\nError: {error}"
                }
            },
            {
                "name": "Cache Service",
                "url": "https://httpbin.org",
                "health_endpoint": "/status/200",
                "interval": 60,
                "timeout": 3,
                "max_retries": 2,
                "expected_status_code": 200,
                "web_interface": {
                    "enabled": True
                },
                "email_alert": {
                    "enabled": False,  # Cache service not critical for email
                    "recipients": [],
                    "smtp_server": "smtp.gmail.com",
                    "smtp_port": 587,
                    "username": "alerts@example.com",
                    "app_password": "your-app-password"
                },
                "slack_integration": {
                    "enabled": True,
                    "channel": "#performance-alerts",
                    "api_key": "xoxb-your-slack-api-key",
                    "message_template": "⚡ Performance Alert: {name} is {status}"
                }
            }
        ]
    }
    
    with open("advanced_config.json", "w") as f:
        json.dump(config, f, indent=2)
    
    print("Created advanced_config.json")
    return "advanced_config.json"


def is_business_hours():
    """Check if current time is within business hours (9 AM - 6 PM, Mon-Fri)."""
    now = datetime.now()
    
    # Check weekday (0=Monday, 6=Sunday)
    if now.weekday() > 4:  # Saturday or Sunday
        return False
    
    # Check time (9 AM - 6 PM)
    current_time = now.time()
    start_time = dt_time(9, 0)
    end_time = dt_time(18, 0)
    
    return start_time <= current_time <= end_time


class AdvancedMonitor:
    """Advanced monitoring logic with business rules."""
    
    def __init__(self, checker: HealthChecker):
        self.checker = checker
        self.critical_services = ["Main API", "Database API"]
        self.service_history = {}
        self.consecutive_failures = {}
        
        # Add custom callbacks
        self.checker.add_status_callback(self.on_service_check)
        self.checker.add_status_callback(self.critical_service_alert)
        self.checker.add_status_callback(self.performance_monitoring)
    
    def on_service_check(self, result):
        """Basic status callback."""
        # Track history
        service_name = result.service_name
        if service_name not in self.service_history:
            self.service_history[service_name] = []
        
        self.service_history[service_name].append(result)
        
        # Keep only last 10 results
        if len(self.service_history[service_name]) > 10:
            self.service_history[service_name] = self.service_history[service_name][-10:]
        
        # Track consecutive failures
        if not result.is_healthy():
            self.consecutive_failures[service_name] = self.consecutive_failures.get(service_name, 0) + 1
        else:
            self.consecutive_failures[service_name] = 0
    
    def critical_service_alert(self, result):
        """Special handling for critical services."""
        if result.service_name not in self.critical_services:
            return
        
        if not result.is_healthy():
            consecutive = self.consecutive_failures.get(result.service_name, 0)
            
            if consecutive == 1:
                print(f"🚨 CRITICAL: {result.service_name} failed first check")
            elif consecutive == 3:
                print(f"🔥 URGENT: {result.service_name} has failed {consecutive} times consecutively!")
            elif consecutive >= 5:
                print(f"💀 SEVERE: {result.service_name} has failed {consecutive} times consecutively!")
        else:
            if result.service_name in self.consecutive_failures and self.consecutive_failures[result.service_name] > 0:
                print(f"✅ RECOVERED: {result.service_name} is back online after failures")
    
    def performance_monitoring(self, result):
        """Monitor performance and alert on slow responses."""
        if result.is_healthy() and result.response_time > 2.0:  # > 2 seconds
            print(f"🐌 SLOW: {result.service_name} responded in {result.response_time * 1000:.1f}ms")
    
    def business_hours_filter(self, result):
        """Only alert during business hours for non-critical services."""
        if result.service_name in self.critical_services:
            return True  # Always alert for critical services
        
        if not result.is_healthy() and not is_business_hours():
            print(f"🌙 After-hours: {result.service_name} issue detected (no alerts during off-hours)")
            return False
        
        return True


def main():
    """Demonstrate advanced monitoring with custom logic."""
    print("=== Advanced Health Monitoring Example ===\n")
    
    # Create configuration
    config_file = create_advanced_config()
    
    # Show current time and business hours status
    now = datetime.now()
    print(f"Current time: {now.strftime('%Y-%m-%d %H:%M:%S')}")
    print(f"Business hours: {'Yes' if is_business_hours() else 'No'}")
    print()
    
    # Initialize health checker
    print("Initializing advanced health checker...")
    checker = HealthChecker(
        config_path=config_file,
        log_level="INFO",
        log_file="advanced_monitoring.log"
    )
    
    # Setup advanced monitoring logic
    monitor = AdvancedMonitor(checker)
    
    try:
        # Perform initial assessment
        print("Performing initial health assessment...")
        results = checker.check_all_services()
        
        print(f"\n📊 Initial Assessment Results:")
        for name, result in results.items():
            status_icon = "✅" if result.is_healthy() else "⚠️" if result.status == 'unhealthy' else "🚨"
            critical = " [CRITICAL]" if name in monitor.critical_services else ""
            print(f"  {status_icon} {name}{critical}: {result.status} ({result.response_time * 1000:.1f}ms)")
        
        # Start continuous monitoring
        print(f"\n🔄 Starting advanced monitoring with custom logic...")
        print("📱 Web dashboard: http://localhost:8080")
        print("📝 Log file: advanced_monitoring.log")
        print("\nCustom monitoring features:")
        print("  • Critical service tracking with escalation")
        print("  • Performance monitoring for slow responses")
        print("  • Business hours filtering for non-critical alerts")
        print("  • Consecutive failure tracking")
        print("\nPress Ctrl+C to stop...")
        
        checker.start()
        
        # Run demonstration
        try:
            while True:
                time.sleep(15)
                
                # Show periodic status summary
                status = checker.get_status()
                total = len(status)
                healthy = sum(1 for s in status.values() if s['status'] == 'healthy')
                unhealthy = sum(1 for s in status.values() if s['status'] == 'unhealthy')
                errors = sum(1 for s in status.values() if s['status'] == 'error')
                
                print(f"\n📈 Status Summary: {healthy} healthy, {unhealthy} unhealthy, {errors} errors")
                
                # Show services with consecutive failures
                failing_services = {name: count for name, count in monitor.consecutive_failures.items() if count > 0}
                if failing_services:
                    print("⚠️ Services with consecutive failures:", failing_services)
                
        except KeyboardInterrupt:
            print("\nReceived interrupt signal...")
    
    finally:
        print("\nStopping advanced health checker...")
        checker.stop()
        print("Advanced health checker stopped.")


if __name__ == "__main__":
    main()