"""
Metrics collection utilities for system monitoring.
"""
import time
import logging
from typing import Dict, Any, List
from datetime import datetime, timedelta
from django.db import connection
from django.core.cache import cache
from celery import current_app as celery_app
import os
import requests

logger = logging.getLogger(__name__)

SUPABASE_URL = os.environ.get('SUPABASE_URL', 'https://api.thrillwiki.com')
SUPABASE_SERVICE_KEY = os.environ.get('SUPABASE_SERVICE_ROLE_KEY')


class MetricsCollector:
    """Collects various system metrics for anomaly detection."""
    
    @staticmethod
    def get_error_rate() -> float:
        """
        Calculate error rate from recent logs.
        Returns percentage of error logs in the last minute.
        """
        cache_key = 'metrics:error_rate'
        cached_value = cache.get(cache_key)
        
        if cached_value is not None:
            return cached_value
        
        # In production, query actual error logs
        # For now, return a mock value
        error_rate = 0.0
        cache.set(cache_key, error_rate, 60)
        return error_rate
    
    @staticmethod
    def get_api_response_time() -> float:
        """
        Get average API response time in milliseconds.
        Returns average response time from recent requests.
        """
        cache_key = 'metrics:avg_response_time'
        cached_value = cache.get(cache_key)
        
        if cached_value is not None:
            return cached_value
        
        # In production, calculate from middleware metrics
        # For now, return a mock value
        response_time = 150.0  # milliseconds
        cache.set(cache_key, response_time, 60)
        return response_time
    
    @staticmethod
    def get_celery_queue_size() -> int:
        """
        Get current Celery queue size across all queues.
        """
        try:
            inspect = celery_app.control.inspect()
            active_tasks = inspect.active() or {}
            scheduled_tasks = inspect.scheduled() or {}
            
            total_active = sum(len(tasks) for tasks in active_tasks.values())
            total_scheduled = sum(len(tasks) for tasks in scheduled_tasks.values())
            
            return total_active + total_scheduled
        except Exception as e:
            logger.error(f"Error getting Celery queue size: {e}")
            return 0
    
    @staticmethod
    def get_database_connection_count() -> int:
        """
        Get current number of active database connections.
        """
        try:
            with connection.cursor() as cursor:
                cursor.execute("SELECT count(*) FROM pg_stat_activity WHERE state = 'active';")
                count = cursor.fetchone()[0]
                return count
        except Exception as e:
            logger.error(f"Error getting database connection count: {e}")
            return 0
    
    @staticmethod
    def get_cache_hit_rate() -> float:
        """
        Calculate cache hit rate percentage.
        """
        cache_key_hits = 'metrics:cache_hits'
        cache_key_misses = 'metrics:cache_misses'
        
        hits = cache.get(cache_key_hits, 0)
        misses = cache.get(cache_key_misses, 0)
        
        total = hits + misses
        if total == 0:
            return 100.0
        
        return (hits / total) * 100
    
    @staticmethod
    def record_metric(metric_name: str, metric_value: float, metric_category: str = 'system') -> bool:
        """
        Record a metric to Supabase metric_time_series table.
        """
        if not SUPABASE_SERVICE_KEY:
            logger.warning("SUPABASE_SERVICE_ROLE_KEY not configured, skipping metric recording")
            return False
        
        try:
            headers = {
                'apikey': SUPABASE_SERVICE_KEY,
                'Authorization': f'Bearer {SUPABASE_SERVICE_KEY}',
                'Content-Type': 'application/json',
            }
            
            data = {
                'metric_name': metric_name,
                'metric_value': metric_value,
                'metric_category': metric_category,
                'timestamp': datetime.utcnow().isoformat(),
            }
            
            response = requests.post(
                f'{SUPABASE_URL}/rest/v1/metric_time_series',
                headers=headers,
                json=data,
                timeout=5
            )
            
            if response.status_code in [200, 201]:
                logger.info(f"Recorded metric: {metric_name} = {metric_value}")
                return True
            else:
                logger.error(f"Failed to record metric: {response.status_code} - {response.text}")
                return False
                
        except Exception as e:
            logger.error(f"Error recording metric {metric_name}: {e}")
            return False
    
    @staticmethod
    def collect_all_metrics() -> Dict[str, Any]:
        """
        Collect all system metrics and record them.
        Returns a summary of collected metrics.
        """
        metrics = {}
        
        try:
            # Collect error rate
            error_rate = MetricsCollector.get_error_rate()
            metrics['error_rate'] = error_rate
            MetricsCollector.record_metric('error_rate', error_rate, 'performance')
            
            # Collect API response time
            response_time = MetricsCollector.get_api_response_time()
            metrics['api_response_time'] = response_time
            MetricsCollector.record_metric('api_response_time', response_time, 'performance')
            
            # Collect queue size
            queue_size = MetricsCollector.get_celery_queue_size()
            metrics['celery_queue_size'] = queue_size
            MetricsCollector.record_metric('celery_queue_size', queue_size, 'system')
            
            # Collect database connections
            db_connections = MetricsCollector.get_database_connection_count()
            metrics['database_connections'] = db_connections
            MetricsCollector.record_metric('database_connections', db_connections, 'system')
            
            # Collect cache hit rate
            cache_hit_rate = MetricsCollector.get_cache_hit_rate()
            metrics['cache_hit_rate'] = cache_hit_rate
            MetricsCollector.record_metric('cache_hit_rate', cache_hit_rate, 'performance')
            
            logger.info(f"Successfully collected {len(metrics)} metrics")
            
        except Exception as e:
            logger.error(f"Error collecting metrics: {e}", exc_info=True)
        
        return metrics
