"""
Web dashboard for displaying health check status.
"""

from flask import Flask, render_template_string, jsonify
import logging
from typing import Dict, Any, List
from datetime import datetime, timedelta
from ..core.checker import HealthCheckResult

logger = logging.getLogger(__name__)


class WebDashboard:
    """Web dashboard for displaying real-time health check status."""
    
    def __init__(self, config: Dict[str, Any]):
        """
        Initialize web dashboard.
        
        Args:
            config: Dashboard configuration
        """
        self.config = config
        self.enabled = config.get('enabled', False)
        self.host = config.get('host', '0.0.0.0')
        self.port = config.get('port', 8080)
        self.debug = config.get('debug', False)
        
        # Storage for health check results
        self.service_status: Dict[str, HealthCheckResult] = {}
        self.historical_data: Dict[str, List[HealthCheckResult]] = {}
        self.max_history = config.get('max_history_items', 100)
        
        self.app = None
        self.logger = logging.getLogger(f'{__name__}.{self.__class__.__name__}')
    
    def initialize_app(self):
        """Initialize Flask application."""
        if self.app is not None:
            return self.app
        
        self.app = Flask(__name__)
        self.app.config['SECRET_KEY'] = 'openhealth_secret_key'
        
        # Setup routes
        self._setup_routes()
        
        self.logger.info("Web dashboard Flask app initialized")
        return self.app
    
    def _setup_routes(self):
        """Setup Flask routes."""
        
        @self.app.route('/')
        def index():
            """Main dashboard page."""
            return render_template_string(DASHBOARD_TEMPLATE, 
                                       services=self.service_status,
                                       config=self.config)
        
        @self.app.route('/api/status')
        def api_status():
            """API endpoint for current status."""
            status_data = {}
            for name, result in self.service_status.items():
                status_data[name] = result.to_dict()
            
            return jsonify({
                'timestamp': datetime.now().isoformat(),
                'services': status_data
            })
        
        @self.app.route('/api/history/<service_name>')
        def api_history(service_name):
            """API endpoint for service history."""
            history = self.historical_data.get(service_name, [])
            history_data = [result.to_dict() for result in history[-50:]]  # Last 50 results
            
            return jsonify({
                'service_name': service_name,
                'history': history_data
            })
        
        @self.app.route('/api/summary')
        def api_summary():
            """API endpoint for summary statistics."""
            summary = {
                'total_services': len(self.service_status),
                'healthy_services': 0,
                'unhealthy_services': 0,
                'error_services': 0,
                'last_check': None,
                'uptime_percentage': {}
            }
            
            for name, result in self.service_status.items():
                if result.is_healthy():
                    summary['healthy_services'] += 1
                elif result.status == 'unhealthy':
                    summary['unhealthy_services'] += 1
                else:  # error
                    summary['error_services'] += 1
                
                # Calculate uptime percentage for last 24 hours
                history = self.historical_data.get(name, [])
                if history:
                    recent_checks = [h for h in history 
                                   if h.timestamp > datetime.now() - timedelta(hours=24)]
                    if recent_checks:
                        healthy_count = sum(1 for h in recent_checks if h.is_healthy())
                        summary['uptime_percentage'][name] = (healthy_count / len(recent_checks)) * 100
                
                # Track last check time
                if summary['last_check'] is None or result.timestamp > summary['last_check']:
                    summary['last_check'] = result.timestamp.isoformat()
            
            return jsonify(summary)
    
    def update_service_status(self, result: HealthCheckResult):
        """
        Update service status with new健康 check result.
        
        Args:
            result: New health check result
        """
        service_name = result.service_name
        
        # Update current status
        self.service_status[service_name] = result
        
        # Add to historical data
        if service_name not in self.historical_data:
            self.historical_data[service_name] = []
        
        self.historical_data[service_name].append(result)
        
        # Limit history size
        if len(self.historical_data[service_name]) > self.max_history:
            self.historical_data[service_name] = self.historical_data[service_name][-self.max_history:]
        
        self.logger.debug(f"Updated status for {service_name}: {result.status}")
    
    def get_service_status(self, service_name: str) -> HealthCheckResult:
        """
        Get current status for a specific service.
        
        Args:
            service_name: Name of the service
            
        Returns:
            HealthCheckResult object or None if not found
        """
        return self.service_status.get(service_name)
    
    def get_all_status(self) -> Dict[str, HealthCheckResult]:
        """
        Get all service statuses.
        
        Returns:
            Dictionary of service names to HealthCheckResult objects
        """
        return self.service_status.copy()
    
    def run(self, **kwargs):
        """
        Start the web dashboard server.
        
        Args:
            **kwargs: Additional Flask run arguments
        """
        if not self.enabled:
            self.logger.info("Web dashboard is disabled, not starting server")
            return
        
        if self.app is None:
            self.initialize_app()
        
        run_kwargs = {
            'host': self.host,
            'port': self.port,
            'debug': self.debug,
            'threaded': True,
            'use_reloader': False  # Important: disable reloader in threaded mode
        }
        run_kwargs.update(kwargs)
        
        self.logger.info(f"Starting web dashboard on http://{self.host}:{self.port}")
        
        try:
            self.app.run(**run_kwargs)
        except Exception as e:
            self.logger.error(f"Failed to start web dashboard: {e}")
            raise
    
    def stop(self):
        """Stop the web dashboard server."""
        if self.app:
            self.logger.info("Web dashboard stopped")


