"""Audio source schemas — discriminated unions per source type."""

from datetime import datetime
from typing import Annotated, List, Literal, Optional, Union

from pydantic import BaseModel, Discriminator, Field, Tag

# =====================================================================
# Response schemas (per-type, discriminated union)
# =====================================================================


class _AudioSourceResponseBase(BaseModel):
    """Shared fields for all audio source responses."""

    id: str = Field(description="Source ID")
    name: str = Field(description="Source name")
    description: Optional[str] = Field(None, description="Description")
    tags: List[str] = Field(default_factory=list, description="User-defined tags")
    created_at: datetime = Field(description="Creation timestamp")
    updated_at: datetime = Field(description="Last update timestamp")


class CaptureAudioSourceResponse(_AudioSourceResponseBase):
    source_type: Literal["capture"] = "capture"
    device_index: int = Field(description="Audio device index (-1 = default)")
    is_loopback: bool = Field(description="WASAPI loopback mode")
    audio_template_id: Optional[str] = Field(None, description="Audio capture template ID")


class ProcessedAudioSourceResponse(_AudioSourceResponseBase):
    source_type: Literal["processed"] = "processed"
    audio_source_id: str = Field(description="Input audio source ID")
    audio_processing_template_id: str = Field(description="Audio processing template ID")


AudioSourceResponse = Annotated[
    Union[
        Annotated[CaptureAudioSourceResponse, Tag("capture")],
        Annotated[ProcessedAudioSourceResponse, Tag("processed")],
    ],
    Discriminator("source_type"),
]

# =====================================================================
# Create schemas (per-type, discriminated union)
# =====================================================================


class _AudioSourceCreateBase(BaseModel):
    """Shared fields for all audio source create requests."""

    name: str = Field(description="Source name", min_length=1, max_length=100)
    description: Optional[str] = Field(None, description="Optional description", max_length=500)
    tags: List[str] = Field(default_factory=list, description="User-defined tags")


class CaptureAudioSourceCreate(_AudioSourceCreateBase):
    source_type: Literal["capture"] = "capture"
    device_index: int = Field(-1, description="Audio device index (-1 = default)")
    is_loopback: bool = Field(True, description="True for system audio (WASAPI loopback)")
    audio_template_id: Optional[str] = Field(None, description="Audio capture template ID")


class ProcessedAudioSourceCreate(_AudioSourceCreateBase):
    source_type: Literal["processed"] = "processed"
    audio_source_id: str = Field(description="Input audio source ID")
    audio_processing_template_id: str = Field(description="Audio processing template ID")


AudioSourceCreate = Annotated[
    Union[
        Annotated[CaptureAudioSourceCreate, Tag("capture")],
        Annotated[ProcessedAudioSourceCreate, Tag("processed")],
    ],
    Discriminator("source_type"),
]

# =====================================================================
# Update schemas (per-type, discriminated union)
# =====================================================================


class _AudioSourceUpdateBase(BaseModel):
    """Shared fields for all audio source update requests."""

    name: Optional[str] = Field(None, description="Source name", min_length=1, max_length=100)
    description: Optional[str] = Field(None, description="Optional description", max_length=500)
    tags: Optional[List[str]] = None


class CaptureAudioSourceUpdate(_AudioSourceUpdateBase):
    source_type: Literal["capture"] = "capture"
    device_index: Optional[int] = Field(None, description="Audio device index (-1 = default)")
    is_loopback: Optional[bool] = Field(None, description="True for system audio (WASAPI loopback)")
    audio_template_id: Optional[str] = Field(None, description="Audio capture template ID")


class ProcessedAudioSourceUpdate(_AudioSourceUpdateBase):
    source_type: Literal["processed"] = "processed"
    audio_source_id: Optional[str] = Field(None, description="Input audio source ID")
    audio_processing_template_id: Optional[str] = Field(
        None, description="Audio processing template ID"
    )


AudioSourceUpdate = Annotated[
    Union[
        Annotated[CaptureAudioSourceUpdate, Tag("capture")],
        Annotated[ProcessedAudioSourceUpdate, Tag("processed")],
    ],
    Discriminator("source_type"),
]

# =====================================================================
# List response
# =====================================================================


class AudioSourceListResponse(BaseModel):
    """List of audio sources."""

    sources: List[AudioSourceResponse] = Field(description="List of audio sources")
    count: int = Field(description="Number of sources")
