from sqlalchemy import Column, Integer, String, BigInteger, DateTime, ForeignKey, Boolean, Text
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.core.database import Base

class File(Base):
    __tablename__ = "files"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)

    # 文件基本信息
    filename = Column(String(255), nullable=False, index=True)
    original_filename = Column(String(255), nullable=False)  # 用户上传时的原始文件名
    file_path = Column(String(500), nullable=False)  # 服务器上的存储路径
    file_size = Column(BigInteger, nullable=False)  # 文件大小（字节）
    mime_type = Column(String(100), nullable=False)  # 文件MIME类型
    file_hash = Column(String(64), nullable=False, index=True)  # SHA-256哈希，用于去重和完整性检查

    # 文件状态
    is_public = Column(Boolean, default=False)  # 是否公开分享
    download_count = Column(BigInteger, default=0)  # 下载次数

    # 文件元数据
    description = Column(Text, nullable=True)  # 文件描述
    tags = Column(Text, nullable=True)  # 标签，用逗号分隔

    # 时间戳
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
    last_accessed_at = Column(DateTime(timezone=True), nullable=True)

    # 关联关系
    user = relationship("User", back_populates="files")

    def __repr__(self):
        return f"<File(id={self.id}, filename='{self.filename}', user_id={self.user_id})>"

    def to_dict(self):
        return {
            "id": self.id,
            "user_id": self.user_id,
            "filename": self.filename,
            "original_filename": self.original_filename,
            "file_size": self.file_size,
            "mime_type": self.mime_type,
            "file_hash": self.file_hash,
            "is_public": self.is_public,
            "download_count": self.download_count,
            "description": self.description,
            "tags": self.tags,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
            "last_accessed_at": self.last_accessed_at.isoformat() if self.last_accessed_at else None,
        }

    def get_file_extension(self) -> str:
        """获取文件扩展名"""
        return self.filename.split('.')[-1].lower() if '.' in self.filename else ''

    def is_image(self) -> bool:
        """判断是否为图片文件"""
        return self.mime_type.startswith('image/')

    def is_document(self) -> bool:
        """判断是否为文档文件"""
        document_types = [
            'application/pdf',
            'application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'application/vnd.ms-excel',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'application/vnd.ms-powerpoint',
            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            'text/plain',
            'text/csv'
        ]
        return self.mime_type in document_types

    def get_size_formatted(self) -> str:
        """获取格式化的文件大小"""
        for unit in ['B', 'KB', 'MB', 'GB']:
            if self.file_size < 1024.0:
                return f"{self.file_size:.1f} {unit}"
            self.file_size /= 1024.0
        return f"{self.file_size:.1f} TB"