"""
进度API路由 - M24

功能: Dashboard进度显示

API端点:
- GET /api/progress/{project_name} - 获取项目进度
- GET /api/progress/summary - 获取所有项目汇总
- GET /api/progress/history - 获取进度历史

"""

import logging
from typing import Optional, List
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from backend.models.database import get_db, Project, ProjectSyncStatus
from backend.services.progress_service import ProgressService
from backend.services.oc_collab_client import OcCollabClient, OcCollabError

router = APIRouter()

oc_collab_client = OcCollabClient()
progress_service = ProgressService(client=oc_collab_client)


class ProgressResponse(BaseModel):
    """进度响应"""
    project: str
    progress: int
    requirements: dict
    bugs: dict
    todos: dict
    updated_at: Optional[datetime] = None


class SummaryResponse(BaseModel):
    """汇总响应"""
    total_projects: int
    active_projects: int
    avg_progress: int
    projects: List[dict]


class RequirementsProgress(BaseModel):
    """需求进度"""
    total: int
    completed: int
    in_progress: int
    pending: int
    progress_percentage: int


class BugsProgress(BaseModel):
    """BUG进度"""
    total: int
    resolved: int
    open: int
    progress_percentage: int


class TodosProgress(BaseModel):
    """TODO进度"""
    total: int
    completed: int
    pending: int
    progress_percentage: int


class ProjectProgressDetail(BaseModel):
    """项目进度详情"""
    project_name: str
    overall_progress: int
    requirements: RequirementsProgress
    bugs: BugsProgress
    todos: TodosProgress
    updated_at: Optional[datetime] = None


@router.get("/api/progress/{project_name}")
async def get_project_progress(
    project_name: str,
    db: Session = Depends(get_db)
):
    """
    获取项目进度
    
    Args:
        project_name: 项目名称
        
    Returns:
        ProgressResponse: 项目进度
    """
    try:
        progress = progress_service.get_project_progress(project_name)
        
        req_progress = RequirementsProgress(
            total=progress.requirements.total,
            completed=progress.requirements.completed,
            in_progress=progress.requirements.in_progress,
            pending=progress.requirements.pending,
            progress_percentage=int(progress.requirements.completed / progress.requirements.total * 100) if progress.requirements.total > 0 else 0
        )
        
        bugs_progress = BugsProgress(
            total=progress.bugs.total,
            resolved=progress.bugs.resolved,
            open=progress.bugs.open,
            progress_percentage=int(progress.bugs.resolved / progress.bugs.total * 100) if progress.bugs.total > 0 else 0
        )
        
        todos_progress = TodosProgress(
            total=progress.todos.total,
            completed=progress.todos.completed,
            pending=progress.todos.pending,
            progress_percentage=int(progress.todos.completed / progress.todos.total * 100) if progress.todos.total > 0 else 0
        )
        
        return {
            "project": project_name,
            "progress": progress.overall_progress,
            "requirements": {
                "total": req_progress.total,
                "completed": req_progress.completed,
                "in_progress": req_progress.in_progress,
                "pending": req_progress.pending,
                "progress_percentage": req_progress.progress_percentage
            },
            "bugs": {
                "total": bugs_progress.total,
                "resolved": bugs_progress.resolved,
                "open": bugs_progress.open,
                "progress_percentage": bugs_progress.progress_percentage
            },
            "todos": {
                "total": todos_progress.total,
                "completed": todos_progress.completed,
                "pending": todos_progress.pending,
                "progress_percentage": todos_progress.progress_percentage
            },
            "updated_at": progress.updated_at.isoformat() if progress.updated_at else None
        }
        
    except OcCollabError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/api/progress/summary")
async def get_projects_summary(
    project_names: Optional[List[str]] = Query(default=None),
    db: Session = Depends(get_db)
):
    """
    获取所有项目汇总
    
    Args:
        project_names: 项目名称列表（可选）
        
    Returns:
        SummaryResponse: 项目汇总
    """
    if project_names is None:
        try:
            projects = db.query(Project).filter(Project.status == 'active').all()
            project_names = [p.name for p in projects]
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"获取项目列表失败: {str(e)}")
    
    summary = progress_service.get_all_projects_summary(project_names)
    
    return {
        "total_projects": summary.total_projects,
        "active_projects": summary.active_projects,
        "avg_progress": summary.avg_progress,
        "projects": summary.projects
    }


