"""
系统监控服务
提供系统状态、执行统计、性能指标等监控数据
"""
from sqlalchemy.orm import Session
from sqlalchemy import func, and_, case
from datetime import datetime, timedelta
from typing import Dict, Any, List
from app.models.user import User
from app.models.workflow import Workflow
from app.models.agent import Agent
from app.models.execution import Execution
from app.models.execution_log import ExecutionLog
from app.models.data_source import DataSource
from app.models.model_config import ModelConfig
import logging

logger = logging.getLogger(__name__)


class MonitoringService:
    """系统监控服务"""
    
    @staticmethod
    def get_system_overview(db: Session, user_id: str = None) -> Dict[str, Any]:
        """
        获取系统概览统计
        
        Args:
            db: 数据库会话
            user_id: 用户ID（如果提供，则只统计该用户的数据）
        
        Returns:
            系统概览数据
        """
        # 构建基础查询条件
        user_filter = Workflow.user_id == user_id if user_id else True
        
        # 统计工作流数量
        workflow_count = db.query(func.count(Workflow.id)).filter(user_filter).scalar() or 0
        
        # 统计Agent数量
        agent_filter = Agent.user_id == user_id if user_id else True
        agent_count = db.query(func.count(Agent.id)).filter(agent_filter).scalar() or 0
        
        # 统计执行记录数量
        execution_filter = None
        if user_id:
            execution_filter = Execution.workflow_id.in_(
                db.query(Workflow.id).filter(Workflow.user_id == user_id)
            )
        execution_count = db.query(func.count(Execution.id)).filter(
            execution_filter if execution_filter else True
        ).scalar() or 0
        
        # 统计数据源数量
        data_source_filter = DataSource.user_id == user_id if user_id else True
        data_source_count = db.query(func.count(DataSource.id)).filter(
            data_source_filter
        ).scalar() or 0
        
        # 统计模型配置数量
        model_config_filter = ModelConfig.user_id == user_id if user_id else True
        model_config_count = db.query(func.count(ModelConfig.id)).filter(
            model_config_filter
        ).scalar() or 0
        
        # 统计用户数量（仅管理员可见）
        user_count = None
        if not user_id:
            user_count = db.query(func.count(User.id)).scalar() or 0
        
        return {
            "workflows": workflow_count,
            "agents": agent_count,
            "executions": execution_count,
            "data_sources": data_source_count,
            "model_configs": model_config_count,
            "users": user_count
        }
    
    @staticmethod
    def get_execution_statistics(
        db: Session,
        user_id: str = None,
        days: int = 7
    ) -> Dict[str, Any]:
        """
        获取执行统计信息
        
        Args:
            db: 数据库会话
            user_id: 用户ID（如果提供，则只统计该用户的数据）
            days: 统计天数（默认7天）
        
        Returns:
            执行统计数据
        """
        # 构建时间范围
        end_time = datetime.utcnow()
        start_time = end_time - timedelta(days=days)
        
        # 构建查询条件
        execution_filter = Execution.created_at >= start_time
        if user_id:
            execution_filter = and_(
                execution_filter,
                Execution.workflow_id.in_(
                    db.query(Workflow.id).filter(Workflow.user_id == user_id)
                )
            )
        
        # 统计总执行数
        total_executions = db.query(func.count(Execution.id)).filter(
            execution_filter
        ).scalar() or 0
        
        # 统计各状态执行数
        status_stats = db.query(
            Execution.status,
            func.count(Execution.id).label('count')
        ).filter(execution_filter).group_by(Execution.status).all()
        
        status_counts = {status: count for status, count in status_stats}
        
        # 计算成功率
        completed = status_counts.get('completed', 0)
        failed = status_counts.get('failed', 0)
        success_rate = (completed / total_executions * 100) if total_executions > 0 else 0
        
        # 统计平均执行时间
        avg_execution_time = db.query(
            func.avg(Execution.execution_time)
        ).filter(
            and_(execution_filter, Execution.execution_time.isnot(None))
        ).scalar() or 0
        
        # 统计最近24小时的执行趋势
        hourly_trends = []
        for i in range(24):
            hour_start = end_time - timedelta(hours=24-i)
            hour_end = hour_start + timedelta(hours=1)
            hour_filter = and_(
                execution_filter,
                Execution.created_at >= hour_start,
                Execution.created_at < hour_end
            )
            hour_count = db.query(func.count(Execution.id)).filter(
                hour_filter
            ).scalar() or 0
            hourly_trends.append({
                "hour": hour_start.strftime("%H:00"),
                "count": hour_count
            })
        
        return {
            "total": total_executions,
            "status_counts": status_counts,
            "success_rate": round(success_rate, 2),
            "avg_execution_time": round(avg_execution_time, 2) if avg_execution_time else 0,
            "hourly_trends": hourly_trends
        }
    
    @staticmethod
    def get_node_type_statistics(
        db: Session,
        user_id: str = None,
        days: int = 7
    ) -> List[Dict[str, Any]]:
        """
        获取节点类型统计
        
        Args:
            db: 数据库会话
            user_id: 用户ID（如果提供，则只统计该用户的数据）
            days: 统计天数（默认7天）
        
        Returns:
            节点类型统计数据
        """
        # 构建时间范围
        end_time = datetime.utcnow()
        start_time = end_time - timedelta(days=days)
        
        # 构建查询条件
        execution_filter = Execution.created_at >= start_time
        if user_id:
            execution_filter = and_(
                execution_filter,
                Execution.workflow_id.in_(
                    db.query(Workflow.id).filter(Workflow.user_id == user_id)
                )
            )
        
        # 获取符合条件的执行ID列表
        execution_ids_query = db.query(Execution.id).filter(execution_filter)
        execution_ids = [row[0] for row in execution_ids_query.all()]
        
        if not execution_ids:
            return []
        
        # 统计各节点类型的执行情况
        node_stats = db.query(
            ExecutionLog.node_type,
            func.count(ExecutionLog.id).label('execution_count'),
            func.sum(ExecutionLog.duration).label('total_duration'),
            func.avg(ExecutionLog.duration).label('avg_duration'),
            func.count(
                case((ExecutionLog.level == 'ERROR', 1))
            ).label('error_count')
        ).filter(
            and_(
                ExecutionLog.execution_id.in_(execution_ids),
                ExecutionLog.node_type.isnot(None),
                ExecutionLog.duration.isnot(None)
            )
        ).group_by(ExecutionLog.node_type).all()
        
        result = []
        for node_type, exec_count, total_dur, avg_dur, error_count in node_stats:
            result.append({
                "node_type": node_type,
                "execution_count": exec_count,
                "total_duration": round(total_dur or 0, 2),
                "avg_duration": round(avg_dur or 0, 2),
                "error_count": error_count,
                "success_rate": round((exec_count - error_count) / exec_count * 100, 2) if exec_count > 0 else 0
            })
        
        return result
    
    @staticmethod
    def get_recent_activities(
        db: Session,
        user_id: str = None,
        limit: int = 10
    ) -> List[Dict[str, Any]]:
        """
        获取最近的活动记录
        
        Args:
            db: 数据库会话
            user_id: 用户ID（如果提供，则只统计该用户的数据）
            limit: 返回数量限制
        
        Returns:
            最近活动列表
        """
        # 构建查询条件
        execution_filter = True
        if user_id:
            execution_filter = Execution.workflow_id.in_(
                db.query(Workflow.id).filter(Workflow.user_id == user_id)
            )
        
        # 获取最近的执行记录
        recent_executions = db.query(Execution).filter(
            execution_filter
        ).order_by(Execution.created_at.desc()).limit(limit).all()
        
        result = []
        for execution in recent_executions:
            workflow = db.query(Workflow).filter(
                Workflow.id == execution.workflow_id
            ).first() if execution.workflow_id else None
            
            result.append({
                "id": execution.id,
                "type": "execution",
                "workflow_name": workflow.name if workflow else "未知工作流",
                "status": execution.status,
                "created_at": execution.created_at.isoformat() if execution.created_at else None,
                "execution_time": execution.execution_time
            })
        
        return result
