#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：api_test.py
模块描述：接口测试 API 路由 — 用例管理、执行、结果查询

作者：czj
创建日期：2026-08-17
"""

import asyncio
import logging
from typing import Optional, List

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

from app.database import get_db
from app.schemas.api_test import (
    ApiTestExecuteRequest,
    ApiTestExecuteResponse,
    ApiTestResultItem,
    ApiTestExecutionSummary,
)
from app.services.api_test_service import ApiTestService

logger = logging.getLogger(__name__)

router = APIRouter()


# ==================== 用例管理 ====================

@router.get("/cases", summary="获取接口测试用例列表")
async def list_api_cases(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(20, ge=1, le=100, description="返回记录数"),
    module_id: Optional[str] = Query(None, description="模块ID筛选"),
    keyword: Optional[str] = Query(None, description="关键字搜索"),
    db: AsyncSession = Depends(get_db),
):
    """
    获取接口测试用例列表

    Returns:
        dict: 用例列表和总数
    """
    service = ApiTestService(db)
    cases, total = await service.get_api_cases(
        skip=skip, limit=limit, module_id=module_id, keyword=keyword
    )
    return {
        "items": [c.to_dict() for c in cases],
        "total": total,
    }


@router.get("/cases/{case_id}", summary="获取接口测试用例详情")
async def get_api_case(
    case_id: str,
    db: AsyncSession = Depends(get_db),
):
    """
    获取接口测试用例详情

    Args:
        case_id: 用例ID

    Returns:
        dict: 用例详情
    """
    service = ApiTestService(db)
    case = await service.get_api_case(case_id)
    if not case:
        raise HTTPException(status_code=404, detail=f"接口测试用例不存在: {case_id}")
    return case.to_dict()


# ==================== 执行管理 ====================

@router.post("/executions", summary="创建接口测试执行")
async def create_execution(
    request: ApiTestExecuteRequest,
    db: AsyncSession = Depends(get_db),
):
    """
    创建接口测试执行记录

    Args:
        request: 执行请求（含用例ID列表、目标URL、配置ID）

    Returns:
        ApiTestExecuteResponse: 执行记录
    """
    service = ApiTestService(db)
    execution = await service.create_execution(
        case_ids=request.case_ids,
        target_url=request.target_url,
        config_id=request.config_id,
    )
    return ApiTestExecuteResponse(
        execution_id=execution.id,
        status=execution.status,
        message=f"已创建执行记录，共 {execution.total_cases} 个用例",
    )


@router.post("/executions/{execution_id}/run", summary="执行接口测试")
async def run_execution(
    execution_id: str,
    db: AsyncSession = Depends(get_db),
):
    """
    触发接口测试执行（异步）

    Args:
        execution_id: 执行ID

    Returns:
        dict: 执行状态
    """
    service = ApiTestService(db)

    # 异步执行（不等待完成）
    asyncio.create_task(service.run_execution(execution_id))

    return {
        "execution_id": execution_id,
        "status": "running",
        "message": "接口测试已开始执行",
    }


@router.get("/executions", summary="获取接口测试执行记录列表")
async def list_executions(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(20, ge=1, le=100, description="返回记录数"),
    db: AsyncSession = Depends(get_db),
):
    """
    获取接口测试执行记录列表

    Returns:
        dict: 执行记录列表和总数
    """
    service = ApiTestService(db)
    executions, total = await service.get_executions(skip=skip, limit=limit)
    return {
        "items": [e.to_dict() for e in executions],
        "total": total,
    }


@router.get("/executions/{execution_id}/results", summary="获取接口测试执行结果")
async def get_execution_results(
    execution_id: str,
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(50, ge=1, le=200, description="返回记录数"),
    db: AsyncSession = Depends(get_db),
):
    """
    获取接口测试执行结果详情

    Args:
        execution_id: 执行ID

    Returns:
        ApiTestExecutionSummary: 执行结果摘要
    """
    service = ApiTestService(db)

    # 获取执行记录
    from app.models.execution import Execution
    from sqlalchemy import select

    result = await db.execute(
        select(Execution).where(Execution.id == execution_id)
    )
    execution = result.scalar_one_or_none()
    if not execution:
        raise HTTPException(status_code=404, detail=f"执行记录不存在: {execution_id}")

    # 获取结果列表
    case_results, total = await service.get_execution_results(
        execution_id=execution_id, skip=skip, limit=limit
    )

    # 转换结果
    items = []
    for cr in case_results:
        items.append(ApiTestResultItem(
            case_id=cr.case_id or "",
            case_name=cr.case_name,
            status=cr.status,
            duration=cr.duration,
            error=cr.error_message or "",
        ))

    return ApiTestExecutionSummary(
        execution_id=execution.id,
        name=execution.name,
        status=execution.status,
        total=execution.total_cases,
        passed=execution.passed,
        failed=execution.failed,
        start_time=execution.start_time.isoformat() if execution.start_time else None,
        end_time=execution.end_time.isoformat() if execution.end_time else None,
        duration=execution.duration,
        results=items,
    )


@router.get("/executions/{execution_id}/result/{case_result_id}", summary="获取单个用例执行详情")
async def get_case_result_detail(
    execution_id: str,
    case_result_id: str,
    db: AsyncSession = Depends(get_db),
):
    """
    获取单个用例的执行详情（含请求/响应/断言结果）

    Args:
        execution_id: 执行ID
        case_result_id: 用例结果ID

    Returns:
        dict: 用例执行详情
    """
    from app.models.case_result import CaseResult
    from sqlalchemy import select

    result = await db.execute(
        select(CaseResult).where(
            CaseResult.id == case_result_id,
            CaseResult.execution_id == execution_id,
        )
    )
    case_result = result.scalar_one_or_none()
    if not case_result:
        raise HTTPException(status_code=404, detail="用例结果不存在")

    return case_result.to_dict()