from typing import List, Optional, Literal
from pydantic import BaseModel, Field, model_validator

from common.models.common import Platform

WebcamType = Literal["square", "rectangle", "rounded", "circle"]
LayoutType = Literal["top", "middle", "bottom"]

TikTokPrivacySettings = Literal[
    "PUBLIC_TO_EVERYONE",
    "MUTUAL_FOLLOW_FRIENDS",
    "SELF_ONLY",
]


class TikTokSettings(BaseModel):
    # id nullable => first time setup (DAO creates row, then sets FK)
    id: Optional[int] = Field(default=None, ge=1)

    comment: bool = False
    duet: bool = False
    stitch: bool = False

    promotional_content: bool = False
    promoting_yourself: bool = False
    paid_partnership: bool = False

    privacy_settings: TikTokPrivacySettings = "SELF_ONLY"


class StreamSignalPublishPlatform(BaseModel):
    platform: Platform
    is_reel: bool = False
    is_story: bool = False

    @model_validator(mode="after")
    def _at_least_one_target(self):
        if not (self.is_reel or self.is_story):
            raise ValueError(
                f"Can't save the plaform {self.platform.value} without reel or story setup"
            )
        return self


class StreamSignalUpsert(BaseModel):
    is_active: bool = False
    webcam: WebcamType
    layout: LayoutType
    tagline: Optional[str] = None
    add_live_badge: bool = False

    camera_position_top: Optional[float] = None
    camera_position_left: Optional[float] = None
    camera_position_width: Optional[float] = None
    camera_position_height: Optional[float] = None

    live_platforms: List[Platform] = Field(default_factory=list)
    publish_platforms: List[StreamSignalPublishPlatform] = Field(..., min_length=1)

    # Optional; can be None. If present, id can be None (first time setup).
    tiktok_settings: Optional[TikTokSettings] = None


class StreamSignalConfig(BaseModel):
    user_id: Optional[int] = Field(..., ge=1)
    template_id: Optional[str] = Field(None, description="Creatomate template id")

    is_active: bool
    webcam: Optional[WebcamType] = None
    layout: Optional[LayoutType] = None
    tagline: Optional[str] = None
    add_live_badge: bool

    camera_position_top: Optional[float] = None
    camera_position_left: Optional[float] = None
    camera_position_width: Optional[float] = None
    camera_position_height: Optional[float] = None

    live_platforms: List[Platform] = Field(default_factory=list)
    publish_platforms: List[StreamSignalPublishPlatform] = Field(default_factory=list)

    # Returned as None if FK is null.
    tiktok_settings: Optional[TikTokSettings] = None
