"""
Playbook API Router - #7 Playbook 萃取
======================================
Playbook CRUD API 端點

Phase 7.4: API Router 實作
建立時間: 2026-03-26 (台北時區)
建立者: Claude Code (#7 Playbook 萃取)

遵循 leWOOOgo 積木化原則:
- Router 層只做 HTTP 轉發
- 不直接存取 Redis/DB
- 業務邏輯委託給 Service 層
"""

from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel

from src.models.playbook import (
    Playbook,
    PlaybookApproveRequest,
    PlaybookListResponse,
    PlaybookRecommendation,
    PlaybookResponse,
    PlaybookSource,
    PlaybookStatus,
    PlaybookUpdateRequest,
    SymptomPatternRequest,
)
from src.services.playbook_service import get_playbook_service

router = APIRouter(prefix="/playbooks", tags=["Playbooks"])


# =============================================================================
# Response Models
# =============================================================================


class ExtractPlaybookResponse(BaseModel):
    """萃取 Playbook 回應"""

    success: bool
    playbook: Playbook | None = None
    message: str


class DeletePlaybookResponse(BaseModel):
    """刪除 Playbook 回應"""

    success: bool
    message: str


class CreatePlaybookResponse(BaseModel):
    """建立 Playbook 回應"""

    success: bool
    playbook_id: str
    message: str


# =============================================================================
# API Endpoints
# =============================================================================


# 2026-04-05 Claude Code: Sprint 3 — 直接建立 Playbook (seed 腳本用)
@router.post("/", response_model=CreatePlaybookResponse)
async def create_playbook(playbook: Playbook) -> CreatePlaybookResponse:
    """直接建立 Playbook（管理/seed 用途）"""
    service = get_playbook_service()
    playbook.source = PlaybookSource.MANUAL
    saved = await service.create(playbook)
    return CreatePlaybookResponse(
        success=True,
        playbook_id=saved.playbook_id,
        message=f"Playbook '{saved.name}' created",
    )


@router.post("/extract/{incident_id}", response_model=ExtractPlaybookResponse)
async def extract_playbook(
    incident_id: str,
    auto_approve: bool = Query(False, description="自動核准 (僅限高信心度)"),
) -> ExtractPlaybookResponse:
    """
    從成功案例萃取 Playbook

    前置條件:
    - Incident 狀態為 RESOLVED 或 CLOSED
    - 執行成功且 effectiveness_score >= 4
    """
    # 取得 Incident (需要從 incident_service 取得)
    from src.services.incident_service import get_incident_service

    incident_service = get_incident_service()
    incident = await incident_service.get_incident(incident_id)

    if not incident:
        raise HTTPException(
            status_code=404,
            detail=f"Incident {incident_id} not found",
        )

    service = get_playbook_service()
    playbook = await service.extract_from_incident(
        incident=incident,
        auto_approve=auto_approve,
    )

    if playbook:
        return ExtractPlaybookResponse(
            success=True,
            playbook=playbook,
            message=f"Playbook {playbook.playbook_id} extracted successfully",
        )
    else:
        return ExtractPlaybookResponse(
            success=False,
            playbook=None,
            message="Cannot extract playbook: incident does not meet requirements",
        )


@router.post("/recommend", response_model=list[PlaybookRecommendation])
async def get_recommendations(
    symptoms: SymptomPatternRequest,
    top_k: int = Query(3, ge=1, le=10, description="返回數量"),
) -> list[PlaybookRecommendation]:
    """
    根據症狀取得 Playbook 推薦

    輸入症狀模式，返回最相似的 Playbooks
    """
    service = get_playbook_service()
    recommendations = await service.get_recommendations(
        symptoms=symptoms.to_symptom_pattern(),
        top_k=top_k,
    )
    return recommendations


@router.post("/{playbook_id}/approve", response_model=PlaybookResponse)
async def approve_playbook(
    playbook_id: str,
    request: PlaybookApproveRequest,
) -> PlaybookResponse:
    """
    人工核准 Playbook

    將 DRAFT 狀態的 Playbook 核准為 APPROVED
    """
    service = get_playbook_service()
    playbook = await service.approve(
        playbook_id=playbook_id,
        approved_by=request.approved_by,
        notes=request.notes,
    )

    if not playbook:
        raise HTTPException(
            status_code=404,
            detail=f"Playbook {playbook_id} not found or not in DRAFT status",
        )

    return PlaybookResponse.from_playbook(playbook)


@router.get("/", response_model=PlaybookListResponse)
async def list_playbooks(
    status: PlaybookStatus | None = Query(default=None, description="狀態過濾"),  # noqa: B008
    tags: list[str] | None = Query(default=None, description="標籤過濾"),  # noqa: B008
    limit: int = Query(default=20, ge=1, le=100, description="每頁數量"),
    offset: int = Query(default=0, ge=0, description="偏移量"),
) -> PlaybookListResponse:
    """
    取得 Playbook 列表

    支援狀態和標籤過濾
    """
    service = get_playbook_service()
    items, total = await service.list_playbooks(
        status=status,
        tags=tags,
        limit=limit,
        offset=offset,
    )

    return PlaybookListResponse(
        items=[PlaybookResponse.from_playbook(p) for p in items],
        total=total,
        limit=limit,
        offset=offset,
    )


@router.get("/{playbook_id}", response_model=PlaybookResponse)
async def get_playbook(playbook_id: str) -> PlaybookResponse:
    """取得單一 Playbook"""
    service = get_playbook_service()
    playbook = await service.get_by_id(playbook_id)

    if not playbook:
        raise HTTPException(
            status_code=404,
            detail=f"Playbook {playbook_id} not found",
        )

    return PlaybookResponse.from_playbook(playbook)


@router.patch("/{playbook_id}", response_model=PlaybookResponse)
async def update_playbook(
    playbook_id: str,
    request: PlaybookUpdateRequest,
) -> PlaybookResponse:
    """
    更新 Playbook (人工編輯)

    可更新名稱、描述、步驟、標籤等

    Phase 8 P1 修復: 委託給 Service 層進行驗證
    """
    service = get_playbook_service()

    # 委託給 Service 層進行驗證和更新
    update_data = request.model_dump(exclude_unset=True)
    updated = await service.update_with_validation(
        playbook_id=playbook_id,
        update_data=update_data,
    )

    if not updated:
        raise HTTPException(
            status_code=404,
            detail=f"Playbook {playbook_id} not found or update not allowed",
        )

    return PlaybookResponse.from_playbook(updated)


@router.delete("/{playbook_id}", response_model=DeletePlaybookResponse)
async def delete_playbook(playbook_id: str) -> DeletePlaybookResponse:
    """
    刪除 Playbook (軟刪除)

    將狀態改為 DEPRECATED，不真正刪除
    """
    service = get_playbook_service()
    success = await service.delete(playbook_id)

    if not success:
        raise HTTPException(
            status_code=404,
            detail=f"Playbook {playbook_id} not found",
        )

    return DeletePlaybookResponse(
        success=True,
        message=f"Playbook {playbook_id} deprecated successfully",
    )


@router.post("/{playbook_id}/record-execution")
async def record_execution(
    playbook_id: str,
    success: bool = Query(..., description="執行是否成功"),
) -> dict:
    """
    記錄 Playbook 執行結果

    用於更新成功率統計
    """
    service = get_playbook_service()
    result = await service.record_execution(playbook_id, success)

    if not result:
        raise HTTPException(
            status_code=404,
            detail=f"Playbook {playbook_id} not found",
        )

    return {"success": True, "message": "Execution recorded"}
