"""
Confirm Cards API Routes

确认卡片API路由 - 提供确认卡片的CRUD操作
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from typing import List, Optional
from datetime import datetime, timedelta

from app.models.confirm_card import (
    ConfirmCard, ConfirmCardStatus, ConfirmCardOption
)
from app.db.confirm_card_repository import get_confirm_card_repo
from app.api.v1.websocket import manager
from app.utils.logger import get_logger

logger = get_logger(__name__)

router = APIRouter(prefix="/confirm-cards", tags=["确认卡片"])


# ============================================
# 依赖注入
# ============================================

async def get_repo():
    """获取确认卡片仓储"""
    return get_confirm_card_repo()


# ============================================
# CRUD 端点
# ============================================

@router.post("")
async def create_confirm_card(
    card: ConfirmCard,
    repo=Depends(get_repo)
):
    """
    创建确认卡片

    由Agent推送，用户可中途退出后随时确认
    """
    try:
        created_card = await repo.create(card)

        # WebSocket推送
        await manager.send_to_project(card.project_id, {
            "type": "confirm_card_created",
            "data": {
                "card_id": card.id,
                "card_type": card.card_type.value,
                "title": card.title,
                "description": card.description[:200] + "..." if len(card.description) > 200 else card.description,
                "options_count": len(card.options),
                "created_at": card.created_at.isoformat()
            }
        })

        logger.info(f"创建确认卡片成功: {card.id}")
        return {"success": True, "card": created_card}

    except Exception as e:
        logger.error(f"创建确认卡片失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"创建确认卡片失败: {str(e)}")


@router.post("/simple")
async def create_confirm_card_simple(
    project_id: str,
    card_type: str,
    title: str,
    description: str,
    options: Optional[List[dict]] = None,
    episode_number: Optional[int] = None,
    allow_custom_response: bool = False,
    expires_in_hours: Optional[int] = None,
    repo=Depends(get_repo)
):
    """
    简化创建确认卡片

    用于Agent快速推送确认任务
    """
    try:
        # 构建选项列表
        card_options = []
        if options:
            for i, opt in enumerate(options):
                if isinstance(opt, dict):
                    card_options.append(ConfirmCardOption(
                        id=opt.get("id", f"opt_{i}"),
                        label=opt.get("label", f"选项 {i+1}"),
                        description=opt.get("description", ""),
                        implications=opt.get("implications")
                    ))
                elif isinstance(opt, str):
                    card_options.append(ConfirmCardOption(
                        id=f"opt_{i}",
                        label=opt,
                        description=""
                    ))

        # 计算过期时间
        expires_at = None
        if expires_in_hours:
            expires_at = datetime.now() + timedelta(hours=expires_in_hours)

        from app.models.confirm_card import ConfirmCardType
        # 创建卡片
        card = ConfirmCard(
            id=None,  # 由repository生成
            project_id=project_id,
            episode_number=episode_number,
            card_type=ConfirmCardType(card_type),
            title=title,
            description=description,
            options=card_options,
            allow_custom_response=allow_custom_response,
            expires_at=expires_at
        )

        created_card = await repo.create(card)

        # WebSocket推送
        await manager.send_to_project(project_id, {
            "type": "confirm_card_created",
            "data": {
                "card_id": created_card.id,
                "card_type": card.card_type.value,
                "title": card.title,
                "description": card.description[:200] + "..." if len(card.description) > 200 else card.description,
                "options": [{"id": o.id, "label": o.label} for o in card_options],
                "created_at": created_card.created_at.isoformat()
            }
        })

        logger.info(f"简化创建确认卡片成功: {created_card.id}")
        return {"success": True, "card_id": created_card.id, "card": created_card}

    except Exception as e:
        logger.error(f"简化创建确认卡片失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"创建确认卡片失败: {str(e)}")


@router.get("")
async def list_confirm_cards(
    project_id: str,
    status: Optional[ConfirmCardStatus] = None,
    include_expired: bool = False,
    repo=Depends(get_repo)
) -> List[ConfirmCard]:
    """
    获取确认卡片列表

    默认不包含过期的卡片
    """
    try:
        return await repo.list_by_project(project_id, status, include_expired)

    except Exception as e:
        logger.error(f"获取确认卡片列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取列表失败: {str(e)}")


@router.get("/{card_id}")
async def get_confirm_card(
    card_id: str,
    repo=Depends(get_repo)
) -> ConfirmCard:
    """获取确认卡片详情"""
    card = await repo.get(card_id)
    if not card:
        raise HTTPException(status_code=404, detail="确认卡片不存在")

    # 检查是否过期
    if card.expires_at and card.expires_at < datetime.now():
        if card.status == ConfirmCardStatus.PENDING:
            card.status = ConfirmCardStatus.EXPIRED

    return card


@router.delete("/{card_id}")
async def delete_confirm_card(
    card_id: str,
    repo=Depends(get_repo)
):
    """删除确认卡片"""
    try:
        success = await repo.delete(card_id)
        if not success:
            raise HTTPException(status_code=404, detail="确认卡片不存在")

        logger.info(f"删除确认卡片成功: {card_id}")
        return {"success": True}

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除确认卡片失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"删除失败: {str(e)}")


# ============================================
# 操作端点
# ============================================

@router.post("/{card_id}/confirm")
async def confirm_card(
    card_id: str,
    selected_option_id: Optional[str] = None,
    custom_response: Optional[str] = None,
    user_notes: Optional[str] = None,
    repo=Depends(get_repo)
):
    """
    确认卡片

    用户选择一个选项或提供自定义回复
    """
    try:
        card = await repo.get(card_id)
        if not card:
            raise HTTPException(status_code=404, detail="确认卡片不存在")

        # 检查是否过期
        if card.expires_at and card.expires_at < datetime.now():
            await repo.update_status(card_id, ConfirmCardStatus.EXPIRED)
            raise HTTPException(status_code=400, detail="确认卡片已过期")

        # 更新状态
        updated_card = await repo.update_status(
            card_id,
            ConfirmCardStatus.APPROVED,
            selected_option_id,
            custom_response,
            user_notes
        )

        # WebSocket通知
        await manager.send_to_project(card.project_id, {
            "type": "confirm_card_confirmed",
            "data": {
                "card_id": card_id,
                "status": "approved",
                "selected_option": selected_option_id,
                "custom_response": custom_response,
                "confirmed_at": updated_card.confirmed_at.isoformat() if updated_card.confirmed_at else None
            }
        })

        logger.info(f"确认卡片成功: {card_id}, 选择: {selected_option_id}")
        return {"success": True, "card": updated_card}

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"确认卡片失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"操作失败: {str(e)}")


@router.post("/{card_id}/reject")
async def reject_card(
    card_id: str,
    user_notes: Optional[str] = None,
    repo=Depends(get_repo)
):
    """
    拒绝确认卡片

    用户拒绝该确认任务
    """
    try:
        updated_card = await repo.update_status(
            card_id,
            ConfirmCardStatus.REJECTED,
            user_notes=user_notes
        )

        if not updated_card:
            raise HTTPException(status_code=404, detail="确认卡片不存在")

        # WebSocket通知
        await manager.send_to_project(updated_card.project_id, {
            "type": "confirm_card_rejected",
            "data": {
                "card_id": card_id,
                "status": "rejected",
                "user_notes": user_notes
            }
        })

        logger.info(f"拒绝确认卡片成功: {card_id}")
        return {"success": True, "card": updated_card}

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"拒绝确认卡片失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"操作失败: {str(e)}")


@router.post("/cleanup-expired")
async def cleanup_expired_cards(repo=Depends(get_repo)):
    """
    清理过期的确认卡片

    将过期且仍为pending状态的卡片标记为expired
    """
    try:
        count = await repo.cleanup_expired()
        logger.info(f"清理过期确认卡片: {count}个")
        return {"success": True, "cleaned_count": count}

    except Exception as e:
        logger.error(f"清理过期卡片失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"清理失败: {str(e)}")
