"""
DecodeVideo 模型

对应数据库表 decode_videos 的 ORM 模型
"""

from enum import IntEnum
from typing import Optional
from sqlalchemy import Column, String, BigInteger, Integer, Text, DateTime
from sqlalchemy.sql import func

from src.models.database import Base
from src.utils.logger import get_logger

logger = get_logger(__name__)


class DecodeStatus(IntEnum):
    """解码状态枚举
    
    对应数据库字段 status 的值：
    - PENDING: 0 - 待执行
    - EXECUTING: 1 - 执行中
    - SUCCESS: 2 - 执行成功
    - FAILED: 3 - 执行失败
    """
    PENDING = 0
    EXECUTING = 1
    SUCCESS = 2
    FAILED = 3
    
    @classmethod
    def get_description(cls, status: int) -> str:
        """获取状态描述
        
        Args:
            status: 状态值
            
        Returns:
            str: 状态描述
        """
        descriptions = {
            cls.PENDING: "待执行",
            cls.EXECUTING: "执行中",
            cls.SUCCESS: "执行成功",
            cls.FAILED: "执行失败",
        }
        return descriptions.get(status, "未知状态")


class DecodeVideo(Base):
    """解码视频模型
    
    对应数据库表: decode_videos
    
    字段说明:
    - video_id: 视频ID (varchar(100), nullable)
    - task_id: 任务ID (bigint, not null)
    - result: 解码结果 (mediumtext, nullable)
    - status: 状态 (int, nullable) - 0:待执行 / 1:执行中 / 2:执行成功 / 3:执行失败
    - error_reason: 失败原因 (mediumtext, nullable)
    """
    
    __tablename__ = "decode_videos"
    
    # 主键：使用 task_id 作为主键（根据业务需求，可能需要调整）
    task_id = Column(BigInteger, primary_key=True, nullable=False, comment="任务ID")
    
    # 视频ID
    video_id = Column(String(100), nullable=True, index=True, comment="视频ID")
    
    # 解码结果（JSON 格式）
    result = Column(Text, nullable=True, comment="解码结果")
    
    # 状态
    status = Column(Integer, nullable=True, default=DecodeStatus.PENDING, index=True, comment="状态: 0:待执行 / 1:执行中 / 2:执行成功 / 3:执行失败")
    
    # 失败原因
    error_reason = Column(Text, nullable=True, comment="失败原因")
    
    # 时间戳字段（可选，用于记录创建和更新时间）
    created_at = Column(DateTime, nullable=True, server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime, nullable=True, server_default=func.now(), onupdate=func.now(), comment="更新时间")
    
    def __repr__(self) -> str:
        """对象字符串表示"""
        return f"<DecodeVideo(task_id={self.task_id}, video_id={self.video_id}, status={self.status})>"
    
    def to_dict(self) -> dict:
        """转换为字典
        
        Returns:
            dict: 模型数据字典
        """
        return {
            "task_id": self.task_id,
            "video_id": self.video_id,
            "result": self.result,
            "status": self.status,
            "status_description": DecodeStatus.get_description(self.status) if self.status is not None else None,
            "error_reason": self.error_reason,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
        }
    
    @classmethod
    def create(
        cls,
        task_id: int,
        video_id: Optional[str] = None,
        status: Optional[int] = None,
        result: Optional[str] = None,
        error_reason: Optional[str] = None
    ) -> "DecodeVideo":
        """创建新的解码视频记录
        
        Args:
            task_id: 任务ID
            video_id: 视频ID
            status: 状态（默认: PENDING）
            result: 解码结果
            error_reason: 失败原因
            
        Returns:
            DecodeVideo: 新创建的模型实例
        """
        return cls(
            task_id=task_id,
            video_id=video_id,
            status=status if status is not None else DecodeStatus.PENDING,
            result=result,
            error_reason=error_reason
        )
    
    def update_status(self, status: DecodeStatus, error_reason: Optional[str] = None):
        """更新状态
        
        Args:
            status: 新状态
            error_reason: 失败原因（仅在失败时使用）
        """
        self.status = status.value
        if status == DecodeStatus.FAILED and error_reason:
            self.error_reason = error_reason
        elif status != DecodeStatus.FAILED:
            self.error_reason = None
    
    def update_result(self, result: str):
        """更新解码结果
        
        Args:
            result: 解码结果（JSON 字符串）
        """
        self.result = result
        if self.status == DecodeStatus.EXECUTING:
            self.update_status(DecodeStatus.SUCCESS)

