"""
Review System API Routes

审核系统 API 路由

提供审核配置、执行、维度和自定义规则的管理接口
"""
from fastapi import APIRouter, Depends, HTTPException, status
from typing import List, Optional
import uuid
from datetime import datetime

from app.models.review import (
    ReviewConfig,
    ReviewConfigUpdate,
    ReviewResult,
    ReviewRequest,
    ReviewResponse,
    DimensionInfo,
    DimensionConfig,
    DimensionType,
    CustomRule,
    CustomRuleCreate,
    CustomRuleUpdate,
    ReviewPreset
)
from app.models.project import SeriesProject, Episode
from app.core.review.review_manager import ReviewManager, get_review_manager
from app.db.repositories import project_repo, episode_repo
from app.utils.logger import get_logger


logger = get_logger(__name__)

router = APIRouter(prefix="/review", tags=["审核系统"])


# ============================================
# 项目审核配置管理
# ============================================

@router.get("/projects/{project_id}/review-config", response_model=ReviewConfig)
async def get_review_config(project_id: str):
    """
    获取项目的审核配置

    Args:
        project_id: 项目ID

    Returns:
        ReviewConfig: 审核配置
    """
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    # 从项目配置中获取审核配置
    # 如果还没有配置，返回默认配置
    review_config = getattr(project, 'reviewConfig', None)
    if not review_config:
        review_config = ReviewConfig()

    return review_config


@router.put("/projects/{project_id}/review-config", response_model=ReviewConfig)
async def update_review_config(
    project_id: str,
    config_update: ReviewConfigUpdate
):
    """
    更新项目的审核配置

    Args:
        project_id: 项目ID
        config_update: 配置更新数据

    Returns:
        ReviewConfig: 更新后的配置
    """
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    try:
        # 获取现有配置
        current_config = getattr(project, 'reviewConfig', ReviewConfig())

        # 更新配置
        update_data = config_update.dict(exclude_unset=True)

        for field, value in update_data.items():
            setattr(current_config, field, value)

        # 保存到项目
        await project_repo.update(project_id, {
            "reviewConfig": current_config.dict()
        })

        logger.info(f"更新项目审核配置: {project_id}")

        return current_config

    except Exception as e:
        logger.error(f"更新审核配置失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新配置失败: {str(e)}"
        )


