/**
 * 系统用户数据模型
 * 作者: 阿瑞
 * 功能: 提供系统用户数据的CRUD操作
 * 版本: 1.3
 */
import { PoolConnection, RowDataPacket, ResultSetHeader } from 'mysql2/promise';
import { 
  ISystemUser, 
  ICreateSystemUserParams, 
  IUpdateSystemUserParams, 
  UserStatus, 
  SystemRoleType
} from './types';

/**
 * 系统用户查询结果行类型
 */
interface UserRow extends RowDataPacket, ISystemUser {}

/**
 * 系统用户数据模型类
 * 提供对系统用户表的增删改查操作
 */
export class SystemUserModel {
  /**
   * 表名常量
   */
  private static readonly TABLE_NAME = 'system_users';

  /**
   * 获取所有系统用户列表
   * @param connection 数据库连接
   */
  public static async getAll(connection: PoolConnection): Promise<ISystemUser[]> {
    try {
      // 执行查询
      const [rows] = await connection.query<UserRow[]>(
        `SELECT * FROM ${this.TABLE_NAME}`
      );
      
      return rows as ISystemUser[];
    } catch (error) {
      console.error('获取系统用户列表失败:', error);
      throw new Error('获取系统用户列表失败');
    }
  }

  /**
   * 按工作空间ID获取用户列表
   * @param connection 数据库连接
   * @param workspaceId 工作空间ID
   */
  public static async getByWorkspace(connection: PoolConnection, workspaceId: number): Promise<ISystemUser[]> {
    try {
      // 执行查询
      const [rows] = await connection.query<UserRow[]>(
        `SELECT * FROM ${this.TABLE_NAME} WHERE workspace_id = ?`,
        [workspaceId]
      );
      
      return rows as ISystemUser[];
    } catch (error) {
      console.error(`获取工作空间(ID: ${workspaceId})的用户列表失败:`, error);
      throw new Error('获取工作空间用户列表失败');
    }
  }

  /**
   * 根据ID获取系统用户
   * @param connection 数据库连接
   * @param id 用户ID
   */
  public static async getById(connection: PoolConnection, id: number): Promise<ISystemUser | null> {
    try {
      // 执行查询
      const [rows] = await connection.query<UserRow[]>(
        `SELECT * FROM ${this.TABLE_NAME} WHERE id = ?`,
        [id]
      );
      
      return rows.length > 0 ? rows[0] as ISystemUser : null;
    } catch (error) {
      console.error(`获取用户(ID: ${id})失败:`, error);
      throw new Error(`获取用户失败`);
    }
  }

  /**
   * 根据用户名获取系统用户
   * @param connection 数据库连接
   * @param username 用户名
   */
  public static async getByUsername(connection: PoolConnection, username: string): Promise<ISystemUser | null> {
    try {
      // 执行查询
      const [rows] = await connection.query<UserRow[]>(
        `SELECT * FROM ${this.TABLE_NAME} WHERE username = ?`, 
        [username]
      );
      
      return rows.length > 0 ? rows[0] as ISystemUser : null;
    } catch (error) {
      console.error(`获取用户(用户名: ${username})失败:`, error);
      throw new Error(`获取用户失败`);
    }
  }

  /**
   * 根据邮箱获取系统用户
   * @param connection 数据库连接
   * @param email 邮箱
   */
  public static async getByEmail(connection: PoolConnection, email: string): Promise<ISystemUser | null> {
    try {
      // 执行查询
      const [rows] = await connection.query<UserRow[]>(
        `SELECT * FROM ${this.TABLE_NAME} WHERE email = ?`, 
        [email]
      );
      
      return rows.length > 0 ? rows[0] as ISystemUser : null;
    } catch (error) {
      console.error(`获取用户(邮箱: ${email})失败:`, error);
      throw new Error(`获取用户失败`);
    }
  }

