"""
Sofiia Supervisor — Pydantic models for HTTP API
"""

from __future__ import annotations

import datetime
from enum import Enum
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field


class RunStatus(str, Enum):
    QUEUED = "queued"
    RUNNING = "running"
    SUCCEEDED = "succeeded"
    FAILED = "failed"
    CANCELLED = "cancelled"


class EventType(str, Enum):
    NODE_START = "node_start"
    NODE_END = "node_end"
    TOOL_CALL = "tool_call"
    TOOL_RESULT = "tool_result"
    ERROR = "error"


# ─── Run event (stored without payload for privacy) ──────────────────────────

class RunEvent(BaseModel):
    ts: str = Field(description="ISO timestamp")
    type: EventType
    node: Optional[str] = None
    tool: Optional[str] = None
    # payload is intentionally NOT stored — only correlation/size info
    details: Dict[str, Any] = Field(default_factory=dict)


# ─── Run metadata stored in Redis ────────────────────────────────────────────

class RunRecord(BaseModel):
    run_id: str
    graph: str
    status: RunStatus = RunStatus.QUEUED
    agent_id: str
    workspace_id: str
    user_id: str
    started_at: Optional[str] = None
    finished_at: Optional[str] = None
    result: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    events: List[RunEvent] = Field(default_factory=list)


# ─── HTTP Request/Response models ────────────────────────────────────────────

class StartRunRequest(BaseModel):
    workspace_id: str = Field(default="daarion")
    user_id: str = Field(default="system")
    agent_id: str = Field(default="sofiia")
    input: Dict[str, Any] = Field(default_factory=dict)


class StartRunResponse(BaseModel):
    run_id: str
    status: RunStatus
    result: Optional[Dict[str, Any]] = None


class GetRunResponse(BaseModel):
    run_id: str
    graph: str
    status: RunStatus
    started_at: Optional[str] = None
    finished_at: Optional[str] = None
    result: Optional[Dict[str, Any]] = None
    events: List[RunEvent] = Field(default_factory=list)


class CancelRunResponse(BaseModel):
    run_id: str
    status: RunStatus
    message: str


# ─── Graph input schemas ──────────────────────────────────────────────────────

class ReleaseCheckInput(BaseModel):
    diff_text: Optional[str] = None
    service_name: Optional[str] = None
    openapi_base: Optional[Dict[str, str]] = None
    openapi_head: Optional[Dict[str, str]] = None
    risk_profile: str = "default"
    fail_fast: bool = True
    run_smoke: bool = False
    run_drift: bool = True
    run_deps: bool = True
    deps_targets: List[str] = Field(default_factory=lambda: ["python", "node"])
    deps_vuln_mode: str = "offline_cache"
    deps_fail_on: List[str] = Field(default_factory=lambda: ["CRITICAL", "HIGH"])
    drift_categories: List[str] = Field(
        default_factory=lambda: ["services", "openapi", "nats", "tools"]
    )
    timeouts: Dict[str, float] = Field(
        default_factory=lambda: {"overall_sec": 180, "per_gate_sec": 60}
    )


class IncidentTriageInput(BaseModel):
    service: str
    symptom: str
    time_range: Optional[Dict[str, str]] = None   # {"from": ISO, "to": ISO}
    env: str = "prod"
    include_traces: bool = False
    max_log_lines: int = 120
    log_query_hint: Optional[str] = None
