"""Compute layer 2 (trace summaries) from full traces."""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Any


def compute_layer2(trace: dict[str, Any]) -> dict[str, Any]:
    """Compute layer 2 summary from a trace.
    
    Minimal ~200 bytes per trace:
    - trace_id, project, started_at, ended_at
    - status, span_count, total_cost, latency
    - tags
    
    Does NOT include input/output previews.
    """
    trace_id = trace.get("trace_id", "")
    project = trace.get("project", "")
    started_at = trace.get("started_at")
    ended_at = trace.get("ended_at")
    status = trace.get("status", "ok")
    tags = trace.get("tags", [])
    
    spans = trace.get("spans", [])
    span_count = len(spans)
    
    total_cost = 0.0
    for span in spans:
        cost = span.get("cost")
        if cost is not None:
            total_cost += cost
    
    latency = None
    if started_at and ended_at:
        try:
            s = datetime.fromisoformat(started_at.replace("Z", "+00:00"))
            e = datetime.fromisoformat(ended_at.replace("Z", "+00:00"))
            latency = (e - s).total_seconds()
        except (ValueError, TypeError):
            pass
    
    return {
        "trace_id": trace_id,
        "project": project,
        "started_at": _parse_datetime(started_at),
        "ended_at": _parse_datetime(ended_at),
        "status": status,
        "span_count": span_count,
        "total_cost": total_cost if total_cost > 0 else None,
        "latency": latency,
        "tags": tags if tags else None,
    }


def _parse_datetime(value: str | None) -> datetime | None:
    """Parse datetime string to timezone-naive UTC datetime."""
    if not value:
        return None
    try:
        dt = datetime.fromisoformat(value.replace("Z", "+00:00"))
        return dt.replace(tzinfo=None)
    except (ValueError, TypeError):
        return None


def compute_layer2_from_trace_model(trace: Any) -> dict[str, Any]:
    """Compute layer 2 summary from a Trace model object."""
    started_at = trace.started_at
    ended_at = trace.ended_at
    
    latency = None
    if started_at and ended_at:
        if started_at.tzinfo:
            started_at = started_at.replace(tzinfo=None)
        if ended_at.tzinfo:
            ended_at = ended_at.replace(tzinfo=None)
        latency = (ended_at - started_at).total_seconds()
    
    spans = trace.spans or []
    span_count = len(spans)
    
    total_cost = 0.0
    for span in spans:
        cost = getattr(span, "cost", None)
        if cost is not None:
            total_cost += cost
    
    tags = getattr(trace, "tags", None) or []
    
    return {
        "trace_id": trace.trace_id,
        "project": trace.project,
        "started_at": started_at,
        "ended_at": ended_at,
        "status": getattr(trace, "status", "ok") or "ok",
        "span_count": span_count,
        "total_cost": total_cost if total_cost > 0 else None,
        "latency": latency,
        "tags": tags if tags else None,
    }