# HTML Template for Dashboard
DASHBOARD_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Health Checker Dashboard</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background-color: #f5f5f5;
            color: #333;
        }
        
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 1rem 2rem;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .header h1 {
            font-size: 1.8rem;
            font-weight: 600;
        }
        
        .header p {
            opacity: 0.9;
            margin-top: 0.5rem;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }
        
        .summary {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1rem;
            margin-bottom: 2rem;
        }
        
        .summary-card {
            background: white;
            padding: 1.5rem;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            text-align: center;
        }
        
        .summary-card h3 {
            font-size: 2rem;
            margin-bottom: 0.5rem;
        }
        
        .summary-card p {
            color: #666;
            font-weight: 500;
        }
        
        .services-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 1.5rem;
        }
        
        .service-card {
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            overflow: hidden;
            transition: transform 0.2s, box-shadow 0.2s;
        }
        
        .service-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.15);
        }
        
        .service-header {
            padding: 1rem;
            border-bottom: 1px solid #eee;
        }
        
        .service-name {
            font-size: 1.2rem;
            font-weight: 600;
            margin-bottom: 0.5rem;
        }
        
        .service-url {
            color: #666;
            font-size: 0.9rem;
            word-break: break-all;
        }
        
        .service-status {
            padding: 1.5rem;
            text-align: center;
        }
        
        .status-healthy {
            background-color: #d4edda;
            color: #155724;
        }
        
        .status-unhealthy {
            background-color: #fff3cd;
            color: #856404;
        }
        
        .status-error {
            background-color: #f8d7da;
            color: #721c24;
        }
        
        .status-icon {
            font-size: 3rem;
            margin-bottom: 1rem;
        }
        
        .status-text {
            font-size: 1.1rem;
            font-weight: 600;
            margin-bottom: 0.5rem;
        }
        
        .status-details {
            font-size: 0.9rem;
            opacity: 0.8;
        }
        
        .refresh-info {
            text-align: center;
            margin-top: 2rem;
            color: #666;
        }
        
        .auto-refresh {
            display: inline-block;
            background: #007bff;
            color: white;
            padding: 0.5rem 1rem;
            border-radius: 4px;
            text-decoration: none;
            font-size: 0.9rem;
        }
        
        .auto-refresh:hover {
            background: #0056b3;
        }
        
        @media (max-width: 768px) {
            .container {
                padding: 1rem;
            }
            
            .services-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🏥 Health Checker Dashboard</h1>
        <p>Real-time monitoring of service health and availability</p>
    </div>
    
    <div class="container">
        <div class="summary">
            <div class="summary-card">
                <h3 id="total-services">{{ services|length }}</h3>
                <p>Total Services</p>
            </div>
            <div class="summary-card" style="background-color: #d4edda;">
                <h3 id="healthy-services">{{ services|selectattr('status', 'equalto', 'healthy')|list|length }}</h3>
                <p style="color: #155724;">Healthy</p>
            </div>
            <div class="summary-card" style="background-color: #fff3cd;">
                <h3 id="unhealthy-services">{{ services|selectattr('status', 'equalto', 'unhealthy')|list|length }}</h3>
                <p style="color: #856404;">Unhealthy</p>
            </div>
            <div class="summary-card" style="background-color: #f8d7da;">
                <h3 id="error-services">{{ services|selectattr('status', 'equalto', 'error')|list|length }}</h3>
                <p style="color: #721c24;">Errors</p>
            </div>
        </div>
        
        <div class="services-grid">
            {% for service_name, result in services.items() %}
            <div class="service-card">
                <div class="service-header">
                    <div class="service-name">{{ result.service_name }}</div>
                    <div class="service-url">{{ result.url }}</div>
                </div>
                <div class="service-status status-{{ result.status }}">
                    <div class="status-icon">
                        {% if result.status == 'healthy' %}✅
                        {% elif result.status == 'unhealthy' %}⚠️
                        {% else %}🚨{% endif %}
                    </div>
                    <div class="status-text">{{ result.status|title }}</div>
                    <div class="status-details">
                        <div>Response: {{ "%.2f"|format(result.response_time * 1000) }}ms</div>
                        <div>Last check: {{ result.timestamp.strftime('%H:%M:%S') }}</div>
                        {% if result.error_message %}
                        <div>Error: {{ result.error_message }}</div>
                        {% endif %}
                        {% if result.status_code %}
                        <div>Status: {{ result.status_code }}</div>
                        {% endif %}
                    </div>
                </div>
            </div>
            {% endfor %}
        </div>
        
        <div class="refresh-info">
            <p>Auto-refresh every 30 seconds</p>
            <a href="#" class="auto-refresh" onclick="location.reload()">Refresh Now</a>
        </div>
    </div>
    
    <script>
        // Auto-refresh every 30 seconds
        setTimeout(() => {
            location.reload();
        }, 30000);
        
        // Update last update time
        const updateTime = () => {
            const now = new Date();
            document.title = `Health Checker - ${now.toLocaleTimeString()}`;
        };
        
        updateTime();
        setInterval(updateTime, 1000);
    </script>
</body>
</html>
"""