from flask import Blueprint, render_template, jsonify, request, session
from functools import wraps
import psycopg2
from psycopg2.extras import RealDictCursor
import os
import requests
from datetime import datetime, timedelta
import logging
from utils.partition_helper import ensure_partition_exists, check_table_exists

monitoring_bp = Blueprint('monitoring', __name__)
logger = logging.getLogger(__name__)

# Database connection
def get_db_connection():
    return psycopg2.connect(
        host=os.environ.get('POSTGRES_HOST', 'postgres'),
        database=os.environ.get('POSTGRES_DB', 'v2_adminpanel'),
        user=os.environ.get('POSTGRES_USER', 'postgres'),
        password=os.environ.get('POSTGRES_PASSWORD', 'postgres')
    )

# Login required decorator
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'logged_in' not in session:
            return render_template('error.html', 
                                 error_message='Nicht autorisiert',
                                 details='Sie müssen angemeldet sein, um diese Seite zu sehen.')
        return f(*args, **kwargs)
    return decorated_function

@monitoring_bp.route('/live-dashboard')
@login_required
def live_dashboard():
    """Live Dashboard showing active customer sessions and analytics"""
    try:
        conn = get_db_connection()
        cur = conn.cursor(cursor_factory=RealDictCursor)
        
        # Check if license_heartbeats table exists
        if not check_table_exists(conn, 'license_heartbeats'):
            logger.warning("license_heartbeats table does not exist")
            # Return empty data
            return render_template('monitoring/live_dashboard.html',
                                 active_sessions=[],
                                 stats={'active_licenses': 0, 'active_devices': 0, 'total_heartbeats': 0},
                                 validation_timeline=[],
                                 live_stats=[0, 0, 0, 0],
                                 validation_rates=[],
                                 recent_anomalies=[],
                                 top_licenses=[])
        
        # Ensure current month partition exists
        ensure_partition_exists(conn, 'license_heartbeats', datetime.now())
        
        # Get active customer sessions (last 5 minutes)
        cur.execute("""
            SELECT 
                l.id,
                l.license_key,
                c.name as company_name,
                lh.hardware_id,
                lh.ip_address,
                lh.timestamp as last_activity,
                lh.session_data,
                COUNT(DISTINCT lh.hardware_id) OVER (PARTITION BY l.id) as active_devices
            FROM license_heartbeats lh
            JOIN licenses l ON l.id = lh.license_id
            JOIN customers c ON c.id = l.customer_id
            WHERE lh.timestamp > NOW() - INTERVAL '5 minutes'
            AND l.is_active = true
            ORDER BY lh.timestamp DESC
            LIMIT 100
        """)
        active_sessions = cur.fetchall()
        
        # Get session statistics
        cur.execute("""
            SELECT 
                COUNT(DISTINCT license_id) as active_licenses,
                COUNT(DISTINCT hardware_id) as active_devices,
                COUNT(*) as total_heartbeats
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '5 minutes'
        """)
        stats = cur.fetchone()
        
        # Get validations per minute (for both charts)
        cur.execute("""
            SELECT 
                DATE_TRUNC('minute', timestamp) as minute,
                COUNT(*) as validations
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '60 minutes'
            GROUP BY minute
            ORDER BY minute DESC
            LIMIT 60
        """)
        validation_timeline = cur.fetchall()
        
        # Get live statistics for analytics cards
        cur.execute("""
            SELECT 
                COUNT(DISTINCT license_id) as active_licenses,
                COUNT(*) as total_validations,
                COUNT(DISTINCT hardware_id) as unique_devices,
                COUNT(DISTINCT ip_address) as unique_ips
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '5 minutes'
        """)
        live_stats_data = cur.fetchone()
        live_stats = [
            live_stats_data['active_licenses'] or 0,
            live_stats_data['total_validations'] or 0,
            live_stats_data['unique_devices'] or 0,
            live_stats_data['unique_ips'] or 0
        ]
        
        # Get validation rates for analytics chart (last 30 minutes)
        cur.execute("""
            SELECT 
                DATE_TRUNC('minute', timestamp) as minute,
                COUNT(*) as count
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '30 minutes'
            GROUP BY minute
            ORDER BY minute DESC
            LIMIT 30
        """)
        validation_rates = [(row['minute'].isoformat(), row['count']) for row in cur.fetchall()]
        
        # Get recent anomalies
        cur.execute("""
            SELECT 
                ad.*,
                l.license_key,
                c.name as customer_name
            FROM anomaly_detections ad
            LEFT JOIN licenses l ON l.id = ad.license_id
            LEFT JOIN customers c ON c.id = l.customer_id
            WHERE ad.detected_at > NOW() - INTERVAL '24 hours'
            ORDER BY ad.detected_at DESC
            LIMIT 10
        """)
        recent_anomalies = cur.fetchall()
        
        # Get top active licenses
        cur.execute("""
            SELECT 
                l.license_key,
                c.name as customer_name,
                COUNT(DISTINCT lh.hardware_id) as device_count,
                COUNT(*) as validation_count,
                MAX(lh.timestamp) as last_seen
            FROM license_heartbeats lh
            JOIN licenses l ON l.id = lh.license_id
            JOIN customers c ON c.id = l.customer_id
            WHERE lh.timestamp > NOW() - INTERVAL '15 minutes'
            GROUP BY l.license_key, c.name
            ORDER BY validation_count DESC
            LIMIT 10
        """)
        top_licenses = cur.fetchall()
        
        cur.close()
        conn.close()
        
        return render_template('monitoring/live_dashboard.html',
                             active_sessions=active_sessions,
                             stats=stats,
                             validation_timeline=validation_timeline,
                             live_stats=live_stats,
                             validation_rates=validation_rates,
                             recent_anomalies=recent_anomalies,
                             top_licenses=top_licenses)
        
    except Exception as e:
        logger.error(f"Error in live dashboard: {str(e)}")
        return render_template('error.html', 
                             error_message='Fehler beim Laden des Dashboards',
                             details=str(e))

