"""历史记录管理服务，负责管理算法调用历史和用户操作历史"""

from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
import json
import logging

from sqlalchemy.orm import Session
from sqlalchemy import and_, or_, desc

from app.models.models import AlgorithmCall, User, Algorithm
from app.utils.file import file_storage

logger = logging.getLogger(__name__)


class HistoryManager:
    """历史记录管理器，处理算法调用历史和其他用户操作历史"""
    
    def __init__(self):
        pass
    
    def get_user_call_history(
        self, 
        db: Session, 
        user_id: str, 
        algorithm_id: Optional[str] = None,
        start_date: Optional[datetime] = None,
        end_date: Optional[datetime] = None,
        status: Optional[str] = None,
        skip: int = 0, 
        limit: int = 100
    ) -> List[AlgorithmCall]:
        """获取用户的调用历史"""
        query = db.query(AlgorithmCall).filter(AlgorithmCall.user_id == user_id)
        
        # 添加过滤条件
        if algorithm_id:
            query = query.filter(AlgorithmCall.algorithm_id == algorithm_id)
        
        if start_date:
            query = query.filter(AlgorithmCall.created_at >= start_date)
        
        if end_date:
            query = query.filter(AlgorithmCall.created_at <= end_date)
        
        if status:
            query = query.filter(AlgorithmCall.status == status)
        
        # 按创建时间倒序排列
        query = query.order_by(desc(AlgorithmCall.created_at))
        
        # 分页
        history = query.offset(skip).limit(limit).all()
        
        return history
    
    def get_algorithm_call_history(
        self,
        db: Session,
        algorithm_id: str,
        user_id: Optional[str] = None,
        start_date: Optional[datetime] = None,
        end_date: Optional[datetime] = None,
        status: Optional[str] = None,
        skip: int = 0,
        limit: int = 100
    ) -> List[AlgorithmCall]:
        """获取特定算法的调用历史"""
        query = db.query(AlgorithmCall).filter(AlgorithmCall.algorithm_id == algorithm_id)
        
        # 添加过滤条件
        if user_id:
            query = query.filter(AlgorithmCall.user_id == user_id)
        
        if start_date:
            query = query.filter(AlgorithmCall.created_at >= start_date)
        
        if end_date:
            query = query.filter(AlgorithmCall.created_at <= end_date)
        
        if status:
            query = query.filter(AlgorithmCall.status == status)
        
        # 按创建时间倒序排列
        query = query.order_by(desc(AlgorithmCall.created_at))
        
        # 分页
        history = query.offset(skip).limit(limit).all()
        
        return history
    
    def get_call_statistics(
        self,
        db: Session,
        user_id: Optional[str] = None,
        algorithm_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """获取调用统计信息"""
        query = db.query(AlgorithmCall)
        
        if user_id:
            query = query.filter(AlgorithmCall.user_id == user_id)
        
        if algorithm_id:
            query = query.filter(AlgorithmCall.algorithm_id == algorithm_id)
        
        # 总调用次数
        total_calls = query.count()
        
        # 按状态统计
        status_counts = db.query(
            AlgorithmCall.status, 
            db.func.count(AlgorithmCall.id)
        ).filter(
            AlgorithmCall.user_id == user_id if user_id else AlgorithmCall.algorithm_id == algorithm_id
        ).group_by(AlgorithmCall.status).all()
        
        status_dict = {status: count for status, count in status_counts}
        
        # 成功率
        success_count = status_dict.get('success', 0)
        success_rate = (success_count / total_calls * 100) if total_calls > 0 else 0
        
        # 平均响应时间
        avg_response_time = db.query(
            db.func.avg(AlgorithmCall.response_time)
        ).filter(
            AlgorithmCall.response_time.isnot(None),
            AlgorithmCall.user_id == user_id if user_id else AlgorithmCall.algorithm_id == algorithm_id
        ).scalar()
        
        # 今日调用次数
        today_start = datetime.combine(datetime.today().date(), datetime.min.time())
        today_calls = query.filter(AlgorithmCall.created_at >= today_start).count()
        
        return {
            "total_calls": total_calls,
            "status_counts": status_dict,
            "success_rate": round(success_rate, 2),
            "avg_response_time": round(avg_response_time, 3) if avg_response_time else None,
            "today_calls": today_calls
        }
    
    def get_comparison_data(
        self,
        db: Session,
        call_ids: List[str]
    ) -> List[Dict[str, Any]]:
        """获取用于对比的历史数据"""
        calls = db.query(AlgorithmCall).filter(AlgorithmCall.id.in_(call_ids)).all()
        
        comparison_data = []
        for call in calls:
            comparison_data.append({
                "id": call.id,
                "algorithm_id": call.algorithm_id,
                "algorithm_name": getattr(call.algorithm, 'name', 'Unknown'),
                "version_id": call.version_id,
                "input_data": call.input_data,
                "output_data": call.output_data,
                "params": call.params,
                "status": call.status,
                "response_time": call.response_time,
                "created_at": call.created_at.isoformat() if call.created_at else None,
                "error_message": call.error_message
            })
        
        return comparison_data
    
    def export_history(
        self,
        db: Session,
        user_id: str,
        algorithm_id: Optional[str] = None,
        start_date: Optional[datetime] = None,
        end_date: Optional[datetime] = None,
        format_type: str = "json"
    ) -> Optional[str]:
        """导出历史记录"""
        history = self.get_user_call_history(
            db=db,
            user_id=user_id,
            algorithm_id=algorithm_id,
            start_date=start_date,
            end_date=end_date,
            skip=0,
            limit=10000  # 限制导出数量
        )
        
        # 转换为可序列化的格式
        export_data = []
        for call in history:
            export_data.append({
                "id": call.id,
                "user_id": call.user_id,
                "algorithm_id": call.algorithm_id,
                "algorithm_name": getattr(call.algorithm, 'name', 'Unknown'),
                "version_id": call.version_id,
                "version_number": getattr(call.version, 'version', 'Unknown'),
                "input_data": call.input_data,
                "output_data": call.output_data,
                "params": call.params,
                "status": call.status,
                "response_time": call.response_time,
                "created_at": call.created_at.isoformat() if call.created_at else None,
                "updated_at": call.updated_at.isoformat() if call.updated_at else None,
                "error_message": call.error_message
            })
        
        try:
            if format_type.lower() == "json":
                json_str = json.dumps(export_data, ensure_ascii=False, default=str)
                file_path = f"exports/history_{user_id}_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.json"
                
                # 上传到存储
                success = file_storage.upload_from_bytes(json_str.encode('utf-8'), file_path)
                
                if success:
                    return file_path
                else:
                    logger.error("Failed to upload exported history")
                    return None
            else:
                logger.error(f"Unsupported export format: {format_type}")
                return None
        except Exception as e:
            logger.error(f"Error exporting history: {str(e)}")
            return None
    
    def delete_old_history(
        self,
        db: Session,
        days_old: int,
        user_id: Optional[str] = None,
        algorithm_id: Optional[str] = None
    ) -> int:
        """删除旧的历史记录"""
        cutoff_date = datetime.utcnow() - timedelta(days=days_old)
        
        query = db.query(AlgorithmCall).filter(AlgorithmCall.created_at < cutoff_date)
        
        if user_id:
            query = query.filter(AlgorithmCall.user_id == user_id)
        
        if algorithm_id:
            query = query.filter(AlgorithmCall.algorithm_id == algorithm_id)
        
        deleted_count = query.delete()
        db.commit()
        
        logger.info(f"Deleted {deleted_count} old history records")
        return deleted_count


# 全局历史记录管理器实例
history_manager = HistoryManager()