"""
Agent Performance Monitoring Framework for ALwrity Autonomous Marketing Agents
Tracks agent performance, efficiency, and provides optimization recommendations
"""

import asyncio
import json
import logging
from datetime import datetime, timedelta
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass, asdict
from enum import Enum
from collections import defaultdict, deque

from utils.logger_utils import get_service_logger
from services.database import get_session_for_user

logger = get_service_logger(__name__)

class PerformanceMetric(Enum):
    """Types of performance metrics tracked"""
    RESPONSE_TIME = "response_time"
    SUCCESS_RATE = "success_rate"
    EFFICIENCY_SCORE = "efficiency_score"
    RESOURCE_USAGE = "resource_usage"
    USER_SATISFACTION = "user_satisfaction"
    MARKET_IMPACT = "market_impact"

class AgentStatus(Enum):
    """Status of agent operations"""
    ACTIVE = "active"
    IDLE = "idle"
    PROCESSING = "processing"
    ERROR = "error"
    MAINTENANCE = "maintenance"

@dataclass
class PerformanceDataPoint:
    """Single performance data point"""
    timestamp: str
    metric_type: PerformanceMetric
    value: float
    context: Dict[str, Any]
    agent_id: str
    user_id: str

@dataclass
class AgentPerformanceSnapshot:
    """Complete performance snapshot for an agent"""
    agent_id: str
    user_id: str
    timestamp: str
    status: AgentStatus
    total_actions: int
    successful_actions: int
    failed_actions: int
    average_response_time: float
    success_rate: float
    efficiency_score: float
    resource_usage: Dict[str, float]
    market_impact_score: float
    last_action_at: str
    
    def __post_init__(self):
        if self.timestamp is None:
            self.timestamp = datetime.utcnow().isoformat()

@dataclass
class PerformanceTrend:
    """Performance trend analysis"""
    metric_type: PerformanceMetric
    trend_direction: str  # "improving", "declining", "stable"
    trend_strength: float  # 0.0 to 1.0
    change_rate: float  # Percentage change per time unit
    confidence: float  # 0.0 to 1.0
    period_start: str
    period_end: str

@dataclass
class OptimizationRecommendation:
    """Performance optimization recommendation"""
    recommendation_id: str
    agent_id: str
    user_id: str
    recommendation_type: str
    priority: str  # "high", "medium", "low"
    description: str
    expected_impact: float  # Expected improvement in performance
    implementation_steps: List[str]
    estimated_effort: str  # "low", "medium", "high"
    created_at: str
    expires_at: str
    
    def __post_init__(self):
        if self.created_at is None:
            self.created_at = datetime.utcnow().isoformat()
        if self.expires_at is None:
            # Default expiration: 7 days
            expires = datetime.utcnow().timestamp() + (7 * 24 * 60 * 60)
            self.expires_at = datetime.fromtimestamp(expires).isoformat()