@monitoring_bp.route('/system-status')
@login_required
def system_status():
    """System status showing service health"""
    services = []
    
    # Check each service
    service_checks = [
        {'name': 'License Server', 'url': 'http://license-server:8443/health', 'port': 8443},
        {'name': 'PostgreSQL', 'check': 'database'},
    ]
    
    for service in service_checks:
        status = {'name': service['name'], 'status': 'unknown', 'response_time': None}
        
        try:
            if service.get('check') == 'database':
                # Check database
                start = datetime.now()
                conn = get_db_connection()
                conn.close()
                status['status'] = 'healthy'
                status['response_time'] = (datetime.now() - start).total_seconds() * 1000
            elif service.get('url'):
                # Check HTTP service
                start = datetime.now()
                response = requests.get(service['url'], timeout=2)
                if response.status_code == 200:
                    status['status'] = 'healthy'
                else:
                    status['status'] = 'unhealthy'
                status['response_time'] = (datetime.now() - start).total_seconds() * 1000
        except:
            status['status'] = 'down'
            
        services.append(status)
    
    # Get Prometheus metrics if available
    prometheus_data = None
    try:
        response = requests.get('http://prometheus:9090/api/v1/query', 
                              params={'query': 'up'}, timeout=2)
        if response.status_code == 200:
            prometheus_data = response.json()
    except:
        pass
    
    return render_template('monitoring/system_status.html',
                         services=services,
                         prometheus_data=prometheus_data)

@monitoring_bp.route('/alerts')
@login_required
def alerts():
    """Show active alerts from Alertmanager"""
    alerts = []
    
    try:
        # Get alerts from Alertmanager
        response = requests.get('http://alertmanager:9093/api/v1/alerts', timeout=2)
        if response.status_code == 200:
            alerts = response.json()
    except:
        # Fallback to database anomalies
        conn = get_db_connection()
        cur = conn.cursor(cursor_factory=RealDictCursor)
        
        cur.execute("""
            SELECT 
                ad.*,
                l.license_key,
                c.name as company_name
            FROM anomaly_detections ad
            LEFT JOIN licenses l ON l.id = ad.license_id
            LEFT JOIN customers c ON c.id = l.customer_id
            WHERE ad.resolved = false
            ORDER BY ad.detected_at DESC
            LIMIT 50
        """)
        alerts = cur.fetchall()
        
        cur.close()
        conn.close()
    
    return render_template('monitoring/alerts.html', alerts=alerts)

