"""
进度跟踪服务
用于跟踪长时间运行任务的进度

⚠️ 重要部署限制：
本服务使用内存存储进度数据 (self._progress_store)。
这意味着：
1. 必须使用单 worker 模式部署 (uvicorn 默认单 worker)
2. 如果使用 gunicorn 多 worker (如 -w 4)，进度数据无法跨 worker 共享
3. 如需多 worker 部署，需改用 Redis 或数据库存储进度数据

当前部署方式 (Dockerfile):
  CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
  ✅ 单 worker，进度服务正常工作
"""

import asyncio
from typing import Dict, Any, Optional
from datetime import datetime
import uuid


class ProgressService:
    """进度跟踪服务"""
    
    def __init__(self):
        # 存储所有任务的进度信息
        self._progress_store: Dict[str, Dict[str, Any]] = {}
        # 清理过期任务的锁
        self._cleanup_lock = asyncio.Lock()
    
    def create_task(self, task_type: str, total: int = 0, title: str = "") -> str:
        """
        创建新的进度任务
        
        Args:
            task_type: 任务类型 (aggregate, download)
            total: 总任务数
            title: 任务标题
            
        Returns:
            任务ID
        """
        task_id = str(uuid.uuid4())
        self._progress_store[task_id] = {
            "id": task_id,
            "type": task_type,
            "title": title,
            "total": total,
            "current": 0,
            "percentage": 0,
            "status": "running",  # running, success, failed
            "message": "初始化中...",
            "details": "",
            "result_message": "",
            "created_at": datetime.now(),
            "updated_at": datetime.now(),
            "completed": False,
            "success": False
        }
        return task_id
    
    def update_progress(self, task_id: str, current: int = None, 
                       message: str = None, details: str = None) -> bool:
        """
        更新任务进度
        
        Args:
            task_id: 任务ID
            current: 当前进度值
            message: 状态消息
            details: 详细信息
            
        Returns:
            是否更新成功
        """
        if task_id not in self._progress_store:
            return False
        
        task = self._progress_store[task_id]
        
        if current is not None:
            task["current"] = current
            if task["total"] > 0:
                task["percentage"] = min(100, int((current / task["total"]) * 100))
        
        if message is not None:
            task["message"] = message
        
        if details is not None:
            task["details"] = details
        
        task["updated_at"] = datetime.now()
        return True
    
    def set_percentage(self, task_id: str, percentage: int,
                       message: str = None, details: str = None) -> bool:
        """
        直接设置任务进度百分比（用于无法预知总数的场景）

        Args:
            task_id: 任务ID
            percentage: 进度百分比 (0-100)
            message: 状态消息
            details: 详细信息

        Returns:
            是否更新成功
        """
        if task_id not in self._progress_store:
            return False

        task = self._progress_store[task_id]
        task["percentage"] = min(100, max(0, percentage))

        if message is not None:
            task["message"] = message

        if details is not None:
            task["details"] = details

        task["updated_at"] = datetime.now()
        return True

    def complete_task(self, task_id: str, success: bool = True,
                     result_message: str = None,
                     result_data: Dict[str, Any] = None) -> bool:
        """
        完成任务

        Args:
            task_id: 任务ID
            success: 是否成功
            result_message: 结果消息
            result_data: 结果数据（如下载文件信息）

        Returns:
            是否更新成功
        """
        if task_id not in self._progress_store:
            return False

        task = self._progress_store[task_id]
        task["completed"] = True
        task["success"] = success
        task["status"] = "success" if success else "failed"
        task["percentage"] = 100 if success else task.get("percentage", 0)

        if result_message:
            task["result_message"] = result_message

        if result_data:
            task["result_data"] = result_data

        task["updated_at"] = datetime.now()
        return True
    
    def get_progress(self, task_id: str) -> Optional[Dict[str, Any]]:
        """
        获取任务进度
        
        Args:
            task_id: 任务ID
            
        Returns:
            进度信息
        """
        return self._progress_store.get(task_id)
    
    def get_all_tasks(self, task_type: str = None) -> Dict[str, Dict[str, Any]]:
        """
        获取所有任务
        
        Args:
            task_type: 可选的任务类型过滤
            
        Returns:
            所有匹配的任务
        """
        if task_type:
            return {
                tid: task for tid, task in self._progress_store.items()
                if task.get("type") == task_type
            }
        return self._progress_store.copy()
    
    async def cleanup_old_tasks(self, max_age_hours: int = 24):
        """
        清理过期任务
        
        Args:
            max_age_hours: 最大保留时间（小时）
        """
        async with self._cleanup_lock:
            now = datetime.now()
            to_remove = []
            
            for task_id, task in self._progress_store.items():
                created_at = task.get("created_at")
                if created_at:
                    age_hours = (now - created_at).total_seconds() / 3600
                    if age_hours > max_age_hours:
                        to_remove.append(task_id)
            
            for task_id in to_remove:
                del self._progress_store[task_id]
            
            return len(to_remove)


# 全局进度服务实例
progress_service = ProgressService()