"""
基于数据库的Token管理器
"""
import hashlib
import secrets
from datetime import datetime, timedelta
from typing import Optional, List, Dict, Any
from sqlalchemy.orm import Session
from database import TokenRecord, get_database_session
from token_auth import TokenRequest, TokenResponse, AuthenticatedUser, UserRole


class DatabaseTokenManager:
    """数据库Token管理器"""
    
    def __init__(self):
        pass
    
    def generate_token(self, request: TokenRequest) -> TokenResponse:
        """生成访问令牌并存储到数据库（永不过期）"""
        db = get_database_session()
        try:
            # 生成随机令牌
            token = f"hf_{secrets.token_urlsafe(32)}"
            token_hash = hashlib.sha256(token.encode()).hexdigest()
            
            # 创建数据库记录
            db_token = TokenRecord(
                token_hash=token_hash,
                user_id=request.user_id,
                user_name=request.user_name,
                role=request.role.value,
                max_file_size=1024 * 1024 * 1024 * 1024,  # 强制1TB，不依赖客户端传值
                daily_upload_limit=request.daily_upload_limit,
                created_at=datetime.utcnow()
            )
            
            # 保存到数据库
            db.add(db_token)
            db.commit()
            db.refresh(db_token)
            
            # 返回响应
            return TokenResponse(
                access_token=token,
                user_info={
                    "user_id": request.user_id,
                    "user_name": request.user_name,
                    "role": request.role.value,
                    "max_file_size": request.max_file_size,
                    "daily_upload_limit": request.daily_upload_limit
                }
            )
            
        finally:
            db.close()
    
    def verify_token(self, token: str) -> Optional[AuthenticatedUser]:
        """验证Token并返回用户信息（永不过期）"""
        if not token or not token.startswith("hf_"):
            return None
        
        db = get_database_session()
        try:
            token_hash = hashlib.sha256(token.encode()).hexdigest()
            
            # 从数据库查询Token
            db_token = db.query(TokenRecord).filter(
                TokenRecord.token_hash == token_hash
            ).first()
            
            if not db_token:
                return None
            
            # 更新使用统计
            self._update_token_usage(db, db_token)
            
            # 计算今日剩余次数
            daily_remaining = max(0, db_token.daily_upload_limit - db_token.daily_usage)
            
            return AuthenticatedUser(
                user_id=db_token.user_id,
                user_name=db_token.user_name,
                role=UserRole(db_token.role),
                max_file_size=db_token.max_file_size,
                daily_remaining=daily_remaining,
                token_hash=token_hash
            )
            
        finally:
            db.close()
    
    def _update_token_usage(self, db: Session, db_token: TokenRecord):
        """更新Token访问记录（不增加每日上传计数，仅记录访问）"""
        now = datetime.utcnow()
        today = now.strftime("%Y-%m-%d")

        # 如果是新的一天，重置每日使用计数
        last_used_date = db_token.last_used_at.strftime("%Y-%m-%d") if db_token.last_used_at else None
        if last_used_date != today:
            db_token.daily_usage = 0

        # 只更新访问时间和总调用次数，不增加 daily_usage
        # daily_usage 只在文件上传完成时增加（由 record_upload_complete 处理）
        db_token.usage_count += 1
        db_token.last_used_at = now

        db.commit()

    def record_upload_complete(self, token_hash: str) -> bool:
        """记录一次完成的文件上传（增加每日上传计数）"""
        db = get_database_session()
        try:
            db_token = db.query(TokenRecord).filter(
                TokenRecord.token_hash == token_hash
            ).first()

            if not db_token:
                return False

            # 检查是否需要重置每日计数
            now = datetime.utcnow()
            today = now.strftime("%Y-%m-%d")
            last_used_date = db_token.last_used_at.strftime("%Y-%m-%d") if db_token.last_used_at else None
            if last_used_date != today:
                db_token.daily_usage = 0

            # 增加每日上传计数
            db_token.daily_usage += 1
            db.commit()
            return True

        finally:
            db.close()
    
    def revoke_token(self, token: str) -> bool:
        """撤销Token（直接删除）"""
        if not token or not token.startswith("hf_"):
            return False
        
        db = get_database_session()
        try:
            token_hash = hashlib.sha256(token.encode()).hexdigest()
            
            deleted_count = db.query(TokenRecord).filter(
                TokenRecord.token_hash == token_hash
            ).delete()
            
            db.commit()
            return deleted_count > 0
            
        finally:
            db.close()
    
    def get_user_tokens(self, user_id: str) -> List[Dict[str, Any]]:
        """获取用户的所有Token（不包含实际token值）"""
        db = get_database_session()
        try:
            db_tokens = db.query(TokenRecord).filter(
                TokenRecord.user_id == user_id
            ).all()
            
            user_tokens = []
            for db_token in db_tokens:
                user_tokens.append({
                    "token_hash": db_token.token_hash[:16] + "...",
                    "user_name": db_token.user_name,
                    "role": db_token.role,
                    "created_at": db_token.created_at,
                    "last_used_at": db_token.last_used_at,
                    "usage_count": db_token.usage_count,
                    "daily_usage": db_token.daily_usage,
                    "daily_limit": db_token.daily_upload_limit
                })
            return user_tokens
            
        finally:
            db.close()
    


# 全局数据库Token管理器实例
db_token_manager = DatabaseTokenManager()


def get_db_token_manager() -> DatabaseTokenManager:
    """获取数据库Token管理器实例"""
    return db_token_manager