  /**
   * 创建新系统用户
   * @param connection 数据库连接
   * @param params 创建参数
   */
  public static async create(connection: PoolConnection, params: ICreateSystemUserParams): Promise<number> {
    try {
      const { 
        username, 
        password, 
        email, 
        phone, 
        workspace_id, 
        role_type = SystemRoleType.USER,
        role_name = '普通用户',
        is_custom_role = false,
        invited_by = null, 
        invitation_token = null 
      } = params;
      
      // 使用参数化查询插入用户
      const [result] = await connection.query<ResultSetHeader>(
        `INSERT INTO ${this.TABLE_NAME} (
          username, password, email, phone, workspace_id, 
          role_type, role_name, is_custom_role, status, 
          invited_by, invitation_token, created_at
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          username, password, email, phone, workspace_id,
          role_type, role_name, is_custom_role, UserStatus.ENABLED,
          invited_by, invitation_token, new Date()
        ]
      );
      
      return result.insertId;
    } catch (error) {
      console.error('创建系统用户失败:', error);
      throw new Error('创建系统用户失败');
    }
  }

  /**
   * 更新系统用户信息
   * @param connection 数据库连接
   * @param id 用户ID
   * @param params 更新参数
   */
  public static async update(connection: PoolConnection, id: number, params: IUpdateSystemUserParams): Promise<boolean> {
    try {
      // 构建更新字段和参数
      const updateFields: string[] = [];
      const values: (string | number | boolean | Date | null)[] = [];
      
      if (params.username !== undefined) {
        updateFields.push('username = ?');
        values.push(params.username);
      }
      
      if (params.password !== undefined) {
        updateFields.push('password = ?');
        values.push(params.password);
      }
      
      if (params.email !== undefined) {
        updateFields.push('email = ?');
        values.push(params.email);
      }
      
      if (params.phone !== undefined) {
        updateFields.push('phone = ?');
        values.push(params.phone);
      }
      
      if (params.role_type !== undefined) {
        updateFields.push('role_type = ?');
        values.push(params.role_type);
      }
      
      if (params.role_name !== undefined) {
        updateFields.push('role_name = ?');
        values.push(params.role_name);
      }
      
      if (params.is_custom_role !== undefined) {
        updateFields.push('is_custom_role = ?');
        values.push(params.is_custom_role);
      }
      
      if (params.status !== undefined) {
        updateFields.push('status = ?');
        values.push(params.status);
      }
      
      if (params.last_login_at !== undefined) {
        updateFields.push('last_login_at = ?');
        values.push(params.last_login_at);
      }
      
      // 添加更新时间
      updateFields.push('updated_at = ?');
      values.push(new Date());
      
      // 没有更新字段则直接返回成功
      if (updateFields.length === 0) {
        return true;
      }
      
      // 添加ID条件参数
      values.push(id);
      
      // 执行更新
      const [result] = await connection.query<ResultSetHeader>(
        `UPDATE ${this.TABLE_NAME} SET ${updateFields.join(', ')} WHERE id = ?`,
        values
      );
      
      return result.affectedRows > 0;
    } catch (error) {
      console.error(`更新用户(ID: ${id})失败:`, error);
      throw new Error('更新用户失败');
    }
  }

  /**
   * 更新用户最后登录时间
   * @param connection 数据库连接
   * @param id 用户ID
   */
  public static async updateLastLogin(connection: PoolConnection, id: number): Promise<boolean> {
    try {
      // 更新最后登录时间为当前时间
      const [result] = await connection.query<ResultSetHeader>(
        `UPDATE ${this.TABLE_NAME} SET last_login_at = ?, updated_at = ? WHERE id = ?`,
        [new Date(), new Date(), id]
      );
      
      return result.affectedRows > 0;
    } catch (error) {
      console.error(`更新用户(ID: ${id})最后登录时间失败:`, error);
      throw new Error('更新用户最后登录时间失败');
    }
  }

  /**
   * 禁用系统用户
   * @param connection 数据库连接
   * @param id 用户ID
   */
  public static async disable(connection: PoolConnection, id: number): Promise<boolean> {
    try {
      // 禁用用户
      const [result] = await connection.query<ResultSetHeader>(
        `UPDATE ${this.TABLE_NAME} SET status = ?, updated_at = ? WHERE id = ?`,
        [UserStatus.DISABLED, new Date(), id]
      );
      
      return result.affectedRows > 0;
    } catch (error) {
      console.error(`禁用用户(ID: ${id})失败:`, error);
      throw new Error('禁用用户失败');
    }
  }
} 