#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：dependencies.py
模块描述：依赖管理 API 路由

作者：czj
创建日期：2026-07-12
"""

import logging
from typing import List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.services.dependency_service import DependencyService
from app.schemas.dependency import (
    DependencyResponse,
    SetDependenciesRequest,
    ValidateDependenciesResponse,
    ExecutionOrderResponse,
    DependencyStatusResponse,
)

logger = logging.getLogger(__name__)

router = APIRouter()


def get_dependency_service(db: AsyncSession = Depends(get_db)) -> DependencyService:
    """获取依赖管理服务"""
    return DependencyService(db)


@router.get("/cases/{case_id}/dependencies", response_model=List[DependencyResponse])
async def get_case_dependencies(
    case_id: str,
    service: DependencyService = Depends(get_dependency_service),
):
    """
    获取用例的所有依赖关系

    Args:
        case_id: 用例ID

    Returns:
        List[DependencyResponse]: 依赖关系列表
    """
    try:
        dependencies = await service.get_case_dependencies(case_id)
        return [DependencyResponse.model_validate(d) for d in dependencies]
    except Exception as e:
        logger.error(f"获取依赖关系失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取依赖关系失败: {str(e)}")


@router.post("/cases/{case_id}/dependencies", response_model=dict)
async def set_case_dependencies(
    case_id: str,
    request: SetDependenciesRequest,
    service: DependencyService = Depends(get_dependency_service),
):
    """
    设置用例依赖关系

    Args:
        case_id: 用例ID
        request: 依赖定义列表

    Returns:
        dict: 操作结果
    """
    try:
        # 转换为字典列表
        dependencies = [dep.model_dump() for dep in request.dependencies]
        success = await service.set_case_dependencies(case_id, dependencies)

        return {
            "success": success,
            "message": f"成功设置 {len(dependencies)} 个依赖关系"
        }
    except ValueError as e:
        logger.warning(f"设置依赖关系参数错误: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"设置依赖关系失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"设置依赖关系失败: {str(e)}")


@router.post("/validate", response_model=ValidateDependenciesResponse)
async def validate_dependencies(
    case_ids: List[str],
    service: DependencyService = Depends(get_dependency_service),
):
    """
    验证依赖关系是否有效（检测循环依赖）

    Args:
        case_ids: 用例ID列表

    Returns:
        ValidateDependenciesResponse: 验证结果
    """
    try:
        result = await service.validate_dependencies(case_ids)
        return ValidateDependenciesResponse(**result)
    except Exception as e:
        logger.error(f"验证依赖关系失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"验证依赖关系失败: {str(e)}")


@router.post("/execution-order", response_model=ExecutionOrderResponse)
async def get_execution_order(
    case_ids: List[str],
    service: DependencyService = Depends(get_dependency_service),
):
    """
    计算执行顺序（拓扑排序 + 优先级排序）

    Args:
        case_ids: 用例ID列表

    Returns:
        ExecutionOrderResponse: 执行顺序
    """
    try:
        ordered_ids, cycle = await service.topological_sort(case_ids, respect_priority=True)

        return ExecutionOrderResponse(
            ordered_case_ids=ordered_ids,
            has_cycle=cycle is not None,
            cycle_path=cycle
        )
    except Exception as e:
        logger.error(f"计算执行顺序失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"计算执行顺序失败: {str(e)}")


@router.get("/cases/{case_id}/dependency-status", response_model=DependencyStatusResponse)
async def check_dependency_status(
    case_id: str,
    execution_id: str,
    service: DependencyService = Depends(get_dependency_service),
):
    """
    检查用例依赖状态

    Args:
        case_id: 用例ID
        execution_id: 执行ID

    Returns:
        DependencyStatusResponse: 依赖状态
    """
    try:
        result = await service.check_dependency_status(case_id, execution_id)
        return DependencyStatusResponse(**result)
    except Exception as e:
        logger.error(f"检查依赖状态失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"检查依赖状态失败: {str(e)}")
