from pydantic import BaseModel, Field, validator
from typing import Optional, List
from datetime import datetime
import re

class FileUploadRequest(BaseModel):
    """文件上传请求"""
    description: Optional[str] = Field(None, max_length=500, description="文件描述")
    tags: Optional[str] = Field(None, max_length=200, description="文件标签，用逗号分隔")
    is_public: bool = Field(False, description="是否公开分享")

    @validator('tags')
    def validate_tags(cls, v):
        if v:
            # 验证标签格式，只允许字母、数字、中文、下划线、中划线
            tags = v.split(',')
            for tag in tags:
                tag = tag.strip()
                if not re.match(r'^[\w\u4e00-\u9fa5-]+$', tag):
                    raise ValueError(f"标签 '{tag}' 格式不正确，只允许字母、数字、中文、下划线、中划线")
                if len(tag) > 20:
                    raise ValueError(f"标签 '{tag}' 长度不能超过20个字符")
        return v

class FileResponse(BaseModel):
    """文件响应"""
    id: int
    user_id: int
    filename: str
    original_filename: str
    file_size: int
    mime_type: str
    file_hash: str
    is_public: bool
    download_count: int
    description: Optional[str] = None
    tags: Optional[str] = None
    created_at: datetime
    updated_at: datetime
    last_accessed_at: Optional[datetime] = None

    class Config:
        from_attributes = True

class FileListResponse(BaseModel):
    """文件列表响应"""
    files: List[FileResponse]
    total: int
    page: int
    size: int
    pages: int

    class Config:
        from_attributes = True

class FileListRequest(BaseModel):
    """文件列表请求"""
    user_id: int = Field(..., description="用户ID")
    page: int = Field(1, ge=1, description="页码")
    size: int = Field(20, ge=1, le=100, description="每页数量")

class FileIdRequest(BaseModel):
    """文件ID请求"""
    user_id: int = Field(..., description="用户ID")
    file_id: int = Field(..., description="文件ID")

class StorageInfoRequest(BaseModel):
    """存储信息请求"""
    user_id: int = Field(..., description="用户ID")

class FileUpdateRequest(BaseModel):
    """文件更新请求"""
    description: Optional[str] = Field(None, max_length=500, description="文件描述")
    tags: Optional[str] = Field(None, max_length=200, description="文件标签，用逗号分隔")
    is_public: Optional[bool] = Field(None, description="是否公开分享")

    @validator('tags')
    def validate_tags(cls, v):
        if v:
            tags = v.split(',')
            for tag in tags:
                tag = tag.strip()
                if not re.match(r'^[\w\u4e00-\u9fa5-]+$', tag):
                    raise ValueError(f"标签 '{tag}' 格式不正确，只允许字母、数字、中文、下划线、中划线")
                if len(tag) > 20:
                    raise ValueError(f"标签 '{tag}' 长度不能超过20个字符")
        return v

class FileSearchRequest(BaseModel):
    """文件搜索请求"""
    filename: Optional[str] = Field(None, description="文件名搜索")
    tags: Optional[str] = Field(None, description="标签搜索，用逗号分隔")
    mime_type: Optional[str] = Field(None, description="MIME类型过滤")
    is_public: Optional[bool] = Field(None, description="是否公开文件")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    end_date: Optional[datetime] = Field(None, description="结束日期")
    min_size: Optional[int] = Field(None, ge=0, description="最小文件大小（字节）")
    max_size: Optional[int] = Field(None, ge=0, description="最大文件大小（字节）")

class FileInfo(BaseModel):
    """文件信息"""
    id: int
    filename: str
    original_filename: str
    file_size: int
    mime_type: str
    file_hash: str
    is_image: bool
    is_document: bool
    file_extension: str
    size_formatted: str
    is_public: bool = False
    download_count: int = 0
    description: Optional[str] = None
    tags: Optional[str] = None
    created_at: datetime
    updated_at: datetime
    last_accessed_at: Optional[datetime] = None

    class Config:
        from_attributes = True

class UploadResponse(BaseModel):
    """文件上传响应"""
    file_info: FileResponse
    message: str
    success: bool

class DeleteResponse(BaseModel):
    """删除文件响应"""
    message: str
    success: bool

class StorageInfo(BaseModel):
    """存储信息"""
    total_quota: int
    used_space: int
    available_space: int
    usage_percentage: float
    file_count: int

# 通用API响应格式
class ApiResponse(BaseModel):
    """API响应"""
    success: bool
    message: str
    data: Optional[dict] = None
    code: Optional[str] = None