from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Callable, Generic, TypeVar

T = TypeVar("T")


# --- Agents ---

@dataclass
class Agent:
    id: str
    name: str
    provider: str
    config: dict[str, Any]
    created_at: str
    description: str | None = None
    is_active: bool | None = None
    updated_at: str | None = None
    agent_category: str | None = None
    org_id: str | None = None


@dataclass
class CreateAgentParams:
    name: str
    provider: str
    config: dict[str, Any]
    description: str | None = None
    is_active: bool | None = None


@dataclass
class UpdateAgentParams:
    name: str | None = None
    description: str | None = None
    config: dict[str, Any] | None = None
    is_active: bool | None = None


@dataclass
class ValidationResult:
    valid: bool
    message: str
    details: Any | None = None


# --- Tests ---

@dataclass
class CreateTestParams:
    agent_id: str
    name: str | None = None
    scenario_ids: list[str] | None = None
    max_turns: int | None = None
    max_scenarios: int | None = None
    test_mode: str | None = None  # "demo" | "full"


@dataclass
class TestRunCreated:
    id: str
    test_id: str
    status: str
    total_scenarios: int


@dataclass
class TestRun:
    id: str
    test_id: str
    status: str  # pending | running | grading | completed | failed | canceled
    agent_id: str
    pass_rate: float
    passed_count: int
    failed_count: int
    error_count: int
    total_scenarios: int
    name: str | None = None
    agent_name: str | None = None
    started_at: str | None = None
    completed_at: str | None = None
    duration_seconds: float | None = None
    created_at: str | None = None


# --- Scenario Results ---

@dataclass
class ScenarioResult:
    id: str
    scenario_id: str
    status: str
    created_at: str
    scenario_name: str | None = None
    passed: bool | None = None
    grade_summary: str | None = None
    duration_ms: int | None = None
    error_code: str | None = None
    error_message: str | None = None
    completed_at: str | None = None


@dataclass
class ScenarioRun:
    id: str
    scenario_id: str
    test_id: str
    status: str
    created_at: str
    scenario_name: str | None = None
    passed: bool | None = None
    grade_summary: str | None = None
    criteria_results: list[dict[str, Any]] = field(default_factory=list)
    duration_ms: int | None = None
    error_code: str | None = None
    error_message: str | None = None
    completed_at: str | None = None
    transcript: list[dict[str, Any]] = field(default_factory=list)
    metadata: dict[str, Any] | None = None


# --- Scenarios ---

@dataclass
class Scenario:
    id: str
    name: str
    category: str | None = None
    severity: str | None = None
    test_type: str | None = None
    content_summary: str | None = None
    content: Any | None = None
    rubric: Any | None = None
    persona: Any | None = None
    created_at: str | None = None
    updated_at: str | None = None


# --- Webhooks ---

@dataclass
class Webhook:
    id: str
    url: str
    is_enabled: bool
    created_at: str
    description: str | None = None
    agent_id: str | None = None
    last_triggered_at: str | None = None
    consecutive_failures: int | None = None
    updated_at: str | None = None


@dataclass
class CreateWebhookParams:
    url: str
    description: str | None = None
    agent_id: str | None = None
    secret: str | None = None
    is_enabled: bool | None = None


@dataclass
class UpdateWebhookParams:
    url: str | None = None
    description: str | None = None
    secret: str | None = None
    is_enabled: bool | None = None


@dataclass
class WebhookTestResult:
    success: bool
    message: str
    http_status: int | None = None


@dataclass
class WebhookDelivery:
    id: str
    status: str
    created_at: str
    http_status: int | None = None
    attempt_count: int | None = None
    completed_at: str | None = None


# --- Generic ---

@dataclass
class PaginatedResponse(Generic[T]):
    data: list[T]
    total: int
    limit: int
    offset: int


@dataclass
class ListParams:
    limit: int | None = None
    offset: int | None = None
    status: str | None = None


@dataclass
class PollOptions:
    interval_seconds: float = 10.0
    timeout_seconds: float = 1800.0
    on_progress: Callable[[TestRun], None] | None = None
