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

作者：czj
创建日期：2026-07-09
最后修改：2026-07-09
"""

import logging
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import HTMLResponse, FileResponse
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, desc

from app.database import get_db
from app.models.execution import Execution
from app.services.execution_service import ExecutionService
from app.services.report_service import ReportService

logger = logging.getLogger(__name__)

router = APIRouter()


def get_execution_service(db: AsyncSession = Depends(get_db)) -> ExecutionService:
    """获取执行服务实例"""
    return ExecutionService(db)


@router.get("/generate/{execution_id}", response_class=HTMLResponse)
async def generate_report(
    execution_id: str,
    db: AsyncSession = Depends(get_db),
):
    """
    生成并返回 HTML 测试报告

    Args:
        execution_id (str): 执行记录ID
        db (AsyncSession): 数据库会话

    Returns:
        HTMLResponse: HTML 报告内容
    """
    try:
        report_service = ReportService()
        html = await report_service.generate_html(execution_id, db)
        return HTMLResponse(content=html)
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.error(f"生成报告失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"生成报告失败: {str(e)}")


@router.post("/export/{execution_id}", response_model=dict)
async def export_report(
    execution_id: str,
    db: AsyncSession = Depends(get_db),
):
    """
    导出报告为文件

    Args:
        execution_id (str): 执行记录ID
        db (AsyncSession): 数据库会话

    Returns:
        dict: 包含文件路径
    """
    try:
        report_service = ReportService()
        html = await report_service.generate_html(execution_id, db)
        file_path = await report_service.save_report(execution_id, html)

        return {
            "message": "报告已导出",
            "file_path": file_path,
            "execution_id": execution_id,
        }
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.error(f"导出报告失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"导出报告失败: {str(e)}")


@router.get("/download/{execution_id}")
async def download_report(
    execution_id: str,
    db: AsyncSession = Depends(get_db),
):
    """
    下载已导出的报告文件

    Args:
        execution_id (str): 执行记录ID
        db (AsyncSession): 数据库会话

    Returns:
        FileResponse: 报告文件
    """
    try:
        report_service = ReportService()
        file_path = await report_service.get_report_path(execution_id)

        if not file_path:
            # 如果没有缓存，先生成
            html = await report_service.generate_html(execution_id, db)
            file_path = await report_service.save_report(execution_id, html)

        return FileResponse(
            file_path,
            media_type="text/html",
            filename=f"test_report_{execution_id}.html",
        )
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.error(f"下载报告失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"下载报告失败: {str(e)}")


@router.get("/list", response_model=dict)
async def list_reports(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(50, ge=1, le=200, description="返回记录数上限"),
    case_type: Optional[str] = Query(None, description="用例类型筛选: ui/api/security/deploy/performance/functional"),
    db: AsyncSession = Depends(get_db),
):
    """
    获取可生成报告的已完成执行记录列表

    Args:
        skip (int): 跳过记录数
        limit (int): 返回记录数上限
        case_type (Optional[str]): 用例类型筛选（按关联执行的 case_type）
        db (AsyncSession): 数据库会话

    Returns:
        dict: 执行记录列表
    """
    from sqlalchemy import func

    # 构建筛选条件：已完成 + 可选按用例类型
    conditions = [Execution.status == "completed"]
    if case_type:
        conditions.append(Execution.case_type == case_type)

    query = (
        select(Execution)
        .where(*conditions)
        .order_by(desc(Execution.created_at))
        .offset(skip)
        .limit(limit)
    )
    result = await db.execute(query)
    items = result.scalars().all()

    count_query = select(func.count(Execution.id)).where(*conditions)
    result = await db.execute(count_query)
    total = result.scalar() or 0

    return {
        "total": total,
        "items": [
            {
                "id": e.id,
                "name": e.name,
                "pass_rate": e.pass_rate,
                "total_cases": e.total_cases,
                "passed": e.passed,
                "failed": e.failed,
                "duration": e.duration,
                "created_at": e.created_at.isoformat() if e.created_at else None,
            }
            for e in items
        ],
    }