class AgentPerformanceMonitor:
    """Main performance monitoring system for agents"""
    
    def __init__(self, user_id: str):
        self.user_id = user_id
        self.performance_data: Dict[str, List[PerformanceDataPoint]] = defaultdict(list)
        self.agent_snapshots: Dict[str, AgentPerformanceSnapshot] = {}
        self.recommendations: List[OptimizationRecommendation] = []
        self.performance_history: deque = deque(maxlen=1000)  # Keep last 1000 data points
        
        # Performance thresholds and targets
        self.performance_targets = {
            "success_rate": 0.85,        # 85% success rate target
            "response_time": 30.0,       # 30 seconds average response time target
            "efficiency_score": 0.75,    # 75% efficiency score target
            "market_impact": 0.60        # 60% market impact score target
        }
        
        # Alert thresholds
        self.alert_thresholds = {
            "success_rate": 0.70,        # Alert if below 70%
            "response_time": 60.0,       # Alert if above 60 seconds
            "efficiency_score": 0.50,    # Alert if below 50%
            "market_impact": 0.30        # Alert if below 30%
        }
        
        logger.info(f"Initialized AgentPerformanceMonitor for user: {user_id}")
    
    async def record_performance_data(self, agent_id: str, metric_type: PerformanceMetric, value: float, context: Dict[str, Any] = None) -> bool:
        """Record a performance data point"""
        try:
            if context is None:
                context = {}
            
            data_point = PerformanceDataPoint(
                timestamp=datetime.utcnow().isoformat(),
                metric_type=metric_type,
                value=value,
                context=context,
                agent_id=agent_id,
                user_id=self.user_id
            )
            
            # Store in performance data
            self.performance_data[agent_id].append(data_point)
            self.performance_history.append(data_point)
            
            # Keep only recent data (last 24 hours for real-time analysis)
            cutoff_time = datetime.utcnow().timestamp() - (24 * 60 * 60)
            self.performance_data[agent_id] = [
                dp for dp in self.performance_data[agent_id]
                if datetime.fromisoformat(dp.timestamp).timestamp() > cutoff_time
            ]
            
            logger.debug(f"Recorded performance data for agent {agent_id}: {metric_type.value} = {value}")
            return True
            
        except Exception as e:
            logger.error(f"Error recording performance data for agent {agent_id}: {e}")
            return False
    
    async def update_agent_snapshot(self, agent_id: str, status: AgentStatus, action_result: Dict[str, Any] = None) -> AgentPerformanceSnapshot:
        """Update performance snapshot for an agent"""
        try:
            # Get recent performance data
            recent_data = self.performance_data[agent_id]
            
            # Calculate metrics from recent data
            total_actions = len([dp for dp in recent_data if dp.metric_type == PerformanceMetric.SUCCESS_RATE])
            successful_actions = len([dp for dp in recent_data if dp.metric_type == PerformanceMetric.SUCCESS_RATE and dp.value > 0.5])
            failed_actions = total_actions - successful_actions
            
            # Calculate average response time
            response_time_data = [dp.value for dp in recent_data if dp.metric_type == PerformanceMetric.RESPONSE_TIME]
            avg_response_time = sum(response_time_data) / len(response_time_data) if response_time_data else 0.0
            
            # Calculate success rate
            success_rate = successful_actions / total_actions if total_actions > 0 else 0.0
            
            # Calculate efficiency score
            efficiency_data = [dp.value for dp in recent_data if dp.metric_type == PerformanceMetric.EFFICIENCY_SCORE]
            avg_efficiency = sum(efficiency_data) / len(efficiency_data) if efficiency_data else 0.0
            
            # Calculate market impact
            market_impact_data = [dp.value for dp in recent_data if dp.metric_type == PerformanceMetric.MARKET_IMPACT]
            avg_market_impact = sum(market_impact_data) / len(market_impact_data) if market_impact_data else 0.0
            
            # Get resource usage
            resource_usage = self._calculate_resource_usage(agent_id, recent_data)
            
            # Get last action time
            last_action_at = max([dp.timestamp for dp in recent_data], default=datetime.utcnow().isoformat()) if recent_data else datetime.utcnow().isoformat()
            
            # Create snapshot
            snapshot = AgentPerformanceSnapshot(
                agent_id=agent_id,
                user_id=self.user_id,
                timestamp=datetime.utcnow().isoformat(),
                status=status,
                total_actions=total_actions,
                successful_actions=successful_actions,
                failed_actions=failed_actions,
                average_response_time=avg_response_time,
                success_rate=success_rate,
                efficiency_score=avg_efficiency,
                resource_usage=resource_usage,
                market_impact_score=avg_market_impact,
                last_action_at=last_action_at
            )
            
            self.agent_snapshots[agent_id] = snapshot
            
            logger.info(f"Updated performance snapshot for agent {agent_id}: success_rate={success_rate:.2f}, efficiency={avg_efficiency:.2f}")
            return snapshot
            
        except Exception as e:
            logger.error(f"Error updating performance snapshot for agent {agent_id}: {e}")
            # Return a default snapshot
            return AgentPerformanceSnapshot(
                agent_id=agent_id,
                user_id=self.user_id,
                timestamp=datetime.utcnow().isoformat(),
                status=AgentStatus.ERROR,
                total_actions=0,
                successful_actions=0,
                failed_actions=0,
                average_response_time=0.0,
                success_rate=0.0,
                efficiency_score=0.0,
                resource_usage={},
                market_impact_score=0.0,
                last_action_at=datetime.utcnow().isoformat()
            )
    
    def _calculate_resource_usage(self, agent_id: str, recent_data: List[PerformanceDataPoint]) -> Dict[str, float]:
        """Calculate resource usage metrics"""
        resource_usage = {
            "cpu_usage": 0.0,
            "memory_usage": 0.0,
            "api_calls": 0,
            "processing_time": 0.0
        }
        
        try:
            # Extract resource usage from context
            for dp in recent_data:
                if dp.metric_type == PerformanceMetric.RESOURCE_USAGE and dp.context:
                    resource_usage["cpu_usage"] = max(resource_usage["cpu_usage"], dp.context.get("cpu_usage", 0.0))
                    resource_usage["memory_usage"] = max(resource_usage["memory_usage"], dp.context.get("memory_usage", 0.0))
                    resource_usage["api_calls"] += dp.context.get("api_calls", 0)
                    resource_usage["processing_time"] += dp.context.get("processing_time", 0.0)
            
            # Calculate averages if multiple data points
            if len(recent_data) > 0:
                resource_usage["processing_time"] = resource_usage["processing_time"] / len(recent_data)
            
        except Exception as e:
            logger.error(f"Error calculating resource usage for agent {agent_id}: {e}")
        
        return resource_usage
    
    async def analyze_performance_trends(self, agent_id: str, period_hours: int = 24) -> List[PerformanceTrend]:
        """Analyze performance trends for an agent"""
        try:
            cutoff_time = datetime.utcnow().timestamp() - (period_hours * 60 * 60)
            agent_data = [
                dp for dp in self.performance_data[agent_id]
                if datetime.fromisoformat(dp.timestamp).timestamp() > cutoff_time
            ]
            
            if len(agent_data) < 5:  # Need at least 5 data points for trend analysis
                return []
            
            trends = []
            
            # Analyze trends for each metric type
            for metric_type in PerformanceMetric:
                metric_data = [dp for dp in agent_data if dp.metric_type == metric_type]
                
                if len(metric_data) < 3:  # Need at least 3 points for trend
                    continue
                
                # Sort by timestamp
                metric_data.sort(key=lambda x: x.timestamp)
                
                # Calculate trend
                trend_result = self._calculate_trend(metric_data)
                
                if trend_result:
                    trend = PerformanceTrend(
                        metric_type=metric_type,
                        trend_direction=trend_result["direction"],
                        trend_strength=trend_result["strength"],
                        change_rate=trend_result["change_rate"],
                        confidence=trend_result["confidence"],
                        period_start=metric_data[0].timestamp,
                        period_end=metric_data[-1].timestamp
                    )
                    trends.append(trend)
            
            logger.info(f"Analyzed performance trends for agent {agent_id}: found {len(trends)} trends")
            return trends
            
        except Exception as e:
            logger.error(f"Error analyzing performance trends for agent {agent_id}: {e}")
            return []
    
    def _calculate_trend(self, data_points: List[PerformanceDataPoint]) -> Optional[Dict[str, Any]]:
        """Calculate trend from performance data points"""
        try:
            if len(data_points) < 3:
                return None
            
            # Extract values and timestamps
            values = [dp.value for dp in data_points]
            timestamps = [datetime.fromisoformat(dp.timestamp).timestamp() for dp in data_points]
            
            # Simple linear trend calculation
            n = len(values)
            sum_x = sum(timestamps)
            sum_y = sum(values)
            sum_xy = sum(x * y for x, y in zip(timestamps, values))
            sum_x2 = sum(x * x for x in timestamps)
            
            # Calculate slope and intercept
            slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x)
            intercept = (sum_y - slope * sum_x) / n
            
            # Calculate correlation coefficient (confidence)
            mean_y = sum_y / n
            ss_tot = sum((y - mean_y) ** 2 for y in values)
            ss_res = sum((y - (slope * x + intercept)) ** 2 for x, y in zip(timestamps, values))
            r_squared = 1 - (ss_res / ss_tot) if ss_tot > 0 else 0
            
            # Determine trend direction
            if abs(slope) < 0.001:  # Nearly flat
                direction = "stable"
                strength = 0.0
            elif slope > 0:
                direction = "improving"
                strength = min(1.0, abs(slope) * 100)  # Scale slope to 0-1
            else:
                direction = "declining"
                strength = min(1.0, abs(slope) * 100)
            
            # Calculate change rate (percentage change per hour)
            time_span = timestamps[-1] - timestamps[0]
            if time_span > 0:
                change_rate = (slope * 3600) / (values[0] if values[0] != 0 else 1) * 100  # Per hour
            else:
                change_rate = 0.0
            
            return {
                "direction": direction,
                "strength": strength,
                "change_rate": change_rate,
                "confidence": r_squared
            }
            
        except Exception as e:
            logger.error(f"Error calculating trend: {e}")
            return None
    
    async def generate_optimization_recommendations(self, agent_id: str) -> List[OptimizationRecommendation]:
        """Generate optimization recommendations for an agent"""
        try:
            recommendations = []
            
            # Get current snapshot
            snapshot = self.agent_snapshots.get(agent_id)
            if not snapshot:
                return []
            
            # Get performance trends
            trends = await self.analyze_performance_trends(agent_id)
            
            # Generate recommendations based on performance analysis
            
            # 1. Success rate recommendations
            if snapshot.success_rate < self.performance_targets["success_rate"]:
                recommendation = OptimizationRecommendation(
                    recommendation_id=f"success_rate_{agent_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
                    agent_id=agent_id,
                    user_id=self.user_id,
                    recommendation_type="success_rate_improvement",
                    priority="high" if snapshot.success_rate < self.alert_thresholds["success_rate"] else "medium",
                    description=f"Agent success rate is {snapshot.success_rate:.1%}, target is {self.performance_targets['success_rate']:.1%}",
                    expected_impact=self.performance_targets["success_rate"] - snapshot.success_rate,
                    implementation_steps=[
                        "Analyze recent failed actions to identify patterns",
                        "Review error logs for common failure causes",
                        "Update agent parameters or logic to address identified issues",
                        "Test improvements with small batch of actions",
                        "Monitor success rate improvement over time"
                    ],
                    estimated_effort="medium"
                )
                recommendations.append(recommendation)
            
            # 2. Response time recommendations
            if snapshot.average_response_time > self.performance_targets["response_time"]:
                recommendation = OptimizationRecommendation(
                    recommendation_id=f"response_time_{agent_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
                    agent_id=agent_id,
                    user_id=self.user_id,
                    recommendation_type="response_time_optimization",
                    priority="high" if snapshot.average_response_time > self.alert_thresholds["response_time"] else "medium",
                    description=f"Agent average response time is {snapshot.average_response_time:.1f}s, target is {self.performance_targets['response_time']:.1f}s",
                    expected_impact=(self.performance_targets["response_time"] - snapshot.average_response_time) / snapshot.average_response_time,
                    implementation_steps=[
                        "Profile agent execution to identify bottlenecks",
                        "Optimize API calls and external service interactions",
                        "Implement caching for frequently accessed data",
                        "Review and optimize agent logic and decision-making",
                        "Monitor response time improvement"
                    ],
                    estimated_effort="high"
                )
                recommendations.append(recommendation)
            
            # 3. Efficiency score recommendations
            if snapshot.efficiency_score < self.performance_targets["efficiency_score"]:
                recommendation = OptimizationRecommendation(
                    recommendation_id=f"efficiency_{agent_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
                    agent_id=agent_id,
                    user_id=self.user_id,
                    recommendation_type="efficiency_improvement",
                    priority="high" if snapshot.efficiency_score < self.alert_thresholds["efficiency_score"] else "medium",
                    description=f"Agent efficiency score is {snapshot.efficiency_score:.2f}, target is {self.performance_targets['efficiency_score']:.2f}",
                    expected_impact=self.performance_targets["efficiency_score"] - snapshot.efficiency_score,
                    implementation_steps=[
                        "Analyze agent decision-making patterns",
                        "Identify redundant or unnecessary operations",
                        "Optimize agent parameters and thresholds",
                        "Implement better error handling and recovery",
                        "Monitor efficiency score improvement"
                    ],
                    estimated_effort="medium"
                )
                recommendations.append(recommendation)
            
            # 4. Market impact recommendations
            if snapshot.market_impact_score < self.performance_targets["market_impact"]:
                recommendation = OptimizationRecommendation(
                    recommendation_id=f"market_impact_{agent_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
                    agent_id=agent_id,
                    user_id=self.user_id,
                    recommendation_type="market_impact_enhancement",
                    priority="medium",
                    description=f"Agent market impact score is {snapshot.market_impact_score:.2f}, target is {self.performance_targets['market_impact']:.2f}",
                    expected_impact=self.performance_targets["market_impact"] - snapshot.market_impact_score,
                    implementation_steps=[
                        "Analyze market signal detection accuracy",
                        "Improve market trend analysis and prediction",
                        "Enhance competitive intelligence gathering",
                        "Optimize timing and execution of market actions",
                        "Monitor market impact score improvement"
                    ],
                    estimated_effort="high"
                )
                recommendations.append(recommendation)
            
            # 5. Trend-based recommendations
            for trend in trends:
                if trend.trend_strength > 0.7 and trend.confidence > 0.8:  # Strong trend with high confidence
                    if trend.trend_direction == "declining":
                        recommendation = OptimizationRecommendation(
                            recommendation_id=f"trend_{trend.metric_type.value}_{agent_id}_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
                            agent_id=agent_id,
                            user_id=self.user_id,
                            recommendation_type="trend_reversal",
                            priority="high" if trend.trend_strength > 0.8 else "medium",
                            description=f"Strong declining trend detected in {trend.metric_type.value}: {trend.change_rate:.1f}% change per hour",
                            expected_impact=0.3,  # Estimate 30% improvement potential
                            implementation_steps=[
                                f"Investigate causes of declining {trend.metric_type.value}",
                                "Identify specific factors contributing to the trend",
                                "Implement corrective measures based on findings",
                                "Monitor trend reversal over time",
                                "Adjust approach if trend continues"
                            ],
                            estimated_effort="medium"
                        )
                        recommendations.append(recommendation)
            
            # Sort by priority and expected impact
            recommendations.sort(key=lambda x: (self._priority_weight(x.priority), x.expected_impact), reverse=True)
            
            # Keep only top 10 recommendations
            recommendations = recommendations[:10]
            
            # Store recommendations
            self.recommendations.extend(recommendations)
            
            # Keep only recent recommendations (last 50)
            if len(self.recommendations) > 50:
                self.recommendations = self.recommendations[-50:]
            
            logger.info(f"Generated {len(recommendations)} optimization recommendations for agent {agent_id}")
            return recommendations
            
        except Exception as e:
            logger.error(f"Error generating optimization recommendations for agent {agent_id}: {e}")
            return []
    
    def _priority_weight(self, priority: str) -> int:
        """Convert priority to numeric weight for sorting"""
        priority_weights = {
            "high": 3,
            "medium": 2,
            "low": 1
        }
        return priority_weights.get(priority, 0)
    
    async def get_performance_alerts(self, agent_id: str) -> List[Dict[str, Any]]:
        """Get performance alerts for an agent"""
        alerts = []
        
        try:
            snapshot = self.agent_snapshots.get(agent_id)
            if not snapshot:
                return []
            
            # Check success rate alert
            if snapshot.success_rate < self.alert_thresholds["success_rate"]:
                alerts.append({
                    "type": "performance_alert",
                    "metric": "success_rate",
                    "current_value": snapshot.success_rate,
                    "threshold": self.alert_thresholds["success_rate"],
                    "target": self.performance_targets["success_rate"],
                    "severity": "high" if snapshot.success_rate < 0.5 else "medium",
                    "message": f"Agent success rate ({snapshot.success_rate:.1%}) is below alert threshold ({self.alert_thresholds['success_rate']:.1%})",
                    "timestamp": datetime.utcnow().isoformat()
                })
            
            # Check response time alert
            if snapshot.average_response_time > self.alert_thresholds["response_time"]:
                alerts.append({
                    "type": "performance_alert",
                    "metric": "response_time",
                    "current_value": snapshot.average_response_time,
                    "threshold": self.alert_thresholds["response_time"],
                    "target": self.performance_targets["response_time"],
                    "severity": "high" if snapshot.average_response_time > 120 else "medium",
                    "message": f"Agent response time ({snapshot.average_response_time:.1f}s) exceeds alert threshold ({self.alert_thresholds['response_time']:.1f}s)",
                    "timestamp": datetime.utcnow().isoformat()
                })
            
            # Check efficiency score alert
            if snapshot.efficiency_score < self.alert_thresholds["efficiency_score"]:
                alerts.append({
                    "type": "performance_alert",
                    "metric": "efficiency_score",
                    "current_value": snapshot.efficiency_score,
                    "threshold": self.alert_thresholds["efficiency_score"],
                    "target": self.performance_targets["efficiency_score"],
                    "severity": "high" if snapshot.efficiency_score < 0.3 else "medium",
                    "message": f"Agent efficiency score ({snapshot.efficiency_score:.2f}) is below alert threshold ({self.alert_thresholds['efficiency_score']:.2f})",
                    "timestamp": datetime.utcnow().isoformat()
                })
            
            # Check market impact alert
            if snapshot.market_impact_score < self.alert_thresholds["market_impact"]:
                alerts.append({
                    "type": "performance_alert",
                    "metric": "market_impact",
                    "current_value": snapshot.market_impact_score,
                    "threshold": self.alert_thresholds["market_impact"],
                    "target": self.performance_targets["market_impact"],
                    "severity": "medium",
                    "message": f"Agent market impact score ({snapshot.market_impact_score:.2f}) is below alert threshold ({self.alert_thresholds['market_impact']:.2f})",
                    "timestamp": datetime.utcnow().isoformat()
                })
            
            return alerts
            
        except Exception as e:
            logger.error(f"Error getting performance alerts for agent {agent_id}: {e}")
            return []
    
    async def get_performance_summary(self, agent_id: str) -> Dict[str, Any]:
        """Get comprehensive performance summary for an agent"""
        try:
            snapshot = self.agent_snapshots.get(agent_id)
            if not snapshot:
                return {}
            
            # Get trends
            trends = await self.analyze_performance_trends(agent_id)
            
            # Get recommendations
            recommendations = await self.generate_optimization_recommendations(agent_id)
            
            # Get alerts
            alerts = await self.get_performance_alerts(agent_id)
            
            # Calculate overall health score
            health_score = self._calculate_health_score(snapshot)
            
            return {
                "agent_id": agent_id,
                "user_id": self.user_id,
                "timestamp": datetime.utcnow().isoformat(),
                "overall_health": health_score,
                "current_performance": asdict(snapshot),
                "performance_trends": [asdict(trend) for trend in trends],
                "optimization_recommendations": [asdict(rec) for rec in recommendations],
                "performance_alerts": alerts,
                "performance_targets": self.performance_targets,
                "alert_thresholds": self.alert_thresholds
            }
            
        except Exception as e:
            logger.error(f"Error getting performance summary for agent {agent_id}: {e}")
            return {}
    
    def _calculate_health_score(self, snapshot: AgentPerformanceSnapshot) -> float:
        """Calculate overall health score based on key metrics"""
        try:
            # Weighted scoring based on key metrics
            weights = {
                "success_rate": 0.3,
                "response_time": 0.25,
                "efficiency_score": 0.25,
                "market_impact": 0.2
            }
            
            scores = {
                "success_rate": min(1.0, snapshot.success_rate / self.performance_targets["success_rate"]),
                "response_time": max(0.0, 1.0 - (snapshot.average_response_time / self.performance_targets["response_time"])),
                "efficiency_score": min(1.0, snapshot.efficiency_score / self.performance_targets["efficiency_score"]),
                "market_impact": min(1.0, snapshot.market_impact_score / self.performance_targets["market_impact"])
            }
            
            # Calculate weighted health score
            health_score = sum(scores[metric] * weights[metric] for metric in weights.keys())
            
            return round(health_score, 2)
            
        except Exception as e:
            logger.error(f"Error calculating health score: {e}")
            return 0.0
    
    def get_all_agents_performance(self) -> List[Dict[str, Any]]:
        """Get performance summary for all agents"""
        all_performance = []
        
        for agent_id, snapshot in self.agent_snapshots.items():
            performance_summary = {
                "agent_id": agent_id,
                "user_id": self.user_id,
                "status": snapshot.status.value,
                "success_rate": snapshot.success_rate,
                "efficiency_score": snapshot.efficiency_score,
                "response_time": snapshot.average_response_time,
                "market_impact": snapshot.market_impact_score,
                "total_actions": snapshot.total_actions,
                "last_action": snapshot.last_action_at,
                "health_score": self._calculate_health_score(snapshot)
            }
            all_performance.append(performance_summary)
        
        return all_performance

