"""
api.v1.status — Agent runtime status and health dashboard API.

GET /api/v1/status                       Platform overview
GET /api/v1/status/agents                All agents status summary
GET /api/v1/status/agents/{id}           Single agent detailed status
GET /api/v1/status/agents/{id}/health    Agent health score
"""
from __future__ import annotations
import json
from fastapi import APIRouter, Depends, Query
from agentpaas.api.deps import get_tenant, get_database
from agentpaas.api.middleware.auth import TenantContext
from agentpaas.db.models import Database

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


@router.get("/recent-runs")
async def recent_runs(
    limit: int = Query(default=5, le=20),
    tenant: TenantContext = Depends(get_tenant),
    db: Database = Depends(get_database),
):
    """跨智能体的最近运行（工作台「继续上次的工作」数据源）。

    带智能体名与 workspace，输入截断到 120 字。运行中的排最前。
    """
    rows = db.fetchall(
        "SELECT r.id, r.agent_id, a.name AS agent_name, r.status, r.input, "
        "r.workspace_path, r.created_at, r.completed_at, r.duration_ms "
        "FROM runs r JOIN agents a ON a.id = r.agent_id "
        "WHERE r.tenant_id = ? AND a.status = 'active' "
        "ORDER BY (r.status = 'running') DESC, r.created_at DESC LIMIT ?",
        (tenant.tenant_id, limit),
    )
    items = []
    for r in rows:
        items.append({
            "run_id": r["id"],
            "agent_id": r["agent_id"],
            "agent_name": r["agent_name"],
            "status": r["status"],
            "input_preview": (r.get("input") or "")[:120],
            "workspace_path": r.get("workspace_path") or "",
            "created_at": r.get("created_at"),
            "completed_at": r.get("completed_at"),
        })
    return {"items": items}


@router.get("")
async def platform_status(
    tenant: TenantContext = Depends(get_tenant),
    db: Database = Depends(get_database),
):
    """Platform-wide status: total agents, runs, success rate, avg latency."""
    t = tenant.tenant_id
    agents = db.fetchone("SELECT COUNT(*) as cnt FROM agents WHERE tenant_id=? AND status='active'", (t,))
    runs = db.fetchone(
        "SELECT COUNT(*) as total, "
        "SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as completed, "
        "SUM(CASE WHEN status='failed' THEN 1 ELSE 0 END) as failed, "
        "SUM(CASE WHEN status='running' THEN 1 ELSE 0 END) as running, "
        "COALESCE(AVG(duration_ms), 0) as avg_duration_ms, "
        "COALESCE(SUM(input_tokens + output_tokens), 0) as total_tokens "
        "FROM runs WHERE tenant_id=?", (t,))
    total = runs["total"] or 0
    completed = runs["completed"] or 0
    return {
        "tenant_id": t,
        "agents_active": agents["cnt"],
        "runs_total": total,
        "runs_completed": completed,
        "runs_failed": runs["failed"] or 0,
        "runs_running": runs["running"] or 0,
        "success_rate": "{:.1%}".format(completed / total) if total else "N/A",
        "avg_latency_ms": int(runs["avg_duration_ms"]),
        "total_tokens": runs["total_tokens"] or 0,
    }


@router.get("/agents")
async def all_agents_status(
    sort: str = Query("last_run", description="Sort by: last_run, runs, errors, latency"),
    tenant: TenantContext = Depends(get_tenant),
    db: Database = Depends(get_database),
):
    """All agents with runtime stats: runs, success rate, avg latency, last run time."""
    t = tenant.tenant_id
    agents = db.fetchall("SELECT id, name, description, current_version, status, created_at FROM agents WHERE tenant_id=? AND status='active'", (t,))

    result = []
    for a in agents:
        stats = db.fetchone(
            "SELECT COUNT(*) as total, "
            "SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as ok, "
            "SUM(CASE WHEN status='failed' THEN 1 ELSE 0 END) as fail, "
            "COALESCE(AVG(CASE WHEN status='completed' THEN duration_ms END), 0) as avg_ms, "
            "COALESCE(MAX(CASE WHEN status='completed' THEN duration_ms END), 0) as p99_ms, "
            "MAX(created_at) as last_run, "
            "COALESCE(SUM(input_tokens + output_tokens), 0) as tokens "
            "FROM runs WHERE agent_id=?", (a["id"],))
        total = stats["total"] or 0
        ok = stats["ok"] or 0
        fail = stats["fail"] or 0
        health = _compute_health(ok, fail, stats["avg_ms"])
        result.append({
            "agent_id": a["id"],
            "name": a["name"],
            "version": a["current_version"],
            "health": health,
            "runs_total": total,
            "runs_ok": ok,
            "runs_failed": fail,
            "success_rate": "{:.1%}".format(ok / total) if total else "N/A",
            "avg_latency_ms": int(stats["avg_ms"]),
            "p99_latency_ms": int(stats["p99_ms"]),
            "total_tokens": stats["tokens"] or 0,
            "last_run": stats["last_run"],
        })

    # Sort
    sort_keys = {
        "last_run": lambda x: x["last_run"] or "",
        "runs": lambda x: x["runs_total"],
        "errors": lambda x: x["runs_failed"],
        "latency": lambda x: x["avg_latency_ms"],
    }
    result.sort(key=sort_keys.get(sort, sort_keys["last_run"]), reverse=True)

    return {"agents": result, "count": len(result)}


