"""
ZIA API — Request/Response Pydantic models.

Keeps route handlers clean and provides clear API contracts.
"""

from __future__ import annotations

from datetime import datetime, timezone
from enum import Enum
from typing import Any

from pydantic import BaseModel, Field


# ---------------------------------------------------------------------------
# Shared
# ---------------------------------------------------------------------------

class RunStatus(str, Enum):
    QUEUED = "queued"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"


# ---------------------------------------------------------------------------
# Tenant models
# ---------------------------------------------------------------------------

class TenantCreateRequest(BaseModel):
    tenant_id: str = Field(..., pattern=r"^[a-z0-9\-_]+$", description="Unique tenant slug")
    name: str = Field(..., description="Human-readable tenant name")
    metadata: dict[str, Any] = Field(default_factory=dict)


class TenantResponse(BaseModel):
    tenant_id: str
    name: str
    metadata: dict[str, Any]
    created_at: datetime


# ---------------------------------------------------------------------------
# Run models
# ---------------------------------------------------------------------------

class RunCreateRequest(BaseModel):
    domain: str = Field(..., description="Agent domain to run (e.g. 'risk_quant')")
    environment: str = Field(default="staging", description="Target environment")
    agent_config: dict[str, Any] = Field(
        default_factory=dict,
        description="Optional overrides passed to the agent at runtime",
    )


class RunRecord(BaseModel):
    run_id: str
    tenant_id: str
    domain: str
    environment: str
    status: RunStatus = RunStatus.QUEUED
    output: dict[str, Any] | None = None
    errors: list[str] = Field(default_factory=list)
    started_at: datetime | None = None
    completed_at: datetime | None = None
    duration_ms: float | None = None

    @property
    def is_terminal(self) -> bool:
        return self.status in (RunStatus.COMPLETED, RunStatus.FAILED)


class RunListResponse(BaseModel):
    tenant_id: str
    runs: list[RunRecord]
    total: int


# ---------------------------------------------------------------------------
# Telemetry models
# ---------------------------------------------------------------------------

class TelemetryEventRequest(BaseModel):
    event_type: str = Field(
        ...,
        description="Event type: vulnerability_found | asset_discovered | control_updated | vendor_assessed",
    )
    payload: dict[str, Any] = Field(
        ...,
        description="Event-specific fields (merged with event_type for ingestor)",
    )


class TelemetryEventResponse(BaseModel):
    accepted: bool
    event_type: str
    tenant_id: str
    ingested_at: datetime


# ---------------------------------------------------------------------------
# Graph read models
# ---------------------------------------------------------------------------

class NodeListResponse(BaseModel):
    tenant_id: str
    node_type: str
    nodes: list[dict[str, Any]]
    total: int


# ---------------------------------------------------------------------------
# Agent models
# ---------------------------------------------------------------------------

class AgentInfo(BaseModel):
    domain: str
    class_name: str
    version: str
    description: str
    module: str


class AgentListResponse(BaseModel):
    agents: list[AgentInfo]
    total: int


# ---------------------------------------------------------------------------
# Health model
# ---------------------------------------------------------------------------

class HealthResponse(BaseModel):
    status: str = "ok"
    version: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
