"""Request and response types for the Gibs API."""

from __future__ import annotations

from pydantic import BaseModel, Field


# --- Shared types ---


class SourceCitation(BaseModel):
    """A citation to a specific legal source."""

    article_id: str
    title: str
    text_excerpt: str
    relevance_score: float


class Obligation(BaseModel):
    """A compliance obligation derived from regulation."""

    id: str
    description: str
    source_article: str
    deadline: str | None = None


# --- Classify ---


class ClassifyRequest(BaseModel):
    """Request body for POST /v1/classify."""

    description: str
    data_types: list[str] | None = None
    decision_scope: str | None = None
    sector: str | None = None
    jurisdiction: str = "EU"


class ClassifyResponse(BaseModel):
    """Response from POST /v1/classify."""

    risk_level: str = Field(description="One of: prohibited, high, limited, minimal")
    confidence: float
    reasoning: str
    obligations: list[Obligation]
    sources: list[SourceCitation]
    request_id: str
    corpus_version: str
    processing_time_ms: int


# --- Check ---


class CheckRequest(BaseModel):
    """Request body for POST /v1/check."""

    question: str
    system_context: dict | None = None  # type: ignore[type-arg]
    regulation: str = "auto"
    response_format: str = "text"


class StructuredAnswer(BaseModel):
    """Parsed structured representation of a compliance answer."""

    summary: str
    legal_basis: str = ""
    requirements: list[str] = Field(default_factory=list)
    timeline: list[str] = Field(default_factory=list)
    articles_cited: list[str] = Field(default_factory=list)


class CheckResponse(BaseModel):
    """Response from POST /v1/check."""

    answer: str
    structured: StructuredAnswer | None = None
    confidence: str = Field(description="One of: high, medium, low")
    confidence_score: float = Field(description="Numeric confidence (0-1)")
    sources: list[SourceCitation]
    should_abstain: bool
    abstention_reason: str | None = None
    request_id: str
    corpus_version: str
    processing_time_ms: int


# --- Health ---


class HealthResponse(BaseModel):
    """Response from GET /v1/health."""

    status: str
    environment: str
    corpus_version: str
    components: dict  # type: ignore[type-arg]


# --- API Keys ---


class APIKey(BaseModel):
    """An API key summary (no secret)."""

    id: int
    name: str
    key_prefix: str
    is_test: bool
    created_at: str
    last_used_at: str | None = None
    request_count: int


class CreateKeyRequest(BaseModel):
    """Request body for POST /v1/account/keys."""

    name: str = "Default"


class CreateKeyResponse(BaseModel):
    """Response from POST /v1/account/keys. Contains the full API key (shown once)."""

    id: int
    api_key: str
    key_prefix: str
    name: str
    created_at: str


class DeleteKeyResponse(BaseModel):
    """Response from DELETE /v1/account/keys/{key_id}."""

    status: str


# --- Streaming ---


class StreamStatus(BaseModel):
    """Status event indicating pipeline stage change."""

    type: str = "status"
    data: dict  # type: ignore[type-arg]


class StreamChunk(BaseModel):
    """A text chunk from streaming synthesis."""

    type: str = "chunk"
    data: str


class StreamComplete(BaseModel):
    """Final metadata after streaming synthesis completes."""

    type: str = "complete"
    data: dict  # type: ignore[type-arg]


class StreamDone(BaseModel):
    """Request completion event with timing info."""

    type: str = "done"
    data: dict  # type: ignore[type-arg]


class StreamError(BaseModel):
    """Error event during streaming."""

    type: str = "error"
    data: str


StreamEvent = StreamStatus | StreamChunk | StreamComplete | StreamDone | StreamError