# Service class for performance monitoring
class AgentPerformanceService:
    """Service class for agent performance monitoring operations"""
    
    def __init__(self):
        self.monitors: Dict[str, AgentPerformanceMonitor] = {}
        self.global_performance_history: deque = deque(maxlen=5000)  # Global history
    
    async def get_monitor(self, user_id: str) -> AgentPerformanceMonitor:
        """Get or create a performance monitor for a user"""
        if user_id not in self.monitors:
            self.monitors[user_id] = AgentPerformanceMonitor(user_id)
        return self.monitors[user_id]
    
    async def record_agent_performance(self, user_id: str, agent_id: str, metric_type: PerformanceMetric, value: float, context: Dict[str, Any] = None) -> bool:
        """Record performance data for an agent"""
        monitor = await self.get_monitor(user_id)
        success = await monitor.record_performance_data(agent_id, metric_type, value, context)
        
        if success:
            # Also record in global history
            data_point = PerformanceDataPoint(
                timestamp=datetime.utcnow().isoformat(),
                metric_type=metric_type,
                value=value,
                context=context or {},
                agent_id=agent_id,
                user_id=user_id
            )
            self.global_performance_history.append(data_point)
        
        return success
    
    async def update_agent_performance_snapshot(self, user_id: str, agent_id: str, status: AgentStatus, action_result: Dict[str, Any] = None) -> AgentPerformanceSnapshot:
        """Update performance snapshot for an agent"""
        monitor = await self.get_monitor(user_id)
        return await monitor.update_agent_snapshot(agent_id, status, action_result)
    
    async def get_agent_performance_summary(self, user_id: str, agent_id: str) -> Dict[str, Any]:
        """Get comprehensive performance summary for an agent"""
        monitor = await self.get_monitor(user_id)
        return await monitor.get_performance_summary(agent_id)
    
    async def get_all_agents_performance_summary(self, user_id: str) -> List[Dict[str, Any]]:
        """Get performance summary for all agents for a user"""
        monitor = await self.get_monitor(user_id)
        return monitor.get_all_agents_performance()
    
    async def get_global_performance_stats(self) -> Dict[str, Any]:
        """Get global performance statistics across all users and agents"""
        if not self.global_performance_history:
            return {}
        
        # Calculate global statistics
        total_actions = len([dp for dp in self.global_performance_history if dp.metric_type == PerformanceMetric.SUCCESS_RATE])
        successful_actions = len([dp for dp in self.global_performance_history if dp.metric_type == PerformanceMetric.SUCCESS_RATE and dp.value > 0.5])
        
        response_times = [dp.value for dp in self.global_performance_history if dp.metric_type == PerformanceMetric.RESPONSE_TIME]
        avg_response_time = sum(response_times) / len(response_times) if response_times else 0.0
        
        efficiency_scores = [dp.value for dp in self.global_performance_history if dp.metric_type == PerformanceMetric.EFFICIENCY_SCORE]
        avg_efficiency = sum(efficiency_scores) / len(efficiency_scores) if efficiency_scores else 0.0
        
        unique_users = len(set(dp.user_id for dp in self.global_performance_history))
        unique_agents = len(set(dp.agent_id for dp in self.global_performance_history))
        
        return {
            "total_actions": total_actions,
            "successful_actions": successful_actions,
            "overall_success_rate": successful_actions / total_actions if total_actions > 0 else 0.0,
            "average_response_time": avg_response_time,
            "average_efficiency_score": avg_efficiency,
            "unique_users": unique_users,
            "unique_agents": unique_agents,
            "total_data_points": len(self.global_performance_history),
            "timestamp": datetime.utcnow().isoformat()
        }

# Global service instance
performance_service = AgentPerformanceService()

# Convenience functions for external use
async def record_agent_performance(user_id: str, agent_id: str, metric_type: PerformanceMetric, value: float, context: Dict[str, Any] = None) -> bool:
    """Record performance data for an agent"""
    return await performance_service.record_agent_performance(user_id, agent_id, metric_type, value, context)

async def update_agent_performance_snapshot(user_id: str, agent_id: str, status: AgentStatus, action_result: Dict[str, Any] = None) -> AgentPerformanceSnapshot:
    """Update performance snapshot for an agent"""
    return await performance_service.update_agent_performance_snapshot(user_id, agent_id, status, action_result)

async def get_agent_performance_summary(user_id: str, agent_id: str) -> Dict[str, Any]:
    """Get comprehensive performance summary for an agent"""
    return await performance_service.get_agent_performance_summary(user_id, agent_id)

async def get_all_agents_performance_summary(user_id: str) -> List[Dict[str, Any]]:       
    """Get performance summary for all agents for a user"""
    return await performance_service.get_all_agents_performance_summary(user_id)

# Alias for backward compatibility
PerformanceMonitor = AgentPerformanceMonitor
performance_monitor = performance_service
AgentPerformanceMetrics = AgentPerformanceSnapshot