"""统一配音响应 Schema — Phase 3 CosyVoice 集成.

支持预置音色和克隆音色的统一响应格式。
"""

from __future__ import annotations

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

from pydantic import BaseModel, Field


class UnifiedVoiceItemResponse(BaseModel):
    """统一配音项响应。

    同时支持预置音色（type=preset）和克隆音色（type=clone）。
    """

    id: str
    """音色 ID（预置音色为 voice_id，克隆音色为数据库 ID）"""

    type: Literal["preset", "clone"]
    """音色类型：preset=预置音色，clone=用户克隆音色"""

    name: str
    """音色展示名称"""

    description: str = ""
    """音色描述"""

    gender: str = "unknown"
    """性别：male/female/unknown"""

    language: str = "zh-CN"
    """语言代码"""

    voice_id: str = ""
    """CosyVoice 模型音色名"""

    voice_provider: str = "cosyvoice"
    """语音服务商"""

    audio_url: str = ""
    """音频 URL（克隆音色为上传的音频，预置音色为空）"""

    preview_url: str = ""
    """预览音频 URL（预置音色可能有）"""

    duration: float = 0
    """音频时长（秒）"""

    file_size: int = 0
    """文件大小（字节）"""

    status: str = "completed"
    """状态"""

    tags: List[str] = Field(default_factory=list)
    """标签列表"""

    # 克隆音色特有字段
    user_id: Optional[str] = None
    """所属用户 ID（仅克隆音色）"""

    project_id: Optional[str] = None
    """所属项目 ID（仅克隆音色）"""

    voice_clone_profile_id: Optional[str] = None
    """关联的音色克隆档案 ID（仅克隆音色）"""

    created_at: Optional[datetime] = None
    """创建时间（仅克隆音色）"""

    updated_at: Optional[datetime] = None
    """更新时间（仅克隆音色）"""


class UnifiedVoiceListResponse(BaseModel):
    """统一配音列表响应。"""

    items: list[UnifiedVoiceItemResponse]
    """音色列表（预置音色在前）"""

    total: int = 0
    """总数"""

    preset_count: int = 0
    """预置音色数量"""

    clone_count: int = 0
    """克隆音色数量"""


class PresetVoiceItemResponse(BaseModel):
    """预置音色项响应。"""

    voice_id: str
    """CosyVoice 模型音色名"""

    name: str
    """中文展示名"""

    description: str
    """音色描述"""

    gender: str
    """性别"""

    language: str = "zh-CN"
    """语言代码"""

    preview_url: str = ""
    """预览音频 URL"""

    tags: List[str] = Field(default_factory=list)
    """标签列表"""


class PresetVoiceListResponse(BaseModel):
    """预置音色列表响应。"""

    items: list[PresetVoiceItemResponse]
    """预置音色列表"""

    total: int = 0
    """总数"""