@router.get("/projects/{project_id}/review-presets", response_model=List[ReviewPreset])
async def get_review_presets(project_id: str = None):
    """
    获取审核预设列表

    Args:
        project_id: 可选的项目ID，用于返回项目特定的预设

    Returns:
        List[ReviewPreset]: 预设列表
    """
    # 内置预设
    presets = [
        ReviewPreset(
            id="strict",
            name="严格审核",
            description="适用于高质量要求，检查所有维度",
            category="quality",
            config=ReviewConfig(
                enabled_review_skills=["consistency_checker"],
                overall_strictness=0.9,
                dimension_settings={
                    DimensionType.consistency: DimensionConfig(enabled=True, strictness=0.9, weight=1.2),
                    DimensionType.quality: DimensionConfig(enabled=True, strictness=0.8, weight=1.0),
                    DimensionType.pacing: DimensionConfig(enabled=True, strictness=0.7, weight=0.8),
                    DimensionType.dialogue: DimensionConfig(enabled=True, strictness=0.8, weight=1.0),
                    DimensionType.character: DimensionConfig(enabled=True, strictness=0.9, weight=1.1),
                    DimensionType.plot: DimensionConfig(enabled=True, strictness=0.9, weight=1.2)
                },
                pass_threshold=85.0
            )
        ),
        ReviewPreset(
            id="balanced",
            name="平衡审核",
            description="适用于一般创作需求，平衡质量和效率",
            category="general",
            config=ReviewConfig(
                enabled_review_skills=["consistency_checker"],
                overall_strictness=0.7,
                dimension_settings={
                    DimensionType.consistency: DimensionConfig(enabled=True, strictness=0.7, weight=1.2),
                    DimensionType.quality: DimensionConfig(enabled=True, strictness=0.6, weight=1.0),
                    DimensionType.pacing: DimensionConfig(enabled=False, strictness=0.5, weight=0.8),
                    DimensionType.dialogue: DimensionConfig(enabled=True, strictness=0.6, weight=1.0),
                    DimensionType.character: DimensionConfig(enabled=True, strictness=0.7, weight=1.1),
                    DimensionType.plot: DimensionConfig(enabled=True, strictness=0.7, weight=1.2)
                },
                pass_threshold=75.0
            )
        ),
        ReviewPreset(
            id="quick",
            name="快速审核",
            description="只检查核心维度，适用于快速迭代",
            category="efficiency",
            config=ReviewConfig(
                enabled_review_skills=["consistency_checker"],
                overall_strictness=0.5,
                dimension_settings={
                    DimensionType.consistency: DimensionConfig(enabled=True, strictness=0.7, weight=1.5),
                    DimensionType.quality: DimensionConfig(enabled=False, strictness=0.5, weight=1.0),
                    DimensionType.pacing: DimensionConfig(enabled=False, strictness=0.5, weight=0.8),
                    DimensionType.dialogue: DimensionConfig(enabled=False, strictness=0.5, weight=1.0),
                    DimensionType.character: DimensionConfig(enabled=False, strictness=0.5, weight=1.1),
                    DimensionType.plot: DimensionConfig(enabled=True, strictness=0.6, weight=1.5)
                },
                pass_threshold=70.0
            )
        ),
        ReviewPreset(
            id="dialogue_focused",
            name="对话专项",
            description="专注于对话质量和人物口吻",
            category="specialized",
            config=ReviewConfig(
                enabled_review_skills=[],
                overall_strictness=0.8,
                dimension_settings={
                    DimensionType.consistency: DimensionConfig(enabled=True, strictness=0.6, weight=0.8),
                    DimensionType.dialogue: DimensionConfig(enabled=True, strictness=0.9, weight=1.5),
                    DimensionType.character: DimensionConfig(enabled=True, strictness=0.8, weight=1.2)
                },
                pass_threshold=75.0
            )
        )
    ]

    return presets


# ============================================
# 审核执行
# ============================================

@router.post("/projects/{project_id}/episodes/{episode_number}/review", response_model=ReviewResponse)
async def review_episode(
    project_id: str,
    episode_number: int,
    request: ReviewRequest,
    review_mgr: ReviewManager = Depends(get_review_manager)
):
    """
    执行剧集审核

    Args:
        project_id: 项目ID
        episode_number: 集数
        request: 审核请求
        review_mgr: 审核管理器（依赖注入）

    Returns:
        ReviewResponse: 审核结果
    """
    # 获取项目
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    # 获取剧集
    episodes = await episode_repo.list_by_project(project_id)
    episode = None
    for ep in episodes:
        if ep.number == episode_number:
            episode = ep
            break

    if not episode:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"剧集不存在: EP{episode_number}"
        )

    # 检查剧集是否有内容
    if not episode.content:
        return ReviewResponse(
            success=False,
            message=f"剧集 EP{episode_number} 没有内容，无法审核",
            episode_id=episode.id
        )

    try:
        # 获取审核配置
        config = getattr(project, 'reviewConfig', ReviewConfig())

        # 执行审核
        logger.info(f"开始审核: 项目 {project_id}, EP{episode_number}")

        result = await review_mgr.review_episode(
            project=project,
            episode=episode,
            config=config,
            dimensions=request.dimensions
        )

        # 保存审核结果到剧集
        await episode_repo.update(project_id, {
            "reviewResult": result.dict(),
            "status": "completed" if result.passed else "needs-review"
        })

        logger.info(f"审核完成: EP{episode_number}, 分数={result.overall_score:.1f}")

        return ReviewResponse(
            success=True,
            review_result=result,
            message=f"审核完成，总分: {result.overall_score:.1f}",
            episode_id=episode.id
        )

    except Exception as e:
        logger.error(f"审核失败: {str(e)}")
        return ReviewResponse(
            success=False,
            message=f"审核失败: {str(e)}",
            episode_id=episode.id
        )