@monitoring_bp.route('/analytics')
@login_required
def analytics():
    """Combined analytics and license server status page"""
    try:
        conn = get_db_connection()
        cur = conn.cursor(cursor_factory=RealDictCursor)
        
        # Get live statistics for the top cards
        cur.execute("""
            SELECT 
                COUNT(DISTINCT license_id) as active_licenses,
                COUNT(*) as total_validations,
                COUNT(DISTINCT hardware_id) as unique_devices,
                COUNT(DISTINCT ip_address) as unique_ips
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '5 minutes'
        """)
        live_stats = cur.fetchone()
        live_stats = [
            live_stats['active_licenses'] or 0,
            live_stats['total_validations'] or 0,
            live_stats['unique_devices'] or 0,
            live_stats['unique_ips'] or 0
        ]
        
        # Get validation rates for chart
        cur.execute("""
            SELECT 
                DATE_TRUNC('minute', timestamp) as minute,
                COUNT(*) as count
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '30 minutes'
            GROUP BY minute
            ORDER BY minute DESC
            LIMIT 30
        """)
        validation_rates = [(row['minute'].isoformat(), row['count']) for row in cur.fetchall()]
        
        # Get recent anomalies
        cur.execute("""
            SELECT 
                ad.*,
                l.license_key,
                c.name as customer_name
            FROM anomaly_detections ad
            LEFT JOIN licenses l ON l.id = ad.license_id
            LEFT JOIN customers c ON c.id = l.customer_id
            WHERE ad.detected_at > NOW() - INTERVAL '24 hours'
            ORDER BY ad.detected_at DESC
            LIMIT 10
        """)
        recent_anomalies = cur.fetchall()
        
        # Get top active licenses
        cur.execute("""
            SELECT 
                l.license_key,
                c.name as customer_name,
                COUNT(DISTINCT lh.hardware_id) as device_count,
                COUNT(*) as validation_count,
                MAX(lh.timestamp) as last_seen
            FROM license_heartbeats lh
            JOIN licenses l ON l.id = lh.license_id
            JOIN customers c ON c.id = l.customer_id
            WHERE lh.timestamp > NOW() - INTERVAL '15 minutes'
            GROUP BY l.license_key, c.name
            ORDER BY validation_count DESC
            LIMIT 10
        """)
        top_licenses = cur.fetchall()
        
        cur.close()
        conn.close()
        
        return render_template('monitoring/analytics.html',
                             live_stats=live_stats,
                             validation_rates=validation_rates,
                             recent_anomalies=recent_anomalies,
                             top_licenses=top_licenses)
        
    except Exception as e:
        logger.error(f"Error in analytics: {str(e)}")
        return render_template('monitoring/analytics.html',
                             live_stats=[0, 0, 0, 0],
                             validation_rates=[],
                             recent_anomalies=[],
                             top_licenses=[])

# API endpoints for live data
@monitoring_bp.route('/api/live-stats')
@login_required
def api_live_stats():
    """API endpoint for live statistics"""
    try:
        conn = get_db_connection()
        cur = conn.cursor(cursor_factory=RealDictCursor)
        
        # Get current stats
        cur.execute("""
            SELECT 
                COUNT(DISTINCT license_id) as active_licenses,
                COUNT(DISTINCT hardware_id) as active_devices,
                COUNT(*) as validations_last_minute
            FROM license_heartbeats
            WHERE timestamp > NOW() - INTERVAL '1 minute'
        """)
        stats = cur.fetchone()
        
        cur.close()
        conn.close()
        
        return jsonify(stats)
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@monitoring_bp.route('/api/active-sessions')
@login_required
def api_active_sessions():
    """API endpoint for active customer sessions"""
    try:
        conn = get_db_connection()
        cur = conn.cursor(cursor_factory=RealDictCursor)
        
        # Get active sessions with geo data
        cur.execute("""
            SELECT 
                l.license_key,
                c.name as company_name,
                lh.hardware_id,
                lh.ip_address,
                lh.timestamp as last_activity,
                EXTRACT(EPOCH FROM (NOW() - lh.timestamp)) as seconds_ago,
                lh.session_data
            FROM license_heartbeats lh
            JOIN licenses l ON l.id = lh.license_id
            JOIN customers c ON c.id = l.customer_id
            WHERE lh.timestamp > NOW() - INTERVAL '5 minutes'
            ORDER BY lh.timestamp DESC
            LIMIT 50
        """)
        sessions = cur.fetchall()
        
        cur.close()
        conn.close()
        
        return jsonify(sessions)
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500