@router.get("/agents/{agent_id}")
async def agent_detail_status(
    agent_id: str,
    limit: int = Query(20, description="Recent runs to include"),
    tenant: TenantContext = Depends(get_tenant),
    db: Database = Depends(get_database),
):
    """Detailed agent status: stats + recent runs + error breakdown."""
    t = tenant.tenant_id
    agent = db.fetchone("SELECT * FROM agents WHERE id=? AND tenant_id=? AND status='active'", (agent_id, t))
    if not agent:
        from fastapi import HTTPException
        raise HTTPException(404, {"error": {"code": "AGENT_NOT_FOUND"}})

    # Aggregate stats
    stats = db.fetchone(
        "SELECT COUNT(*) as total, "
        "SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as ok, "
        "SUM(CASE WHEN status='failed' THEN 1 ELSE 0 END) as fail, "
        "COALESCE(AVG(CASE WHEN status='completed' THEN duration_ms END), 0) as avg_ms, "
        "COALESCE(MIN(CASE WHEN status='completed' THEN duration_ms END), 0) as min_ms, "
        "COALESCE(MAX(CASE WHEN status='completed' THEN duration_ms END), 0) as max_ms, "
        "COALESCE(AVG(steps), 0) as avg_steps, "
        "COALESCE(SUM(input_tokens), 0) as input_tokens, "
        "COALESCE(SUM(output_tokens), 0) as output_tokens "
        "FROM runs WHERE agent_id=?", (agent_id,))

    # Recent runs
    recent = db.fetchall(
        "SELECT id, status, duration_ms, steps, input_tokens, output_tokens, "
        "SUBSTR(input, 1, 100) as input_preview, "
        "SUBSTR(output, 1, 100) as output_preview, "
        "error, created_at, completed_at "
        "FROM runs WHERE agent_id=? ORDER BY created_at DESC LIMIT ?",
        (agent_id, limit))

    # Error breakdown
    errors = db.fetchall(
        "SELECT error, COUNT(*) as cnt FROM runs WHERE agent_id=? AND status='failed' AND error IS NOT NULL "
        "GROUP BY error ORDER BY cnt DESC LIMIT 5", (agent_id,))

    total = stats["total"] or 0
    ok = stats["ok"] or 0
    fail = stats["fail"] or 0

    return {
        "agent_id": agent_id,
        "name": agent["name"],
        "version": agent["current_version"],
        "health": _compute_health(ok, fail, stats["avg_ms"]),
        "stats": {
            "total_runs": total,
            "completed": ok,
            "failed": fail,
            "success_rate": "{:.1%}".format(ok / total) if total else "N/A",
            "latency": {
                "avg_ms": int(stats["avg_ms"]),
                "min_ms": int(stats["min_ms"]),
                "max_ms": int(stats["max_ms"]),
            },
            "avg_steps": round(stats["avg_steps"], 1),
            "tokens": {
                "input": stats["input_tokens"] or 0,
                "output": stats["output_tokens"] or 0,
                "total": (stats["input_tokens"] or 0) + (stats["output_tokens"] or 0),
            },
        },
        "recent_runs": recent,
        "top_errors": errors,
    }


@router.get("/agents/{agent_id}/health")
async def agent_health(
    agent_id: str,
    tenant: TenantContext = Depends(get_tenant),
    db: Database = Depends(get_database),
):
    """Agent health score (0-100) based on success rate and latency."""
    stats = db.fetchone(
        "SELECT "
        "SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as ok, "
        "SUM(CASE WHEN status='failed' THEN 1 ELSE 0 END) as fail, "
        "COALESCE(AVG(CASE WHEN status='completed' THEN duration_ms END), 0) as avg_ms "
        "FROM runs WHERE agent_id=? AND tenant_id=?",
        (agent_id, tenant.tenant_id))
    ok = stats["ok"] or 0
    fail = stats["fail"] or 0
    health = _compute_health(ok, fail, stats["avg_ms"])
    return {
        "agent_id": agent_id,
        "health_score": health["score"],
        "health_level": health["level"],
        "factors": health["factors"],
    }


def _compute_health(ok: int, fail: int, avg_ms: float) -> dict:
    """
    Health = 0.7 * success_rate_score + 0.3 * latency_score
    success_rate_score: 100 if >=99%, 80 if >=95%, 60 if >=90%, 40 if >=80%, 20 else
    latency_score: 100 if <1s, 80 if <3s, 60 if <10s, 40 if <30s, 20 else
    """
    total = ok + fail
    if total == 0:
        return {"score": -1, "level": "no_data", "factors": {"reason": "No runs yet"}}

    sr = ok / total
    if sr >= 0.99: sr_score = 100
    elif sr >= 0.95: sr_score = 80
    elif sr >= 0.90: sr_score = 60
    elif sr >= 0.80: sr_score = 40
    else: sr_score = 20

    if avg_ms < 1000: lat_score = 100
    elif avg_ms < 3000: lat_score = 80
    elif avg_ms < 10000: lat_score = 60
    elif avg_ms < 30000: lat_score = 40
    else: lat_score = 20

    score = int(0.7 * sr_score + 0.3 * lat_score)

    if score >= 90: level = "healthy"
    elif score >= 70: level = "degraded"
    elif score >= 50: level = "warning"
    else: level = "critical"

    return {
        "score": score,
        "level": level,
        "factors": {
            "success_rate": "{:.1%}".format(sr),
            "success_score": sr_score,
            "avg_latency_ms": int(avg_ms),
            "latency_score": lat_score,
            "total_runs": total,
        },
    }
