"""
AwoooP Operator Console — Runs List & Approval API
====================================================
  GET  /runs/list     — 列出 runs（可 filter）
  GET  /approvals     — 列出待審核 runs（state=waiting_approval）
  POST /approvals/{run_id}/decide — 核准或拒絕 run
ADR-106（AwoooP Agent Platform），ADR-114（Run State Machine），ADR-116（Gate 5 Approval）
2026-05-05 ogt + Claude Sonnet 4.6
"""

from __future__ import annotations

from datetime import datetime
from decimal import Decimal
from typing import Any, Literal
from uuid import UUID

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

from src.services.platform_operator_service import (
    decide_approval as decide_approval_svc,
    list_approvals as list_approvals_svc,
    list_runs as list_runs_svc,
)

router = APIRouter()

_DEFAULT_PER_PAGE = 50
_MAX_PER_PAGE = 200


class RunItem(BaseModel):
    run_id: UUID
    project_id: str
    agent_id: str
    state: str
    is_shadow: bool
    cost_usd: Decimal
    step_count: int
    created_at: datetime
    timeout_at: datetime | None


class ListRunsResponse(BaseModel):
    runs: list[RunItem]
    total: int
    page: int
    per_page: int


class ApprovalItem(BaseModel):
    run_id: UUID
    project_id: str
    agent_id: str
    created_at: datetime
    timeout_at: datetime | None


class ListApprovalsResponse(BaseModel):
    items: list[ApprovalItem]
    total: int


class DecideApprovalRequest(BaseModel):
    project_id: str = Field(..., description="租戶 ID")
    decision: Literal["approve", "reject"] = Field(..., description="核准或拒絕")
    approver_id: str = Field(..., description="審核人 ID（platform_subject_id 或 operator email）")
    reason: str | None = Field(None, description="決策原因（可選）")


class DecideApprovalResponse(BaseModel):
    run_id: str
    decision: str
    new_state: str
    approval_token_jti: str | None


@router.get(
    "/runs/list",
    response_model=ListRunsResponse,
    summary="列出 Runs",
    description=(
        "返回 awooop_run_state 記錄，支援 project_id / state filter 與分頁。\n\n"
        "- 按 created_at DESC 排序\n"
        "- 注意：此路徑為 /runs/list 以避免與 runs.py 的 /runs/{run_id} 衝突"
    ),
)
async def list_runs(
    project_id: str | None = Query(None, description="租戶 ID（可選）"),
    state: str | None = Query(None, description="Run 狀態 filter（可選）"),
    page: int = Query(1, ge=1, description="頁碼，從 1 開始"),
    per_page: int = Query(_DEFAULT_PER_PAGE, ge=1, le=_MAX_PER_PAGE, description="每頁筆數"),
) -> dict[str, Any]:
    return await list_runs_svc(
        project_id=project_id, state=state, page=page, per_page=per_page
    )


@router.get(
    "/approvals",
    response_model=ListApprovalsResponse,
    summary="列出待審核 Runs",
    description=(
        "返回 state=waiting_approval 的 runs，即需要人工審核的任務清單。\n\n"
        "ADR-116 Gate 5：人工審核關卡"
    ),
)
async def list_approvals(
    project_id: str | None = Query(None, description="租戶 ID（可選）"),
    run_id: str | None = Query(None, description="Run ID（可選，M8 詳情頁查單筆）"),
) -> dict[str, Any]:
    return await list_approvals_svc(project_id=project_id, run_id=run_id)


@router.post(
    "/approvals/{run_id}/decide",
    response_model=DecideApprovalResponse,
    summary="核准或拒絕 Run",
    description=(
        "對 waiting_approval 狀態的 run 做出審核決定。\n\n"
        "- approve：發行 approval token → record_approval → run 轉為 running\n"
        "- reject：直接 transition → cancelled\n\n"
        "ADR-116 Gate 5：Operator Console 人工審核"
    ),
)
async def decide_approval(
    run_id: str,
    body: DecideApprovalRequest,
) -> dict[str, Any]:
    return await decide_approval_svc(
        run_id=run_id,
        project_id=body.project_id,
        decision=body.decision,
        approver_id=body.approver_id,
        reason=body.reason,
    )
