/**
 * User 模型定义
 * @file User.js
 * @description 定义用户模型，用于数据库操作
 */
const { DataTypes } = require('sequelize');
const bcrypt = require('bcryptjs');
const BaseModel = require('./BaseModel');
const { sequelize } = require('../config/database-simple');

class User extends BaseModel {
  /**
   * 验证密码
   * @param {String} password 待验证的密码
   * @returns {Promise<Boolean>} 验证结果
   */
  async validPassword(password) {
    return await bcrypt.compare(password, this.password);
  }

  /**
   * 获取用户角色
   * @returns {Promise<Array>} 用户角色列表
   */
  async getRoles() {
    // 简化实现，直接返回当前角色
    try {
      const { Role } = require('./index');
      const role = await Role.findByPk(this.roles);
      return role ? [role] : [];
    } catch (error) {
      console.error('获取用户角色失败:', error);
      return [];
    }
  }

  /**
   * 获取用户权限列表
   * @returns {Promise<Array>} 用户权限列表
   */
  async getPermissions() {
    try {
      const { getRolePermissions } = require('../config/permissions');
      const roles = await this.getRoles();
      
      if (roles.length === 0) {
        return [];
      }
      
      // 获取角色的所有权限
      const allPermissions = new Set();
      for (const role of roles) {
        const rolePermissions = getRolePermissions(role.name);
        rolePermissions.forEach(permission => allPermissions.add(permission));
      }
      
      return Array.from(allPermissions);
    } catch (error) {
      console.error('获取用户权限失败:', error);
      return [];
    }
  }

  /**
   * 检查用户是否具有指定权限
   * @param {string|Array} permissions 权限名称或权限数组
   * @returns {Promise<boolean>} 是否有权限
   */
  async hasPermission(permissions) {
    try {
      const { hasPermission } = require('../config/permissions');
      const userPermissions = await this.getPermissions();
      return hasPermission(userPermissions, permissions);
    } catch (error) {
      console.error('检查用户权限失败:', error);
      return false;
    }
  }

  /**
   * 检查用户是否具有指定角色
   * @param {String|Array} roleName 角色名称或角色名称数组
   * @returns {Promise<Boolean>} 检查结果
   */
  async hasRole(roleName) {
    const roles = await this.getRoles();
    const roleNames = roles.map(role => role.name);
    
    if (Array.isArray(roleName)) {
      return roleName.some(name => roleNames.includes(name));
    }
    
    return roleNames.includes(roleName);
  }

  /**
   * 为用户分配角色
   * @param {Number} roleId 角色ID
   * @returns {Promise<Boolean>} 分配结果
   */
  async assignRole(roleId) {
    try {
      this.roles = roleId;
      await this.save();
      return true;
    } catch (error) {
      console.error('分配角色失败:', error);
      return false;
    }
  }

  /**
   * 移除用户角色
   * @returns {Promise<Boolean>} 移除结果
   */
  async removeRole() {
    try {
      this.roles = null;
      await this.save();
      return true;
    } catch (error) {
      console.error('移除角色失败:', error);
      return false;
    }
  }

  /**
   * 获取用户安全信息（不包含密码）
   * @returns {Object} 用户安全信息
   */
  getSafeInfo() {
    const { password, ...safeInfo } = this.get({ plain: true });
    return safeInfo;
  }
}

// 初始化User模型
User.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  username: {
    type: DataTypes.STRING(50),
    allowNull: false,
    unique: true
  },
  email: {
    type: DataTypes.STRING(100),
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true
    }
  },
  password: {
    type: DataTypes.STRING(255),
    allowNull: false
  },
  phone: {
    type: DataTypes.STRING(20),
    allowNull: true
  },
  avatar: {
    type: DataTypes.STRING(255),
    allowNull: true
  },
  roles: {
    type: DataTypes.INTEGER,
    allowNull: true,
    defaultValue: 2, // 默认为user角色ID
    references: {
      model: 'roles',
      key: 'id'
    }
  },
  status: {
    type: DataTypes.ENUM('active', 'inactive', 'suspended'),
    defaultValue: 'active'
  }
}, {
  sequelize,
  tableName: 'users',
  modelName: 'User',
  hooks: {
    beforeCreate: async (user) => {
      if (user.password) {
        user.password = await bcrypt.hash(user.password, 10);
      }
    },
    beforeUpdate: async (user) => {
      if (user.changed('password')) {
        user.password = await bcrypt.hash(user.password, 10);
      }
    }
  }
});

// 关联关系已在 models/index.js 中定义

module.exports = User;