"""Picture source schemas."""

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

from pydantic import BaseModel, Field


class PictureSourceCreate(BaseModel):
    """Request to create a picture source."""

    name: str = Field(description="Stream name", min_length=1, max_length=100)
    stream_type: Literal["raw", "processed", "static_image", "video"] = Field(description="Stream type")
    display_index: Optional[int] = Field(None, description="Display index (raw streams)", ge=0)
    capture_template_id: Optional[str] = Field(None, description="Capture template ID (raw streams)")
    target_fps: Optional[int] = Field(None, description="Target FPS", ge=1, le=90)
    source_stream_id: Optional[str] = Field(None, description="Source stream ID (processed streams)")
    postprocessing_template_id: Optional[str] = Field(None, description="Postprocessing template ID (processed streams)")
    image_asset_id: Optional[str] = Field(None, description="Image asset ID (static_image streams)")
    description: Optional[str] = Field(None, description="Stream description", max_length=500)
    tags: List[str] = Field(default_factory=list, description="User-defined tags")
    # Video fields
    video_asset_id: Optional[str] = Field(None, description="Video asset ID (video streams)")
    loop: bool = Field(True, description="Loop video playback")
    playback_speed: float = Field(1.0, description="Playback speed multiplier", ge=0.1, le=10.0)
    start_time: Optional[float] = Field(None, description="Trim start time in seconds", ge=0)
    end_time: Optional[float] = Field(None, description="Trim end time in seconds", ge=0)
    resolution_limit: Optional[int] = Field(None, description="Max width in pixels for decode downscale", ge=64, le=7680)
    clock_id: Optional[str] = Field(None, description="Sync clock ID for frame-accurate timing")


class PictureSourceUpdate(BaseModel):
    """Request to update a picture source."""

    name: Optional[str] = Field(None, description="Stream name", min_length=1, max_length=100)
    display_index: Optional[int] = Field(None, description="Display index (raw streams)", ge=0)
    capture_template_id: Optional[str] = Field(None, description="Capture template ID (raw streams)")
    target_fps: Optional[int] = Field(None, description="Target FPS", ge=1, le=90)
    source_stream_id: Optional[str] = Field(None, description="Source stream ID (processed streams)")
    postprocessing_template_id: Optional[str] = Field(None, description="Postprocessing template ID (processed streams)")
    image_asset_id: Optional[str] = Field(None, description="Image asset ID (static_image streams)")
    description: Optional[str] = Field(None, description="Stream description", max_length=500)
    tags: Optional[List[str]] = None
    # Video fields
    video_asset_id: Optional[str] = Field(None, description="Video asset ID (video streams)")
    loop: Optional[bool] = Field(None, description="Loop video playback")
    playback_speed: Optional[float] = Field(None, description="Playback speed multiplier", ge=0.1, le=10.0)
    start_time: Optional[float] = Field(None, description="Trim start time in seconds", ge=0)
    end_time: Optional[float] = Field(None, description="Trim end time in seconds", ge=0)
    resolution_limit: Optional[int] = Field(None, description="Max width in pixels for decode downscale", ge=64, le=7680)
    clock_id: Optional[str] = Field(None, description="Sync clock ID for frame-accurate timing")


class PictureSourceResponse(BaseModel):
    """Picture source information response."""

    id: str = Field(description="Stream ID")
    name: str = Field(description="Stream name")
    stream_type: str = Field(description="Stream type (raw, processed, static_image, or video)")
    display_index: Optional[int] = Field(None, description="Display index")
    capture_template_id: Optional[str] = Field(None, description="Capture template ID")
    target_fps: Optional[int] = Field(None, description="Target FPS")
    source_stream_id: Optional[str] = Field(None, description="Source stream ID")
    postprocessing_template_id: Optional[str] = Field(None, description="Postprocessing template ID")
    image_asset_id: Optional[str] = Field(None, description="Image asset ID")
    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")
    description: Optional[str] = Field(None, description="Stream description")
    # Video fields
    video_asset_id: Optional[str] = Field(None, description="Video asset ID")
    loop: Optional[bool] = Field(None, description="Loop video playback")
    playback_speed: Optional[float] = Field(None, description="Playback speed multiplier")
    start_time: Optional[float] = Field(None, description="Trim start time in seconds")
    end_time: Optional[float] = Field(None, description="Trim end time in seconds")
    resolution_limit: Optional[int] = Field(None, description="Max width for decode")
    clock_id: Optional[str] = Field(None, description="Sync clock ID")


class PictureSourceListResponse(BaseModel):
    """List of picture sources response."""

    streams: List[PictureSourceResponse] = Field(description="List of picture sources")
    count: int = Field(description="Number of streams")


class PictureSourceTestRequest(BaseModel):
    """Request to test a picture source."""

    capture_duration: float = Field(default=5.0, ge=0.0, le=30.0, description="Duration to capture in seconds (0 = single frame)")
    border_width: int = Field(default=10, ge=1, le=100, description="Border width in pixels for preview")


class ImageValidateRequest(BaseModel):
    """Request to validate an image source (URL or file path)."""

    image_source: str = Field(description="Image URL or local file path")


class ImageValidateResponse(BaseModel):
    """Response from image validation."""

    valid: bool = Field(description="Whether the image source is accessible and valid")
    width: Optional[int] = Field(None, description="Image width in pixels")
    height: Optional[int] = Field(None, description="Image height in pixels")
    preview: Optional[str] = Field(None, description="Base64-encoded JPEG thumbnail")
    error: Optional[str] = Field(None, description="Error message if invalid")
