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

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

import logging
from typing import Optional

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

from app.database import get_db
from app.schemas.module import (
    ModuleCreate,
    ModuleUpdate,
    ModuleResponse,
    ModuleListResponse,
)
from app.services.module_service import ModuleService

logger = logging.getLogger(__name__)

# 创建路由实例
router = APIRouter()


def get_module_service(db: AsyncSession = Depends(get_db)) -> ModuleService:
    """
    获取模块服务实例（依赖注入）

    Args:
        db (AsyncSession): 数据库会话

    Returns:
        ModuleService: 模块服务实例
    """
    return ModuleService(db)


@router.get("", response_model=ModuleListResponse)
async def list_modules(
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(100, ge=1, le=500, description="返回记录数上限"),
    module_type: Optional[str] = Query(None, description="模块类型筛选: standard/custom"),
    case_type: Optional[str] = Query(None, description="用例类型筛选: ui/security/all"),
    service: ModuleService = Depends(get_module_service)
):
    """
    获取模块列表

    支持分页查询，按排序号升序返回，可按模块类型或用例类型筛选。

    Args:
        skip (int): 跳过的记录数
        limit (int): 返回记录数上限
        module_type (Optional[str]): 模块类型筛选 standard/custom
        case_type (Optional[str]): 用例类型筛选 ui/security/all
            - ui: 只返回 UI 测试模块
            - security: 只返回安全测试模块
            - all 或不传: 返回全部模块
        service (ModuleService): 模块服务实例

    Returns:
        ModuleListResponse: 模块列表响应
    """
    try:
        modules, total = await service.list(
            skip=skip, limit=limit, module_type=module_type, case_type=case_type
        )

        # 转换为响应格式
        items = [
            ModuleResponse(
                id=m.id,
                name=m.name,
                description=m.description,
                icon=m.icon,
                order=m.order,
                module_type=getattr(m, 'module_type', 'standard') or 'standard',
                parent_id=getattr(m, 'parent_id', None),
                created_at=m.created_at,
                updated_at=m.updated_at,
                case_count=getattr(m, 'case_count', 0)
            )
            for m in modules
        ]

        return ModuleListResponse(total=total, items=items)

    except Exception as e:
        logger.error(f"获取模块列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")


@router.get("/{module_id}", response_model=ModuleResponse)
async def get_module(
    module_id: str,
    service: ModuleService = Depends(get_module_service)
):
    """
    获取单个模块详情

    Args:
        module_id (str): 模块ID
        service (ModuleService): 模块服务实例

    Returns:
        ModuleResponse: 模块详情

    Raises:
        HTTPException: 模块不存在时返回404
    """
    try:
        module = await service.get(module_id)
        if not module:
            raise HTTPException(status_code=404, detail=f"模块不存在: {module_id}")

        return ModuleResponse(
            id=module.id,
            name=module.name,
            description=module.description,
            icon=module.icon,
            order=module.order,
            module_type=getattr(module, 'module_type', 'standard') or 'standard',
            parent_id=getattr(module, 'parent_id', None),
            created_at=module.created_at,
            updated_at=module.updated_at,
            case_count=getattr(module, 'case_count', 0)
        )

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取模块详情失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")


@router.post("", response_model=ModuleResponse, status_code=201)
async def create_module(
    data: ModuleCreate,
    service: ModuleService = Depends(get_module_service)
):
    """
    创建测试模块

    Args:
        data (ModuleCreate): 模块创建数据
        service (ModuleService): 模块服务实例

    Returns:
        ModuleResponse: 创建的模块信息

    Raises:
        HTTPException: 参数校验失败时返回400
    """
    try:
        module = await service.create(data)
        return ModuleResponse(
            id=module.id,
            name=module.name,
            description=module.description,
            icon=module.icon,
            order=module.order,
            module_type=getattr(module, 'module_type', 'standard') or 'standard',
            parent_id=getattr(module, 'parent_id', None),
            created_at=module.created_at,
            updated_at=module.updated_at,
            case_count=0
        )

    except ValueError as 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.put("/{module_id}", response_model=ModuleResponse)
async def update_module(
    module_id: str,
    data: ModuleUpdate,
    service: ModuleService = Depends(get_module_service)
):
    """
    更新测试模块

    只更新传入的非空字段。

    Args:
        module_id (str): 模块ID
        data (ModuleUpdate): 更新数据
        service (ModuleService): 模块服务实例

    Returns:
        ModuleResponse: 更新后的模块信息

    Raises:
        HTTPException: 模块不存在时返回404
    """
    try:
        module = await service.update(module_id, data)
        if not module:
            raise HTTPException(status_code=404, detail=f"模块不存在: {module_id}")

        return ModuleResponse(
            id=module.id,
            name=module.name,
            description=module.description,
            icon=module.icon,
            order=module.order,
            module_type=getattr(module, 'module_type', 'standard') or 'standard',
            parent_id=getattr(module, 'parent_id', None),
            created_at=module.created_at,
            updated_at=module.updated_at,
            case_count=getattr(module, 'case_count', 0)
        )

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新模块失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")


@router.delete("/{module_id}", status_code=204)
async def delete_module(
    module_id: str,
    service: ModuleService = Depends(get_module_service)
):
    """
    删除测试模块

    删除模块及其下所有用例（级联删除）。

    Args:
        module_id (str): 模块ID
        service (ModuleService): 模块服务实例

    Raises:
        HTTPException: 模块不存在时返回404
    """
    try:
        deleted = await service.delete(module_id)
        if not deleted:
            raise HTTPException(status_code=404, detail=f"模块不存在: {module_id}")

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除模块失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")


@router.get("/{module_id}/stats")
async def get_module_stats(
    module_id: str,
    service: ModuleService = Depends(get_module_service)
):
    """
    获取模块统计信息

    Args:
        module_id (str): 模块ID
        service (ModuleService): 模块服务实例

    Returns:
        dict: 统计信息

    Raises:
        HTTPException: 模块不存在时返回404
    """
    try:
        stats = await service.get_stats(module_id)
        if not stats:
            raise HTTPException(status_code=404, detail=f"模块不存在: {module_id}")
        return stats

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取模块统计失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")