from datetime import datetime
from typing import Optional
from pydantic import BaseModel, EmailStr, Field, ConfigDict
from app.domain.models.role import UserRole

# ============================================
# Request Schemas (输入)
# ============================================

class UserCreate(BaseModel):
    """用户注册"""
    username: str = Field(..., min_length=3, max_length=50, 
                         description="用户名，3-50个字符")
    email: EmailStr = Field(..., description="邮箱地址")
    password: str = Field(..., min_length=6, max_length=100, 
                         description="密码，至少6个字符")
    role: UserRole = Field(default=UserRole.USER, description="用户角色")

class UserLogin(BaseModel):
    """用户登录"""
    username: str = Field(..., description="用户名或邮箱")
    password: str = Field(..., description="密码")

class UserUpdate(BaseModel):
    """用户信息更新"""
    email: Optional[EmailStr] = None
    password: Optional[str] = Field(None, min_length=6, max_length=100)
    role: Optional[UserRole] = None
    is_active: Optional[bool] = None

# ============================================
# Response Schemas (输出)
# ============================================

class UserResponse(BaseModel):
    """用户信息响应（不含密码）"""
    id: int
    username: str
    email: str
    role: UserRole
    is_active: bool
    is_superuser: bool
    created_at: datetime
    updated_at: datetime
    
    model_config = ConfigDict(from_attributes=True)

class UserInDB(UserResponse):
    """数据库中的用户（含密码哈希）"""
    hashed_password: str

# ============================================
# Token Schemas
# ============================================

class Token(BaseModel):
    """JWT Token 响应"""
    access_token: str
    refresh_token: Optional[str] = None
    token_type: str = "bearer"
    expires_in: int = Field(..., description="过期时间（秒）")

class TokenPayload(BaseModel):
    """JWT Token Payload"""
    sub: str = Field(..., description="用户ID或用户名")
    exp: Optional[int] = None
    iat: Optional[int] = None
    type: str = Field(default="access", description="token类型: access 或 refresh")
