# -*- coding: utf-8 -*-
"""
用户相关模型

包含用户、会话、权限和角色定义
"""

from werkzeug.security import generate_password_hash, check_password_hash
from .base import db, get_beijing_now


# 权限常量
class Permission:
    """权限常量定义"""
    VIEW_PROFILE = 0x01
    EDIT_PROFILE = 0x02
    GENERATE_CHALLENGE = 0x04
    VIEW_OWN_HISTORY = 0x08
    VIEW_ALL_HISTORY = 0x10
    ADMIN = 0xff


# 角色常量
class Role:
    """角色常量定义"""
    USER = 'user'
    ADMIN = 'admin'
    MODERATOR = 'moderator'

    @staticmethod
    def get_permissions(role):
        """根据角色获取权限"""
        if role == Role.ADMIN:
            return Permission.ADMIN
        elif role == Role.MODERATOR:
            return (Permission.VIEW_PROFILE | Permission.EDIT_PROFILE | 
                   Permission.GENERATE_CHALLENGE | Permission.VIEW_OWN_HISTORY |
                   Permission.VIEW_ALL_HISTORY)
        else:  # USER
            return (Permission.VIEW_PROFILE | Permission.EDIT_PROFILE | 
                   Permission.GENERATE_CHALLENGE | Permission.VIEW_OWN_HISTORY)


class User(db.Model):
    """用户模型"""
    __tablename__ = 'users'
    
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password_hash = db.Column(db.String(255), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    avatar = db.Column(db.String(255))
    is_active = db.Column(db.Boolean, default=True)
    role = db.Column(db.String(20), default='user')
    # 用户首选的系统级 AI 配置（指向 ai_provider_configs.id，允许为空）
    preferred_system_ai_config_id = db.Column(
        db.Integer,
        db.ForeignKey('ai_provider_configs.id'),
        nullable=True
    )
    last_login = db.Column(db.DateTime)
    created_at = db.Column(db.DateTime, default=get_beijing_now)
    updated_at = db.Column(db.DateTime, default=get_beijing_now, onupdate=get_beijing_now)
    
    # 关联关系定义在各自模型中
    
    def set_password(self, password):
        """设置加密密码"""
        self.password_hash = generate_password_hash(password, method='pbkdf2:sha256')
    
    def check_password(self, password):
        """验证密码"""
        return check_password_hash(self.password_hash, password)
    
    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'avatar': self.avatar,
            'role': self.role,
            'last_login': self.last_login.isoformat() if self.last_login else None,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }
    
    @staticmethod
    def from_dict(data):
        """从字典创建用户"""
        user = User(
            username=data.get('username'),
            email=data.get('email'),
            avatar=data.get('avatar'),
            role=data.get('role', 'user'),
            is_active=data.get('is_active', True)
        )
        
        if 'password' in data:
            user.set_password(data['password'])
            
        return user


class UserSession(db.Model):
    """用户会话模型"""
    __tablename__ = 'user_sessions'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    session_token = db.Column(db.String(255), unique=True, nullable=False)
    ip_address = db.Column(db.String(50))
    user_agent = db.Column(db.Text)
    expires_at = db.Column(db.DateTime, nullable=False)
    created_at = db.Column(db.DateTime, default=get_beijing_now)
    
    # 关联
    user = db.relationship('User', backref=db.backref('sessions', lazy='dynamic'))
    
    @property
    def is_valid(self):
        """检查会话是否有效"""
        current_time = get_beijing_now()
        return current_time < self.expires_at