@router.get("/projects/{project_id}/episodes/{episode_number}/review-result", response_model=Optional[ReviewResult])
async def get_review_result(project_id: str, episode_number: int):
    """
    获取剧集的审核结果

    Args:
        project_id: 项目ID
        episode_number: 集数

    Returns:
        ReviewResult: 审核结果，如果未审核则返回null
    """
    episodes = await episode_repo.list_by_project(project_id)
    episode = None
    for ep in episodes:
        if ep.number == episode_number:
            episode = ep
            break

    if not episode:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"剧集不存在: EP{episode_number}"
        )

    # 返回审核结果（如果有）
    return getattr(episode, 'reviewResult', None)


# ============================================
# 维度管理
# ============================================

@router.get("/dimensions", response_model=List[DimensionInfo])
async def list_dimensions():
    """
    列出所有可用的审核维度

    Returns:
        List[DimensionInfo]: 维度信息列表
    """
    from app.core.review.review_manager import ReviewManager

    temp_manager = ReviewManager()

    dimensions = []
    for dim_type, dim_info in temp_manager.DIMENSIONS.items():
        dimension_info = DimensionInfo(
            id=dim_type,
            name=dim_info["name"],
            description=dim_info["description"],
            default_strictness=dim_info["default_strictness"],
            supported_skill_ids=dim_info["skill_ids"]
        )
        dimensions.append(dimension_info)

    return dimensions


@router.get("/dimensions/{dimension_id}", response_model=DimensionInfo)
async def get_dimension_info(dimension_id: DimensionType):
    """
    获取单个维度的详细信息

    Args:
        dimension_id: 维度ID

    Returns:
        DimensionInfo: 维度信息
    """
    from app.core.review.review_manager import ReviewManager

    temp_manager = ReviewManager()
    dim_info = temp_manager.DIMENSIONS.get(dimension_id)

    if not dim_info:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"维度不存在: {dimension_id}"
        )

    return DimensionInfo(
        id=dimension_id,
        name=dim_info["name"],
        description=dim_info["description"],
        default_strictness=dim_info["default_strictness"],
        supported_skill_ids=dim_info["skill_ids"]
    )


# ============================================
# 自定义规则管理
# ============================================

@router.get("/custom-rules", response_model=List[CustomRule])
async def list_custom_rules(
    project_id: Optional[str] = None,
    dimension: Optional[DimensionType] = None
):
    """
    列出自定义规则

    Args:
        project_id: 可选的项目ID，只返回该项目的规则
        dimension: 可选的维度筛选

    Returns:
        List[CustomRule]: 自定义规则列表
    """
    if project_id:
        # 从项目获取规则
        project = await project_repo.get(project_id)
        if not project:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"项目不存在: {project_id}"
            )

        config = getattr(project, 'reviewConfig', ReviewConfig())
        rules = config.custom_rules
    else:
        # 返回空列表（暂时不支持全局规则）
        rules = []

    # 按维度筛选
    if dimension:
        rules = [r for r in rules if r.dimension == dimension]

    return rules