@router.get("/api/progress/history")
async def get_progress_history(
    project_name: str,
    days: int = Query(default=30, le=365),
    db: Session = Depends(get_db)
):
    """
    获取进度历史
    
    Args:
        project_name: 项目名称
        days: 天数
        
    Returns:
        list: 进度历史列表
    """
    history = progress_service.get_progress_history(project_name, days)
    
    return {
        "project_name": project_name,
        "days": days,
        "history": history
    }


@router.get("/api/progress/all")
async def get_all_progress(
    db: Session = Depends(get_db)
):
    """
    获取所有项目进度
    
    Returns:
        list: 所有项目进度列表
    """
    results = []
    
    try:
        projects = db.query(Project).filter(Project.status == 'active').all()
        
        for project in projects:
            try:
                progress = progress_service.get_project_progress(project.name)
                
                results.append({
                    "project": project.name,
                    "progress": progress.overall_progress,
                    "requirements": {
                        "total": progress.requirements.total,
                        "completed": progress.requirements.completed
                    },
                    "bugs": {
                        "total": progress.bugs.total,
                        "resolved": progress.bugs.resolved
                    },
                    "todos": {
                        "total": progress.todos.total,
                        "completed": progress.todos.completed
                    },
                    "updated_at": progress.updated_at.isoformat() if progress.updated_at else None
                })
            except Exception as e:
                results.append({
                    "project": project.name,
                    "error": str(e)
                })
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取项目进度失败: {str(e)}")
    
    return {"projects": results}


@router.get("/api/progress/stats")
async def get_progress_stats(
    db: Session = Depends(get_db)
):
    """
    获取进度统计
    
    Returns:
        dict: 进度统计信息
    """
    try:
        projects = db.query(Project).filter(Project.status == 'active').all()
        
        stats = {
            "total_projects": len(projects),
            "completed_projects": 0,
            "in_progress_projects": 0,
            "not_started_projects": 0,
            "avg_progress": 0,
            "by_confidentiality": {
                "normal": {"total": 0, "avg_progress": 0},
                "confidential": {"total": 0, "avg_progress": 0}
            }
        }
        
        progress_list = []
        
        for project in projects:
            try:
                progress = progress_service.get_project_progress(project.name)
                progress_list.append({
                    "name": project.name,
                    "progress": progress.overall_progress,
                    "confidentiality": getattr(project, 'confidentiality', 'normal')
                })
            except Exception:
                progress_list.append({
                    "name": project.name,
                    "progress": 0,
                    "confidentiality": getattr(project, 'confidentiality', 'normal')
                })
        
        if progress_list:
            stats["avg_progress"] = sum(p["progress"] for p in progress_list) // len(progress_list)
            
            for p in progress_list:
                conf = p.get("confidentiality", "normal")
                stats["by_confidentiality"][conf]["total"] += 1
        
        return stats
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取进度统计失败: {str(e)}")


@router.post("/api/progress/save")
async def save_progress(
    project_name: str,
    db: Session = Depends(get_db)
):
    """
    保存项目进度到数据库
    
    Args:
        project_name: 项目名称
        
    Returns:
        dict: 保存结果
    """
    try:
        progress = progress_service.get_project_progress(project_name)
        progress_service.save_progress_to_db(progress, db)
        
        return {
            "status": "success",
            "project_name": project_name,
            "progress": progress.overall_progress,
            "saved_at": datetime.now().isoformat()
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存进度失败: {str(e)}")


@router.post("/api/progress/weights")
async def update_progress_weights(
    requirements: float = Query(default=0.4, ge=0, le=1),
    bugs: float = Query(default=0.3, ge=0, le=1),
    todos: float = Query(default=0.3, ge=0, le=1)
):
    """
    更新进度计算权重
    
    Args:
        requirements: 需求权重
        bugs: BUG权重
        todos: TODO权重
        
    Returns:
        dict: 更新结果
    """
    total = requirements + bugs + todos
    
    if abs(total - 1.0) > 0.01:
        raise HTTPException(status_code=400, detail="权重之和必须为1.0")
    
    progress_service.set_weights(requirements, bugs, todos)
    
    return {
        "status": "success",
        "weights": {
            "requirements": requirements,
            "bugs": bugs,
            "todos": todos
        }
    }
