"""
Agent Status SDK - Data models.
"""

from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional

from pydantic import BaseModel, ConfigDict, Field


class Verdict(str, Enum):
    """Agent health verdict."""

    UP = "UP"
    DEGRADED = "DEGRADED"
    DOWN = "DOWN"
    UNKNOWN = "UNKNOWN"


class AuthConfig(BaseModel):
    """Authentication configuration for an agent."""

    type: str = Field(..., description="Auth type: 'bearer', 'api_key', 'basic'")
    token: Optional[str] = Field(None, description="Bearer token")
    header: Optional[str] = Field(None, description="Header name for api_key auth")
    value: Optional[str] = Field(None, description="Header value for api_key auth")
    username: Optional[str] = Field(None, description="Username for basic auth")
    password: Optional[str] = Field(None, description="Password for basic auth")


class Agent(BaseModel):
    """A registered agent for continuous monitoring."""

    id: str = Field(..., description="Agent UUID")
    name: str = Field(..., description="Display name")
    endpoint_url: str = Field(..., description="Agent endpoint URL")
    status: str = Field("active", description="Agent status: active, paused, deleted")
    interval_minutes: int = Field(360, description="Probe interval in minutes")
    max_nodes_per_run: int = Field(5, description="Nodes per probe run")
    geos: Optional[List[str]] = Field(None, description="Geographic regions")
    eval_type: str = Field("basic", description="Evaluation type")
    gold_prompt_profile: str = Field("general", description="Gold prompt profile")
    timeout_ms: int = Field(30000, description="Request timeout")
    streaming: bool = Field(False, description="Streaming responses")
    inject_geo_context: bool = Field(False, description="Inject geo context")
    last_run_at: Optional[datetime] = Field(None, description="Last probe timestamp")
    next_run_at: Optional[datetime] = Field(None, description="Next scheduled probe")
    last_status: Optional[str] = Field(None, description="Last verdict")
    created_at: Optional[datetime] = Field(None, description="Creation timestamp")

    model_config = ConfigDict(extra="allow")


class AgentStatus(BaseModel):
    """Current status of a registered agent."""

    agent_id: str = Field(..., description="Agent UUID")
    verdict: Verdict = Field(..., description="Current health verdict")
    uptime_24h: Optional[float] = Field(None, description="24-hour uptime percentage")
    uptime_7d: Optional[float] = Field(None, description="7-day uptime percentage")
    latency_p50: Optional[int] = Field(None, description="P50 latency in ms")
    latency_p95: Optional[int] = Field(None, description="P95 latency in ms")
    pass_rate: Optional[float] = Field(None, description="Pass rate (0-1)")
    gold_pass_rate: Optional[float] = Field(None, description="Gold prompt pass rate")
    last_checked: Optional[datetime] = Field(None, description="Last probe timestamp")
    total_checks: int = Field(0, description="Total probes run")
    by_region: Optional[Dict[str, Any]] = Field(None, description="Per-region breakdown")

    model_config = ConfigDict(extra="allow")


class ProbeResult(BaseModel):
    """Individual probe result from a node."""

    node_id: Optional[str] = Field(None, description="Probing node ID")
    geo: Optional[str] = Field(None, description="Node geographic region")
    status: str = Field(..., description="HTTP status or error code")
    latency_ms: Optional[int] = Field(None, description="Response latency in ms")
    ttfb_ms: Optional[int] = Field(None, description="Time to first byte in ms")
    success: bool = Field(..., description="Whether probe succeeded")
    response_preview: Optional[str] = Field(None, description="First 500 chars of response")
    error: Optional[str] = Field(None, description="Error message if failed")
    gold_results: Optional[Dict[str, bool]] = Field(None, description="Gold prompt results")

    model_config = ConfigDict(extra="allow")


class RegionBreakdown(BaseModel):
    """Per-region aggregated results."""

    region: str = Field(..., description="Region code (us, eu, ap, etc.)")
    verdict: Verdict = Field(..., description="Region verdict")
    probe_count: int = Field(0, description="Number of probes")
    pass_rate: Optional[float] = Field(None, description="Pass rate")
    latency_p50: Optional[int] = Field(None, description="P50 latency")
    latency_p95: Optional[int] = Field(None, description="P95 latency")


class JudgeResult(BaseModel):
    """LLM-as-judge evaluation result."""

    verdict: str = Field(..., description="PASS, FAIL, or PARTIAL")
    score: float = Field(..., description="Score 0-100")
    reasoning: Optional[str] = Field(None, description="Judge reasoning")
    issues: Optional[List[str]] = Field(None, description="Identified issues")


class RunResult(BaseModel):
    """Result of a one-off validation run."""

    decision_id: str = Field(..., description="Run identifier")
    verdict: Verdict = Field(..., description="Overall verdict")
    latency_p50: Optional[int] = Field(None, description="P50 latency in ms")
    latency_p95: Optional[int] = Field(None, description="P95 latency in ms")
    latency_p99: Optional[int] = Field(None, description="P99 latency in ms")
    ttfb_p50: Optional[int] = Field(None, description="P50 TTFB in ms")
    ttfb_p95: Optional[int] = Field(None, description="P95 TTFB in ms")
    pass_rate: Optional[float] = Field(None, description="Pass rate (0-1)")
    gold_pass_rate: Optional[float] = Field(None, description="Gold prompt pass rate")
    total_probes: int = Field(0, description="Total probes sent")
    successful_probes: int = Field(0, description="Successful probes")
    failed_probes: int = Field(0, description="Failed probes")
    by_region: Optional[List[RegionBreakdown]] = Field(None, description="Per-region results")
    probe_results: Optional[List[ProbeResult]] = Field(None, description="Individual probe results")
    judge_result: Optional[JudgeResult] = Field(None, description="LLM judge result")
    tested_at: Optional[datetime] = Field(None, description="Test timestamp")

    model_config = ConfigDict(extra="allow")
