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

from pydantic import BaseModel, Field, ConfigDict, HttpUrl, computed_field, RootModel

from ..cache_tasks.models import MediaSource, CacheTaskResult, ProductTimeline
from ..enums.models import TaskStatus
from ..ffmpeg_tasks.models import FFMPEGResult


class DownloadResult(BaseModel):
    urls: List[str] = Field(description="下载链接")


class CacheResultResponse(BaseModel):
    caches: Dict[str, MediaSource] = Field(description="Cache ID")


class UploadResultResponse(BaseModel):
    media: MediaSource = Field(description="上传完成的媒体资源")


class UploadPresignResponse(BaseModel):
    url: str = Field(description="就近加速的PUT上传地址")
    urn: str = Field(description="上传成功后获得的对应资源URN")
    expired_at: datetime = Field(description="上传地址签名过期时间戳")


class UploadMultipartPresignResponse(BaseModel):
    urls: List[str] = Field(description="就近加速的PUT分片上传地址")
    list_url: str = Field(description="用于确认分片上传状态的请求地址")
    complete_url: str = Field(description="用于确认完成分片上传的请求地址")
    urn: str = Field(description="上传成功后获得的对应资源URN")
    expired_at: datetime = Field(description="上传地址签名过期时间戳")


class ModalTaskResponse(BaseModel):
    success: bool = Field(description="任务接受成功")
    taskId: str = Field(description="任务Id")


class CacheDeleteTaskResponse(BaseModel):
    success: bool = Field(description="运行成功")
    keys: List[str] = Field(description="成功从KV和S3删除掉的URN")
    non_kv_keys: List[str] = Field(alias="nonKVKeys", serialization_alias="nonKVKeys",
                                   description="成功从S3删除的URN, 不存在于KV中")
    not_found_keys: List[str] = Field(alias="notFoundKeys", serialization_alias="notFoundKeys",
                                      description="不存在的URN")


class RecordingTaskResponse(BaseModel):
    success: bool = Field(description="任务接受成功")
    taskId: str = Field(description="任务Id")
    manifest: str = Field(description="播放地址")
    manifest_urn: str = Field(description="播放列表URN")


class ClusterCacheBatchResponse(BaseModel):
    results: List[CacheTaskResult] = Field(description="批量操作任务结果")


class BaseFFMPEGTaskStatusResponse(BaseModel):
    taskId: str = Field(description="任务Id")
    status: TaskStatus = Field(description="任务运行状态")
    error: Optional[str] = Field(description="任务错误原因", default=None)
    code: Optional[int] = Field(description="任务错误原因代码", default=None)
    task_type: str = Field(description="任务类型", default="unknown")
    results: Optional[List[Union[FFMPEGResult, Any]]] = Field(description="任务运行结果", default=None)

    model_config = ConfigDict(extra='ignore')


class FFMPEGConvertStreamResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="任务运行结果")


class FFMPEGSliceTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[List[str]] = Field(default=None, description="任务运行结果")


class FFMPEGConcatTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="任务运行结果")


class FFMPEGExtractAudioTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="任务运行结果")


class FFMPEGCornerMirrorTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="任务运行结果")


class FFMPEGBgmTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class FFMPEGZoomLoopTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class FFMPEGOverlayGifTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class FFMPEGSubtitleTaskStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class FFMPEGMixBgmWithNoiseReduceStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class FFMPEGVideoLoopFillAudioResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class FFMPEGExtractFrameStatusResponse(BaseFFMPEGTaskStatusResponse):
    result: Optional[str] = Field(default=None, description="生成结果的URN")


class ModalTaskCancelResponse(BaseModel):
    success: bool = Field(description="成功取消任务")
    error: Optional[str] = Field(default=None, description="失败原因")


class ComfyTaskStatusResponse(BaseModel):
    taskId: str = Field(description="任务Id")
    status: TaskStatus = Field(description="任务运行状态")
    error: Optional[str] = Field(description="任务错误原因", default=None)
    code: Optional[int] = Field(description="任务错误原因代码", default=None)
    result: Optional[str] = Field(description="任务运行结果", default=None)


class GeminiResultResponse(BaseFFMPEGTaskStatusResponse):
    result: str = Field(default="", description="推理出的json")


class LiveRoomProductCachesResponse(BaseModel):
    status: int = Field(default=None,
                        description="缓存状态/0-正常返回 1-直播已结束 2-IP风控 3-请求Tikhub API错误 4-内部错误")
    message: str = Field(default="", description="错误信息")
    cache_json: str = Field(default="", description="缓存内容/Json文本")


class GoogleUploadResponse(BaseModel):
    kind: str
    id: str
    self_link: HttpUrl = Field(alias='selfLink')
    media_link: HttpUrl = Field(alias='mediaLink')
    name: str
    bucket: str
    generation: str
    metageneration: str
    content_type: str = Field(alias='contentType')
    storage_class: str = Field(alias='storageClass')
    size: int
    md5_hash: str = Field(alias='md5Hash')
    crc32c: str
    etag: str
    time_created: datetime = Field(alias='timeCreated')
    updated: datetime
    time_storage_class_updated: datetime = Field(alias='timeStorageClassUpdated')
    time_finalized: datetime = Field(alias='timeFinalized')

    @computed_field(description="适用于Google内部服务的URN")
    @property
    def urn(self) -> str:
        return ("gs://" + self.id).replace(f"/{self.generation}", "")

    model_config = ConfigDict(populate_by_name=True)


class GeminiSecondStageResponseModel(RootModel):
    """
    表示一个包含多个商品及其时间线信息的列表。
    """
    root: List[ProductTimeline]


class NakamaJWTResponse(BaseModel):
    token: str = Field(description="Nakama JWT Token")
    refresh_token: str = Field(description="Nakama JWT Refresh Token")
