"""
T221: Dashboard Web MCP Wrapper View
Panel web para visualización en tiempo real del sistema
"""

import http.server
import socketserver
import json
import threading
import os
from datetime import datetime
from typing import Dict, Any, Optional
from urllib.parse import parse_qs, urlparse


class DashboardHandler(http.server.BaseHTTPRequestHandler):
    """Handler HTTP para el dashboard."""
    
    def do_GET(self):
        """Maneja peticiones GET."""
        parsed = urlparse(self.path)
        path = parsed.path
        params = parse_qs(parsed.query)
        
        # API endpoints
        if path == '/api/status':
            self._send_json(self._get_system_status())
        elif path == '/api/metrics':
            self._send_json(self._get_metrics())
        elif path == '/api/generations':
            self._send_json(self._get_generations(params))
        elif path == '/api/health':
            self._send_json(self._get_health())
        elif path == '/api/logs':
            self._send_json(self._get_logs(params))
        elif path == '/api/diversity':
            self._send_json(self._get_diversity_stats())
        else:
            # Dashboard HTML
            self._send_html(self._generate_dashboard_html())
    
    def do_POST(self):
        """Maneja peticiones POST."""
        parsed = urlparse(self.path)
        path = parsed.path
        
        content_length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(content_length).decode('utf-8') if content_length > 0 else '{}'
        
        try:
            data = json.loads(body)
        except:
            data = {}
        
        if path == '/api/generate':
            self._send_json(self._trigger_generation(data))
        elif path == '/api/stop':
            self._send_json(self._stop_generation())
        elif path == '/api/export':
            self._send_json(self._trigger_export(data))
        else:
            self._send_json({'error': 'Unknown endpoint'}, 404)
    
    def _send_json(self, data: Dict[str, Any], status: int = 200):
        """Envía respuesta JSON."""
        self.send_response(status)
        self.send_header('Content-Type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        self.wfile.write(json.dumps(data, indent=2).encode())
    
    def _send_html(self, html: str, status: int = 200):
        """Envía respuesta HTML."""
        self.send_response(status)
        self.send_header('Content-Type', 'text/html; charset=utf-8')
        self.end_headers()
        self.wfile.write(html.encode())
    
    def _get_system_status(self) -> Dict[str, Any]:
        """Obtiene estado del sistema."""
        try:
            from ..cloud.health_checks import get_health_status
            from ..cloud.performance_watchdog import get_performance_status
            
            return {
                'timestamp': datetime.now().isoformat(),
                'health': get_health_status(),
                'performance': get_performance_status(),
                'system': {
                    'version': '2.0.0',
                    'block': 'T216-T235',
                    'status': 'operational'
                }
            }
        except Exception as e:
            return {'error': str(e)}
    
    def _get_metrics(self) -> Dict[str, Any]:
        """Obtiene métricas del sistema."""
        try:
            from ..cloud.stats_visualizer import get_generation_stats
            
            return {
                'timestamp': datetime.now().isoformat(),
                'generation_stats': get_generation_stats(last_n=10),
                'system_metrics': self._collect_system_metrics()
            }
        except Exception as e:
            return {'error': str(e)}
    
    def _get_generations(self, params: Dict) -> Dict[str, Any]:
        """Obtiene lista de generaciones."""
        limit = int(params.get('limit', ['20'])[0])
        
        try:
            # Intentar cargar desde historial
            history_file = os.path.join(
                os.path.dirname(os.path.dirname(__file__)),
                'logs', 'generations', 'history.json'
            )
            
            if os.path.exists(history_file):
                with open(history_file, 'r') as f:
                    history = json.load(f)
                    return {
                        'total': len(history),
                        'generations': history[-limit:]
                    }
            
            return {'total': 0, 'generations': []}
        except Exception as e:
            return {'error': str(e)}
    
    def _get_health(self) -> Dict[str, Any]:
        """Obtiene estado de salud."""
        try:
            from ..cloud.health_checks import get_health_status
            return get_health_status()
        except Exception as e:
            return {'error': str(e)}
    
    def _get_logs(self, params: Dict) -> Dict[str, Any]:
        """Obtiene logs recientes."""
        category = params.get('category', [None])[0]
        limit = int(params.get('limit', ['50'])[0])
        
        try:
            from ..logs.persistent_logs import get_logs
            return {
                'logs': get_logs(category=category, limit=limit),
                'timestamp': datetime.now().isoformat()
            }
        except Exception as e:
            return {'error': str(e)}
    
    def _get_diversity_stats(self) -> Dict[str, Any]:
        """Obtiene estadísticas de diversidad."""
        try:
            from ..cloud.export_system_report import SystemReporter
            reporter = SystemReporter()
            
            return {
                'timestamp': datetime.now().isoformat(),
                'diversity_memory': reporter._get_system_metrics().get('diversity_memory', {}),
                'sample_coverage': reporter._get_system_metrics().get('sample_coverage', {})
            }
        except Exception as e:
            return {'error': str(e)}
    
    def _collect_system_metrics(self) -> Dict[str, Any]:
        """Recolecta métricas del sistema."""
        try:
            import psutil
            
            return {
                'cpu_percent': psutil.cpu_percent(interval=1),
                'memory': {
                    'percent': psutil.virtual_memory().percent,
                    'available_gb': psutil.virtual_memory().available / 1024**3
                },
                'disk': {
                    'percent': psutil.disk_usage('/').percent,
                    'free_gb': psutil.disk_usage('/').free / 1024**3
                }
            }
        except:
            return {'error': 'psutil not available'}
    
    def _trigger_generation(self, data: Dict) -> Dict[str, Any]:
        """Dispara una generación."""
        genre = data.get('genre', 'techno')
        style = data.get('style', 'standard')
        bpm = data.get('bpm', 128)
        key = data.get('key', 'Am')
        
        # En producción, llamaría al generador real
        return {
            'status': 'queued',
            'genre': genre,
            'style': style,
            'bpm': bpm,
            'key': key,
            'estimated_duration': '3-5 minutes',
            'timestamp': datetime.now().isoformat()
        }
    
    def _stop_generation(self) -> Dict[str, Any]:
        """Detiene generación actual."""
        return {
            'status': 'stopped',
            'timestamp': datetime.now().isoformat()
        }
    
    def _trigger_export(self, data: Dict) -> Dict[str, Any]:
        """Dispara exportación."""
        format_type = data.get('format', 'json')
        
        try:
            from ..cloud.export_system_report import export_system_report
            return export_system_report(format=format_type)
        except Exception as e:
            return {'error': str(e)}
    
    def _generate_dashboard_html(self) -> str:
        """Genera HTML del dashboard."""
        return '''<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AbletonMCP-AI Dashboard</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            color: #fff;
            min-height: 100vh;
        }
        .header {
            background: rgba(0,0,0,0.3);
            padding: 20px 40px;
            border-bottom: 1px solid rgba(255,255,255,0.1);
        }
        .header h1 {
            font-size: 24px;
            font-weight: 600;
        }
        .header .subtitle {
            color: #888;
            font-size: 14px;
            margin-top: 5px;
        }
        .container {
            padding: 40px;
            max-width: 1400px;
            margin: 0 auto;
        }
        .grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }
        .card {
            background: rgba(255,255,255,0.05);
            border-radius: 12px;
            padding: 20px;
            border: 1px solid rgba(255,255,255,0.1);
        }
        .card h3 {
            font-size: 14px;
            text-transform: uppercase;
            letter-spacing: 1px;
            color: #888;
            margin-bottom: 15px;
        }
        .metric {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 0;
            border-bottom: 1px solid rgba(255,255,255,0.05);
        }
        .metric:last-child { border-bottom: none; }
        .metric-value {
            font-size: 24px;
            font-weight: 600;
        }
        .metric-value.success { color: #4CAF50; }
        .metric-value.warning { color: #FF9800; }
        .metric-value.error { color: #f44336; }
        .status-indicator {
            display: inline-block;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            margin-right: 8px;
        }
        .status-indicator.healthy { background: #4CAF50; }
        .status-indicator.warning { background: #FF9800; }
        .status-indicator.critical { background: #f44336; }
        .btn {
            background: #4CAF50;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: background 0.3s;
        }
        .btn:hover { background: #45a049; }
        .btn-secondary {
            background: rgba(255,255,255,0.1);
        }
        .btn-secondary:hover { background: rgba(255,255,255,0.2); }
        .actions {
            display: flex;
            gap: 10px;
            margin-top: 20px;
        }
        .logs-container {
            background: rgba(0,0,0,0.3);
            border-radius: 8px;
            padding: 15px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            max-height: 300px;
            overflow-y: auto;
        }
        .log-entry {
            padding: 5px 0;
            border-bottom: 1px solid rgba(255,255,255,0.05);
        }
        .refresh-info {
            text-align: center;
            color: #666;
            font-size: 12px;
            margin-top: 20px;
        }
        .chart-placeholder {
            background: rgba(0,0,0,0.2);
            border-radius: 8px;
            height: 200px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🎵 AbletonMCP-AI Dashboard</h1>
        <div class="subtitle">Block 6 - T216-T235 | Real-time System Monitor</div>
    </div>
    
    <div class="container">
        <div class="grid">
            <div class="card">
                <h3>System Health</h3>
                <div id="health-status">
                    <div class="metric">
                        <span>Overall Status</span>
                        <span class="metric-value success">
                            <span class="status-indicator healthy"></span>Healthy
                        </span>
                    </div>
                    <div class="metric">
                        <span>Ableton Connection</span>
                        <span class="metric-value success">Connected</span>
                    </div>
                    <div class="metric">
                        <span>Sample Library</span>
                        <span class="metric-value success">Available</span>
                    </div>
                    <div class="metric">
                        <span>MCP Wrapper</span>
                        <span class="metric-value success">Active</span>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <h3>Performance Metrics</h3>
                <div id="performance-metrics">
                    <div class="metric">
                        <span>CPU Usage</span>
                        <span class="metric-value" id="cpu-value">--%</span>
                    </div>
                    <div class="metric">
                        <span>Memory Usage</span>
                        <span class="metric-value" id="memory-value">--%</span>
                    </div>
                    <div class="metric">
                        <span>Audio Latency</span>
                        <span class="metric-value" id="latency-value">-- ms</span>
                    </div>
                    <div class="metric">
                        <span>Active Generations</span>
                        <span class="metric-value" id="active-gen-value">0</span>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <h3>Generation Statistics</h3>
                <div id="gen-stats">
                    <div class="metric">
                        <span>Total Generations</span>
                        <span class="metric-value" id="total-gen">--</span>
                    </div>
                    <div class="metric">
                        <span>Average Rating</span>
                        <span class="metric-value" id="avg-rating">--</span>
                    </div>
                    <div class="metric">
                        <span>Success Rate</span>
                        <span class="metric-value" id="success-rate">--%</span>
                    </div>
                    <div class="metric">
                        <span>Last Generation</span>
                        <span class="metric-value" id="last-gen">--</span>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <h3>Quick Actions</h3>
                <div class="actions">
                    <button class="btn" onclick="triggerGenerate()">🎵 Generate Track</button>
                    <button class="btn btn-secondary" onclick="exportReport()">📊 Export Report</button>
                </div>
                <div class="actions">
                    <button class="btn btn-secondary" onclick="startMonitoring()">⏱️ Start Monitoring</button>
                    <button class="btn btn-secondary" onclick="runHealthCheck()">🏥 Health Check</button>
                </div>
            </div>
        </div>
        
        <div class="card">
            <h3>Recent Logs</h3>
            <div class="logs-container" id="logs">
                <div class="log-entry">[SYSTEM] Dashboard initialized...</div>
                <div class="log-entry">[SYSTEM] Waiting for data...</div>
            </div>
        </div>
        
        <div class="refresh-info">
            Dashboard auto-refreshes every 30 seconds | Last update: <span id="last-update">--</span>
        </div>
    </div>
    
    <script>
        let refreshInterval;
        
        async function fetchData() {
            try {
                const response = await fetch('/api/status');
                const data = await response.json();
                updateDashboard(data);
            } catch (error) {
                console.error('Error fetching data:', error);
                addLog('Error fetching data: ' + error.message, 'error');
            }
        }
        
        function updateDashboard(data) {
            document.getElementById('last-update').textContent = new Date().toLocaleTimeString();
            
            if (data.system_metrics) {
                document.getElementById('cpu-value').textContent = 
                    (data.system_metrics.cpu_percent || '--') + '%';
                document.getElementById('memory-value').textContent = 
                    (data.system_metrics.memory?.percent || '--') + '%';
            }
            
            if (data.generation_stats) {
                const stats = data.generation_stats.summary || {};
                document.getElementById('total-gen').textContent = stats.total_generations || '--';
                document.getElementById('avg-rating').textContent = 
                    (stats.overall_average_rating || '--').toFixed(1);
                document.getElementById('success-rate').textContent = 
                    Math.round(stats.success_rate || 0) + '%';
            }
            
            addLog('[UPDATE] Dashboard refreshed', 'info');
        }
        
        function addLog(message, level) {
            const logs = document.getElementById('logs');
            const entry = document.createElement('div');
            entry.className = 'log-entry';
            entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
            logs.insertBefore(entry, logs.firstChild);
            
            while (logs.children.length > 50) {
                logs.removeChild(logs.lastChild);
            }
        }
        
        async function triggerGenerate() {
            addLog('[ACTION] Triggering track generation...', 'info');
            try {
                const response = await fetch('/api/generate', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({genre: 'techno', bpm: 128})
                });
                const data = await response.json();
                addLog(`[GENERATE] ${data.status}: ${data.genre} at ${data.bpm} BPM`, 'success');
            } catch (error) {
                addLog('[ERROR] Generation failed: ' + error.message, 'error');
            }
        }
        
        async function exportReport() {
            addLog('[ACTION] Exporting system report...', 'info');
            try {
                const response = await fetch('/api/export', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({format: 'json'})
                });
                const data = await response.json();
                if (data.success) {
                    addLog(`[EXPORT] Report saved to: ${data.filepath}`, 'success');
                } else {
                    addLog('[ERROR] Export failed: ' + data.error, 'error');
                }
            } catch (error) {
                addLog('[ERROR] Export failed: ' + error.message, 'error');
            }
        }
        
        async function startMonitoring() {
            addLog('[ACTION] Starting performance monitoring...', 'info');
            // Implementación real llamaría al endpoint
            addLog('[MONITOR] Performance monitoring started (3 hours)', 'success');
        }
        
        async function runHealthCheck() {
            addLog('[ACTION] Running health check...', 'info');
            try {
                const response = await fetch('/api/health');
                const data = await response.json();
                addLog(`[HEALTH] Overall: ${data.overall_status}`, 
                       data.overall_status === 'healthy' ? 'success' : 'warning');
            } catch (error) {
                addLog('[ERROR] Health check failed: ' + error.message, 'error');
            }
        }
        
        // Auto-refresh
        function startRefresh() {
            fetchData();
            refreshInterval = setInterval(fetchData, 30000);
        }
        
        startRefresh();
    </script>
</body>
</html>'''


class DashboardServer:
    """Servidor del Dashboard Web."""
    
    DEFAULT_PORT = 8765
    
    def __init__(self, port: int = DEFAULT_PORT):
        self.port = port
        self.server: Optional[socketserver.TCPServer] = None
        self.server_thread: Optional[threading.Thread] = None
    
    def start(self) -> Dict[str, Any]:
        """Inicia el servidor del dashboard."""
        try:
            self.server = socketserver.TCPServer(('', self.port), DashboardHandler)
            self.server_thread = threading.Thread(target=self.server.serve_forever, daemon=True)
            self.server_thread.start()
            
            return {
                'status': 'started',
                'port': self.port,
                'url': f'http://localhost:{self.port}',
                'timestamp': datetime.now().isoformat()
            }
        except Exception as e:
            return {
                'status': 'error',
                'error': str(e)
            }
    
    def stop(self) -> Dict[str, Any]:
        """Detiene el servidor del dashboard."""
        if self.server:
            self.server.shutdown()
            self.server.server_close()
            
        return {
            'status': 'stopped',
            'timestamp': datetime.now().isoformat()
        }


# Instancia global
_dashboard_server: Optional[DashboardServer] = None

def start_dashboard(port: int = 8765) -> Dict[str, Any]:
    """
    Inicia el panel web del dashboard.
    
    Args:
        port: Puerto para el servidor web (default 8765)
        
    Returns:
        Estado del servidor
    """
    global _dashboard_server
    
    if _dashboard_server is None:
        _dashboard_server = DashboardServer(port=port)
    
    return _dashboard_server.start()


def stop_dashboard() -> Dict[str, Any]:
    """Detiene el panel web del dashboard."""
    global _dashboard_server
    
    if _dashboard_server is None:
        return {'status': 'not_running'}
    
    return _dashboard_server.stop()


def get_dashboard_url() -> str:
    """Retorna URL del dashboard."""
    if _dashboard_server and _dashboard_server.server:
        return f'http://localhost:{_dashboard_server.port}'
    return 'not_started'


if __name__ == '__main__':
    # Test del dashboard
    result = start_dashboard()
    print("Dashboard:", result)
    
    print("\nPress Enter to stop...")
    input()
    
    stop_dashboard()
