"""JSON API endpoints for the monitoring dashboard."""

from __future__ import annotations

from datetime import datetime
from typing import Any

from fastapi import APIRouter, Query, Request

router = APIRouter(tags=["api"])


def _parse_ts(val: str | None) -> datetime | None:
    if not val:
        return None
    try:
        return datetime.fromisoformat(val)
    except ValueError:
        return None


# ── Traces ────────────────────────────────────────────────────


@router.get("/traces")
async def list_traces(
    request: Request,
    page: int = Query(1, ge=1),
    per_page: int = Query(50, ge=1, le=200),
    status: str | None = None,
    service_name: str | None = None,
    environment: str | None = None,
    search: str | None = None,
    model: str | None = None,
    agent_name: str | None = None,
    sort: str = "created_at",
    order: str = "desc",
    from_ts: str | None = Query(None, alias="from"),
    to_ts: str | None = Query(None, alias="to"),
) -> dict[str, Any]:
    """List traces with filtering and pagination."""
    repo = request.app.state.repo
    traces, total = await repo.list_traces(
        page=page,
        per_page=per_page,
        status=status,
        service_name=service_name,
        environment=environment,
        from_ts=_parse_ts(from_ts),
        to_ts=_parse_ts(to_ts),
        search=search,
        model=model,
        agent_name=agent_name,
        sort=sort,
        order=order,
    )
    return {
        "traces": traces,
        "total": total,
        "page": page,
        "per_page": per_page,
        "pages": (total + per_page - 1) // per_page if per_page else 1,
    }


@router.get("/traces/{trace_id}")
async def get_trace(request: Request, trace_id: str) -> dict[str, Any]:
    """Get a single trace with all its spans."""
    repo = request.app.state.repo
    trace = await repo.get_trace(trace_id)
    spans = await repo.get_spans_for_trace(trace_id) if trace else []
    return {"trace": trace, "spans": spans}


@router.get("/traces/{trace_id}/chain")
async def get_trace_chain(request: Request, trace_id: str) -> dict[str, Any]:
    """Get the full span chain/tree for a trace."""
    repo = request.app.state.repo
    chain = await repo.get_trace_chain(trace_id)
    return {"trace_id": trace_id, "chain": chain}


# ── Spans ─────────────────────────────────────────────────────


@router.get("/spans/{span_id}")
async def get_span(request: Request, span_id: str) -> dict[str, Any]:
    """Get a single span with its detail data."""
    repo = request.app.state.repo
    span = await repo.get_span(span_id)
    if not span:
        return {"span": None}

    detail: dict[str, Any] = {}
    if span["span_type"] == "llm":
        detail = await repo.get_llm_detail(span_id) or {}
    elif span["span_type"] == "agent":
        detail = await repo.get_agent_detail(span_id) or {}

    tools = await repo.get_tool_details(span_id)
    return {"span": span, "detail": detail, "tool_calls": tools}


# ── Analytics ─────────────────────────────────────────────────


@router.get("/analytics/overview")
async def analytics_overview(
    request: Request,
    service_name: str | None = None,
    from_ts: str | None = Query(None, alias="from"),
    to_ts: str | None = Query(None, alias="to"),
) -> dict[str, Any]:
    """High-level overview stats."""
    repo = request.app.state.repo
    stats = await repo.get_overview_stats(
        from_ts=_parse_ts(from_ts),
        to_ts=_parse_ts(to_ts),
        service_name=service_name,
    )
    return {"stats": stats}


@router.get("/analytics/usage/daily")
async def daily_usage(
    request: Request,
    days: int = Query(30, ge=1, le=365),
) -> dict[str, Any]:
    """Daily usage data for charts."""
    repo = request.app.state.repo
    data = await repo.get_daily_usage(days=days)
    # Convert dates to ISO strings for JSON serialization
    for row in data:
        if row.get("day"):
            row["day"] = row["day"].isoformat()
    return {"daily": data, "days": days}


@router.get("/analytics/usage/trend")
async def usage_trend(
    request: Request,
    group_by: str = "hour",
    component_type: str | None = None,
    component_class: str | None = None,
    model: str | None = None,
    service_name: str | None = None,
    from_ts: str | None = Query(None, alias="from"),
    to_ts: str | None = Query(None, alias="to"),
) -> dict[str, Any]:
    """Usage trend over time."""
    repo = request.app.state.repo
    data = await repo.get_usage_trend(
        group_by=group_by,
        component_type=component_type,
        component_class=component_class,
        model=model,
        from_ts=_parse_ts(from_ts),
        to_ts=_parse_ts(to_ts),
        service_name=service_name,
    )
    return {"trend": data, "group_by": group_by}


@router.get("/analytics/models")
async def model_breakdown(
    request: Request,
    service_name: str | None = None,
    from_ts: str | None = Query(None, alias="from"),
    to_ts: str | None = Query(None, alias="to"),
) -> dict[str, Any]:
    """Per-model usage breakdown."""
    repo = request.app.state.repo
    data = await repo.get_model_breakdown(
        from_ts=_parse_ts(from_ts),
        to_ts=_parse_ts(to_ts),
        service_name=service_name,
    )
    return {"models": data}


@router.get("/analytics/agents")
async def agent_breakdown(
    request: Request,
    group_by: str = "class",
    service_name: str | None = None,
    from_ts: str | None = Query(None, alias="from"),
    to_ts: str | None = Query(None, alias="to"),
) -> dict[str, Any]:
    """Per-agent usage breakdown."""
    repo = request.app.state.repo
    data = await repo.get_agent_breakdown(
        from_ts=_parse_ts(from_ts),
        to_ts=_parse_ts(to_ts),
        group_by=group_by,
        service_name=service_name,
    )
    return {"agents": data, "group_by": group_by}
