"""
数据模型定义
"""
from typing import List, Optional
from pydantic import BaseModel, Field, validator
from enum import Enum


class UploadStatus(str, Enum):
    """上传状态枚举"""
    PENDING = "pending"
    UPLOADING = "uploading"
    COMPLETED = "completed"
    FAILED = "failed"
    EXPIRED = "expired"


class FileCheckRequest(BaseModel):
    """文件检查请求模型"""
    file_id: str = Field(..., description="文件唯一标识符")
    file_name: str = Field(..., description="原始文件名")
    file_size: int = Field(..., gt=0, description="文件总大小(字节)")
    file_md5: Optional[str] = Field(None, description="文件MD5值")
    total_chunks: int = Field(..., gt=0, description="分片总数")
    dataset_id: str = Field(..., description="数据集ID")
    
    @validator('file_id')
    def validate_file_id(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('文件ID不能为空')
        return v.strip()


class ChunkUploadRequest(BaseModel):
    """分片上传请求模型"""
    file_id: str = Field(..., description="文件唯一标识符")
    file_name: str = Field(..., description="原始文件名")
    file_size: int = Field(..., gt=0, description="文件总大小(字节)")
    file_md5: Optional[str] = Field(None, description="文件MD5值")
    chunk_index: int = Field(..., ge=0, description="当前分片序号(从0开始)")
    total_chunks: int = Field(..., gt=0, description="分片总数")
    chunk_size: int = Field(..., gt=0, description="当前分片大小(字节)")
    chunk_md5: Optional[str] = Field(None, description="当前分片MD5值")
    dataset_id: str = Field(..., description="数据集ID")
    
    @validator('chunk_index')
    def validate_chunk_index(cls, v, values):
        if 'total_chunks' in values and v >= values['total_chunks']:
            raise ValueError('分片序号不能大于等于分片总数')
        return v


class FileUploadResponse(BaseModel):
    """文件上传响应模型"""
    code: int = Field(..., description="响应状态码")
    message: str = Field(..., description="响应消息")
    file_id: Optional[str] = Field(None, description="文件唯一标识符")
    file_name: Optional[str] = Field(None, description="文件名")
    file_url: Optional[str] = Field(None, description="文件访问URL")
    uploaded_chunks: Optional[List[int]] = Field(None, description="已上传的分片列表")
    is_completed: Optional[bool] = Field(None, description="是否上传完成")
    file_size: Optional[int] = Field(None, description="文件大小")
    progress: Optional[float] = Field(None, description="上传进度(百分比)")
    
    @classmethod
    def success(cls, message: str = "操作成功", **kwargs):
        """创建成功响应"""
        return cls(code=200, message=message, **kwargs)
    
    @classmethod
    def error(cls, message: str = "操作失败", code: int = 500, **kwargs):
        """创建错误响应"""
        return cls(code=code, message=message, **kwargs)


class FileMergeRequest(BaseModel):
    """文件合并请求模型"""
    file_id: str = Field(..., description="文件唯一标识符")
    file_name: str = Field(..., description="原始文件名")
    total_chunks: int = Field(..., gt=0, description="分片总数")
    file_md5: Optional[str] = Field(None, description="文件MD5值用于校验")
    dataset_id: str = Field(..., description="数据集ID")


class FileInfo(BaseModel):
    """文件信息模型"""
    file_id: str
    file_name: str
    file_size: int
    file_md5: Optional[str] = None
    total_chunks: int
    uploaded_chunks: List[int] = []
    status: UploadStatus = UploadStatus.PENDING
    created_at: str
    updated_at: str
    file_path: Optional[str] = None
    dataset_id: str
    
    @property
    def progress(self) -> float:
        """计算上传进度"""
        if self.total_chunks == 0:
            return 0.0
        return (len(self.uploaded_chunks) / self.total_chunks) * 100
    
    @property
    def is_completed(self) -> bool:
        """判断是否上传完成"""
        return len(self.uploaded_chunks) == self.total_chunks


class UploadRecordItem(BaseModel):
    """上传记录项"""
    id: int = Field(..., description="记录ID")
    user_id: str = Field(..., description="用户ID")
    user_name: str = Field(..., description="用户名")
    token_hash: Optional[str] = Field(None, description="Token Hash")
    file_id: str = Field(..., description="文件唯一标识符")
    file_name: str = Field(..., description="文件名")
    file_size: int = Field(..., description="文件大小(字节)")
    file_md5: Optional[str] = Field(None, description="文件MD5值")
    file_path: str = Field(..., description="文件存储路径")
    dataset_id: str = Field(..., description="数据集ID")
    total_chunks: int = Field(..., description="分片总数")
    upload_status: str = Field(..., description="上传状态")
    upload_started_at: Optional[str] = Field(None, description="上传开始时间")
    upload_completed_at: Optional[str] = Field(None, description="上传完成时间")
    created_at: Optional[str] = Field(None, description="记录创建时间")


class UploadRecordsResponse(BaseModel):
    """上传记录查询响应"""
    code: int = Field(..., description="响应状态码")
    message: str = Field(..., description="响应消息")
    total: int = Field(..., description="总记录数")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页大小")
    records: List[UploadRecordItem] = Field(..., description="上传记录列表")
    
    @classmethod
    def success(cls, records: List[UploadRecordItem], total: int, page: int, page_size: int, message: str = "查询成功"):
        """创建成功响应"""
        return cls(
            code=200,
            message=message,
            total=total,
            page=page,
            page_size=page_size,
            records=records
        )
    
    @classmethod
    def error(cls, message: str = "查询失败", code: int = 500):
        """创建错误响应"""
        return cls(
            code=code,
            message=message,
            total=0,
            page=1,
            page_size=10,
            records=[]
        )
