const Base = require('../../base');

module.exports = class extends Base {
  // 用户列表页面
  async indexAction() {
    this.assign('currentPage', 'sys-user');
    this.assign('pageTitle', '用户管理');
    this.assign('breadcrumb', [
      { name: '系统管理', url: '/admin/system/user.html' },
      { name: '用户管理' }
    ]);

    // 获取角色列表
    const roles = await this.model('admin_role')
      .where({ is_deleted: 0 })
      .select();
    this.assign('roles', roles);

    // 当前登录用户
    this.assign('adminUser', this.adminUser || {});

    return this.display();
  }

  // 获取用户列表接口
  async listAction() {
    const { keyword, role_id, status, page = 1, pageSize = 10 } = this.get();

    const where = { is_deleted: 0 };

    if (keyword) {
      where._complex = {
        username: ['like', `%${keyword}%`],
        nickname: ['like', `%${keyword}%`],
        _logic: 'or'
      };
    }

    if (role_id) {
      where.role_id = role_id;
    }

    if (status !== undefined && status !== '') {
      where.status = parseInt(status, 10);
    }

    const list = await this.model('admin_user')
      .where(where)
      .order('id ASC')
      .page(page, pageSize)
      .countSelect();

    // 获取角色名称
    const roleIds = [...new Set(list.data.map(item => item.role_id))];
    const roles = roleIds.length ? await this.model('admin_role')
      .where({ id: ['in', roleIds] })
      .select() : [];
    const roleMap = {};
    roles.forEach(r => roleMap[r.id] = r.name);

    list.data.forEach(item => {
      item.role_name = roleMap[item.role_id] || '-';
      delete item.password;
    });

    return this.success(list);
  }

  // 获取单个用户
  async detailAction() {
    const { id } = this.get();
    if (!id) return this.fail('参数错误');

    const user = await this.model('admin_user')
      .where({ id, is_deleted: 0 })
      .find();

    if (think.isEmpty(user)) {
      return this.fail('用户不存在');
    }

    delete user.password;
    return this.success(user);
  }

  // 新增用户
  async addAction() {
    const { username, password, nickname, email, phone, role_id, status = 1 } = this.post();

    if (!username || !password) {
      return this.fail('用户名和密码不能为空');
    }

    // 密码强度校验
    const pwdErr = this.checkPasswordStrength(password);
    if (pwdErr) return this.fail(pwdErr);

    // 检查用户名是否存在
    const exist = await this.model('admin_user')
      .where({ username, is_deleted: 0 })
      .find();

    if (!think.isEmpty(exist)) {
      return this.fail('用户名已存在');
    }

    const data = {
      username,
      password: think.md5(password),
      nickname: nickname || '',
      email: email || '',
      phone: phone || '',
      role_id: role_id || 0,
      status,
      create_by: this.adminUser?.id || 0
    };

    const id = await this.model('admin_user').add(data);
    await this.log('add', '用户管理', `新增用户「${username}」`);
    return this.success({ id });
  }

  // 编辑用户
  async editAction() {
    const { id, nickname, email, phone, role_id, status } = this.post();

    if (!id) return this.fail('参数错误');

    const user = await this.model('admin_user')
      .where({ id, is_deleted: 0 })
      .find();

    if (think.isEmpty(user)) {
      return this.fail('用户不存在');
    }

    const data = {
      nickname: nickname || user.nickname,
      email: email || user.email,
      phone: phone || user.phone,
      role_id: role_id !== undefined ? role_id : user.role_id,
      status: status !== undefined ? status : user.status,
      update_by: this.adminUser?.id || 0
    };

    await this.model('admin_user').where({ id }).update(data);
    await this.log('edit', '用户管理', `编辑用户(ID:${id})`);
    return this.success();
  }

  // 重置密码
  async resetPasswordAction() {
    const { id, password } = this.post();

    if (!id || !password) {
      return this.fail('参数错误');
    }

    // 密码强度校验
    const pwdErr = this.checkPasswordStrength(password);
    if (pwdErr) return this.fail(pwdErr);

    const user = await this.model('admin_user')
      .where({ id, is_deleted: 0 })
      .find();

    if (think.isEmpty(user)) {
      return this.fail('用户不存在');
    }

    await this.model('admin_user')
      .where({ id })
      .update({
        password: think.md5(password),
        update_by: this.adminUser?.id || 0
      });

    await this.log('edit', '用户管理', `重置用户密码(ID:${id})`);
    return this.success();
  }

  // 删除用户（软删除）
  async deleteAction() {
    const { id } = this.post();

    if (!id) return this.fail('参数错误');

    // 不能删除自己
    if (id == this.adminUser?.id) {
      return this.fail('不能删除当前登录用户');
    }

    await this.model('admin_user')
      .where({ id })
      .update({
        is_deleted: 1,
        update_by: this.adminUser?.id || 0
      });

    await this.log('delete', '用户管理', `删除用户(ID:${id})`);
    return this.success();
  }

  // 切换状态
  async toggleStatusAction() {
    const { id } = this.post();

    if (!id) return this.fail('参数错误');

    const user = await this.model('admin_user')
      .where({ id, is_deleted: 0 })
      .find();

    if (think.isEmpty(user)) {
      return this.fail('用户不存在');
    }

    // 不能禁用自己
    if (id == this.adminUser?.id) {
      return this.fail('不能禁用当前登录用户');
    }

    await this.model('admin_user')
      .where({ id })
      .update({
        status: user.status === 1 ? 0 : 1,
        update_by: this.adminUser?.id || 0
      });

    return this.success();
  }

  // 解锁用户（清除登录失败计数）
  async unlockAction() {
    const { id } = this.post();
    if (!id) return this.fail('参数错误');

    const user = await this.model('admin_user')
      .where({ id, is_deleted: 0 })
      .find();

    if (think.isEmpty(user)) {
      return this.fail('用户不存在');
    }

    await this.model('admin_user')
      .where({ id })
      .update({ login_fail_count: 0, login_fail_date: null });

    await this.log('edit', '用户管理', `解锁用户「${user.username}」`);
    return this.success();
  }

  // 密码强度校验：至少8位，大写/小写/数字至少包含两种
  checkPasswordStrength(pwd) {
    if (!pwd || pwd.length < 8) {
      return '密码长度不能少于8位';
    }
    let types = 0;
    if (/[a-z]/.test(pwd)) types++;
    if (/[A-Z]/.test(pwd)) types++;
    if (/\d/.test(pwd)) types++;
    if (types < 2) {
      return '密码需包含大写字母、小写字母、数字中的至少两种';
    }
    return null;
  }
};