@router.post("/custom-rules", response_model=CustomRule, status_code=status.HTTP_201_CREATED)
async def create_custom_rule(
    rule_data: CustomRuleCreate,
    project_id: str
):
    """
    创建自定义规则

    Args:
        rule_data: 规则创建数据
        project_id: 项目ID

    Returns:
        CustomRule: 创建的规则
    """
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    try:
        # 创建规则
        new_rule = CustomRule(
            id=str(uuid.uuid4()),
            name=rule_data.name,
            description=rule_data.description,
            trigger_condition=rule_data.trigger_condition,
            dimension=rule_data.dimension,
            severity=rule_data.severity,
            enabled=True
        )

        # 添加到项目配置
        config = getattr(project, 'reviewConfig', ReviewConfig())
        config.custom_rules.append(new_rule)

        # 保存
        await project_repo.update(project_id, {
            "reviewConfig": config.dict()
        })

        logger.info(f"创建自定义规则: {new_rule.id}")

        return new_rule

    except Exception as e:
        logger.error(f"创建自定义规则失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"创建规则失败: {str(e)}"
        )


@router.put("/custom-rules/{rule_id}", response_model=CustomRule)
async def update_custom_rule(
    rule_id: str,
    rule_update: CustomRuleUpdate,
    project_id: str
):
    """
    更新自定义规则

    Args:
        rule_id: 规则ID
        rule_update: 规则更新数据
        project_id: 项目ID

    Returns:
        CustomRule: 更新后的规则
    """
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    config = getattr(project, 'reviewConfig', ReviewConfig())

    # 查找规则
    rule = None
    for r in config.custom_rules:
        if r.id == rule_id:
            rule = r
            break

    if not rule:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"规则不存在: {rule_id}"
        )

    try:
        # 更新规则
        update_data = rule_update.dict(exclude_unset=True)

        for field, value in update_data.items():
            setattr(rule, field, value)

        rule.updated_at = datetime.now()

        # 保存
        await project_repo.update(project_id, {
            "reviewConfig": config.dict()
        })

        logger.info(f"更新自定义规则: {rule_id}")

        return rule

    except Exception as e:
        logger.error(f"更新自定义规则失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新规则失败: {str(e)}"
        )


@router.delete("/custom-rules/{rule_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_custom_rule(rule_id: str, project_id: str):
    """
    删除自定义规则

    Args:
        rule_id: 规则ID
        project_id: 项目ID

    Returns:
        None
    """
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    config = getattr(project, 'reviewConfig', ReviewConfig())

    # 查找并删除规则
    original_count = len(config.custom_rules)
    config.custom_rules = [r for r in config.custom_rules if r.id != rule_id]

    if len(config.custom_rules) == original_count:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"规则不存在: {rule_id}"
        )

    try:
        # 保存
        await project_repo.update(project_id, {
            "reviewConfig": config.dict()
        })

        logger.info(f"删除自定义规则: {rule_id}")

        return None

    except Exception as e:
        logger.error(f"删除自定义规则失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"删除规则失败: {str(e)}"
        )


@router.post("/custom-rules/{rule_id}/test")
async def test_custom_rule(
    rule_id: str,
    episode_id: str,
    project_id: str,
    review_mgr: ReviewManager = Depends(get_review_manager)
):
    """
    测试自定义规则

    Args:
        rule_id: 规则ID
        episode_id: 剧集ID
        project_id: 项目ID
        review_mgr: 审核管理器

    Returns:
        测试结果
    """
    project = await project_repo.get(project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"项目不存在: {project_id}"
        )

    episode = await episode_repo.get(episode_id)
    if not episode:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"剧集不存在: {episode_id}"
        )

    config = getattr(project, 'reviewConfig', ReviewConfig())

    # 查找规则
    rule = None
    for r in config.custom_rules:
        if r.id == rule_id:
            rule = r
            break

    if not rule:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"规则不存在: {rule_id}"
        )

    try:
        # 测试规则
        issues = await review_mgr._check_single_rule(
            episode=episode,
            rule=rule,
            config=config
        )

        return {
            "rule_id": rule_id,
            "rule_name": rule.name,
            "episode_id": episode_id,
            "violations": len(issues),
            "issues": [issue.dict() for issue in issues]
        }

    except Exception as e:
        logger.error(f"测试规则失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"测试失败: {str(e)}"
        )
