# -*- coding: utf-8 -*-
"""
管理端 — AI 监控后台 Pydantic Schema。

覆盖：Dashboard 总览、调度任务、调用记录、缓存失效、Token 预算、批量执行、告警管理。

需求: A1.1, A2.1, A4.1, A5.1, A6.1, A7.1, A8.1
"""

from __future__ import annotations

from pydantic import BaseModel


# ── Dashboard ─────────────────────────────────────────────


class DailyTrend(BaseModel):
    """近 7 天按日聚合趋势项。"""
    date: str                           # YYYY-MM-DD
    calls: int
    success_rate: float


class AppDistItem(BaseModel):
    """各 App 调用占比分布项。"""
    app_type: str
    count: int
    percentage: float


class BudgetInfo(BaseModel):
    """日/月 Token 预算进度。"""
    daily_used: int
    daily_limit: int
    daily_pct: float
    monthly_used: int
    monthly_limit: int
    monthly_pct: float


class AlertItem(BaseModel):
    """告警事件项（失败/超时/熔断）。"""
    id: int
    app_type: str
    status: str                         # failed / timeout / circuit_open
    alert_status: str | None            # pending / acknowledged / ignored
    error_message: str | None
    created_at: str


class AppHealthItem(BaseModel):
    """各 App 最近一次调用状态。"""
    app_type: str
    last_status: str | None
    last_call_at: str | None


class DashboardResponse(BaseModel):
    """Dashboard 总览统计响应。"""
    today_calls: int
    today_success_rate: float           # 0.0 ~ 1.0
    today_tokens: int
    today_avg_latency_ms: float
    trend_7d: list[DailyTrend]
    app_distribution: list[AppDistItem]
    budget: BudgetInfo
    recent_alerts: list[AlertItem]
    app_health: list[AppHealthItem]


# ── 调度任务 ──────────────────────────────────────────────


class TriggerJobItem(BaseModel):
    """调度任务列表项。"""
    id: int
    event_type: str
    member_id: int | None
    status: str
    app_chain: str | None
    is_forced: bool
    site_id: int
    started_at: str | None
    finished_at: str | None
    created_at: str


class TriggerJobListResponse(BaseModel):
    """调度任务分页列表响应。"""
    items: list[TriggerJobItem]
    total: int
    page: int
    page_size: int
    today_skipped_duplicates: int       # 今日去重跳过数


class TriggerJobDetailResponse(TriggerJobItem):
    """调度任务详情响应（含 payload、error_message）。"""
    payload: dict | None
    error_message: str | None
    connector_type: str


class RetryResponse(BaseModel):
    """手动重跑响应。"""
    trigger_job_id: int
    status: str                         # "pending"


# ── 调用记录 ──────────────────────────────────────────────


class RunLogItem(BaseModel):
    """调用记录列表项。"""
    id: int
    app_type: str
    trigger_type: str
    member_id: int | None
    tokens_used: int
    latency_ms: int | None
    status: str
    site_id: int
    created_at: str


class RunLogListResponse(BaseModel):
    """调用记录分页列表响应。"""
    items: list[RunLogItem]
    total: int
    page: int
    page_size: int


class RunLogDetailResponse(RunLogItem):
    """调用记录详情响应（含完整 prompt/response，不脱敏）。"""
    request_prompt: str | None
    response_text: str | None
    error_message: str | None
    session_id: str | None
    finished_at: str | None


# ── 缓存失效 ─────────────────────────────────────────────


class CacheInvalidateRequest(BaseModel):
    """缓存失效请求（site_id 必填）。"""
    site_id: int
    app_type: str | None = None
    member_id: int | None = None


class CacheInvalidateResponse(BaseModel):
    """缓存失效响应。"""
    affected_count: int


# ── Token 预算 ────────────────────────────────────────────


class BudgetResponse(BaseModel):
    """Token 预算使用情况响应。"""
    daily_used: int
    daily_limit: int
    daily_pct: float
    monthly_used: int
    monthly_limit: int
    monthly_pct: float


# ── 批量执行 ──────────────────────────────────────────────


class BatchRunRequest(BaseModel):
    """批量执行请求。"""
    app_types: list[str]
    member_ids: list[int]
    site_id: int


class BatchRunEstimate(BaseModel):
    """批量执行预估响应（不立即执行）。"""
    batch_id: str
    estimated_calls: int
    estimated_tokens: int


class BatchRunConfirm(BaseModel):
    """批量执行确认请求。"""
    batch_id: str


class BatchRunConfirmResponse(BaseModel):
    """批量执行确认响应。"""
    status: str                         # "started"


# ── 告警 ──────────────────────────────────────────────────


class AlertListResponse(BaseModel):
    """告警分页列表响应。"""
    items: list[AlertItem]
    total: int
    page: int
    page_size: int


class AlertActionResponse(BaseModel):
    """告警操作（确认/忽略）响应。"""
    id: int
    alert_status: str
