"""Type definitions for the Contiss SDK using Pydantic models."""

from datetime import datetime
from typing import Any, Dict, List, Literal, Optional

from pydantic import BaseModel, Field, field_validator


# Memory Types
MemoryType = Literal["fact", "decision", "plan", "summary", "note"]
SearchMode = Literal["semantic", "fulltext", "hybrid"]


class Memory(BaseModel):
    """Represents a memory in the Contiss system."""

    id: str = Field(..., description="Unique identifier for the memory")
    project_id: str = Field(..., description="Project this memory belongs to")
    type: MemoryType = Field(..., description="Type of memory")
    title: Optional[str] = Field(None, description="Optional title for the memory")
    content: str = Field(..., description="The actual memory content")
    tags: List[str] = Field(default_factory=list, description="Tags for categorization")
    sources: List[str] = Field(default_factory=list, description="Source UUIDs")
    confidence: float = Field(..., description="Confidence score (0.0 to 1.0)")
    requires_review: bool = Field(..., description="Whether memory needs review")
    root_id: Optional[str] = Field(None, description="Root ID for version tracking")
    version: int = Field(..., description="Version number")
    is_current: bool = Field(..., description="Whether this is the current version")
    created_by: Optional[str] = Field(None, description="User who created the memory")
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: datetime = Field(..., description="Last update timestamp")
    similarity: Optional[float] = Field(
        None, description="Similarity score from search (0.0 to 1.0)"
    )

    @field_validator("confidence")
    @classmethod
    def validate_confidence(cls, v: float) -> float:
        """Validate confidence is between 0 and 1."""
        if not 0.0 <= v <= 1.0:
            raise ValueError("confidence must be between 0.0 and 1.0")
        return v


class MemoryWriteResult(BaseModel):
    """Result from writing a memory."""

    id: str = Field(..., description="ID of the created memory")
    root_id: Optional[str] = Field(None, description="Root ID for versioning")
    version: int = Field(..., description="Version number")
    is_current: bool = Field(..., description="Whether this is the current version")
    requires_review: bool = Field(..., description="Whether memory needs review")
    type: MemoryType = Field(..., description="Type of memory")


class SearchResult(BaseModel):
    """Result from searching memories."""

    items: List[Memory] = Field(..., description="List of matching memories")


class BundleResult(BaseModel):
    """Result from getting a memory bundle."""

    project_id: str = Field(..., description="Project ID")
    task: str = Field(..., description="Task description")
    summary: str = Field(..., description="Summary of the bundle")
    items: List[Memory] = Field(..., description="Memories in the bundle")
    total_items: int = Field(..., description="Total number of items")
    total_chars: int = Field(..., description="Total character count")
    truncated: bool = Field(..., description="Whether bundle was truncated")


# Auth Types


class User(BaseModel):
    """Represents a user in the system."""

    id: str = Field(..., description="User ID")
    email: str = Field(..., description="User email")
    name: Optional[str] = Field(None, description="User display name")
    org_id: str = Field(..., description="Organization ID")


class AuthResponse(BaseModel):
    """Response from authentication operations."""

    token: str = Field(..., description="JWT authentication token")
    user: User = Field(..., description="User information")


class APIKey(BaseModel):
    """Represents an API key."""

    id: str = Field(..., description="API key ID")
    name: str = Field(..., description="Name/description of the key")
    key_prefix: str = Field(..., description="First few characters of the key")
    last_used_at: Optional[datetime] = Field(None, description="Last usage timestamp")
    expires_at: Optional[datetime] = Field(None, description="Expiration timestamp")
    created_at: datetime = Field(..., description="Creation timestamp")


class APIKeyCreate(BaseModel):
    """Result from creating an API key."""

    key: str = Field(..., description="The actual API key (only shown once)")
    id: str = Field(..., description="API key ID")
    name: str = Field(..., description="Name of the key")
    key_prefix: str = Field(..., description="Key prefix")
    created_at: datetime = Field(..., description="Creation timestamp")
    expires_at: Optional[datetime] = Field(None, description="Expiration timestamp")


class APIKeyList(BaseModel):
    """List of API keys."""

    keys: List[APIKey] = Field(..., description="List of API keys")


# Health Check


class HealthCheck(BaseModel):
    """Health check response."""

    ok: bool = Field(..., description="Whether the service is healthy")
    service: str = Field(..., description="Service name")


# Usage Statistics


class TokenUsage(BaseModel):
    """Token usage statistics."""

    prompt_tokens: int = Field(..., alias="promptTokens", description="Prompt tokens used")
    completion_tokens: int = Field(
        ..., alias="completionTokens", description="Completion tokens used"
    )
    total_tokens: int = Field(..., alias="totalTokens", description="Total tokens used")

    model_config = {"populate_by_name": True}
