/**
 * Password Generator - 密码生成器
 */

const { randomInt } = require('../../utils');

class PasswordGenerator {
  constructor() {
    this.lowercase = 'abcdefghijklmnopqrstuvwxyz';
    this.uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    this.numbers = '0123456789';
    this.special = '!@#$%^&*()_+-=[]{}|;:,.<>?';
  }

  /**
   * 生成密码
   * @param {Object} options - 选项
   * @returns {string}
   */
  generate(options = {}) {
    const {
      length = 12,
      includeUppercase = true,
      includeLowercase = true,
      includeNumbers = true,
      includeSpecial = true,
      minUppercase = 1,
      minLowercase = 1,
      minNumbers = 1,
      minSpecial = 1
    } = options;

    let chars = '';
    let password = '';

    // 构建字符集
    if (includeLowercase) chars += this.lowercase;
    if (includeUppercase) chars += this.uppercase;
    if (includeNumbers) chars += this.numbers;
    if (includeSpecial) chars += this.special;

    if (chars.length === 0) {
      throw new Error('At least one character type must be included');
    }

    // 确保满足最小要求
    if (includeLowercase && minLowercase > 0) {
      for (let i = 0; i < minLowercase; i++) {
        password += this.lowercase.charAt(randomInt(0, this.lowercase.length - 1));
      }
    }

    if (includeUppercase && minUppercase > 0) {
      for (let i = 0; i < minUppercase; i++) {
        password += this.uppercase.charAt(randomInt(0, this.uppercase.length - 1));
      }
    }

    if (includeNumbers && minNumbers > 0) {
      for (let i = 0; i < minNumbers; i++) {
        password += this.numbers.charAt(randomInt(0, this.numbers.length - 1));
      }
    }

    if (includeSpecial && minSpecial > 0) {
      for (let i = 0; i < minSpecial; i++) {
        password += this.special.charAt(randomInt(0, this.special.length - 1));
      }
    }

    // 填充剩余长度
    while (password.length < length) {
      password += chars.charAt(randomInt(0, chars.length - 1));
    }

    // 打乱顺序
    password = this.shuffle(password);

    return password;
  }

  /**
   * 打乱字符串
   * @param {string} str - 字符串
   * @returns {string}
   */
  shuffle(str) {
    const arr = str.split('');
    for (let i = arr.length - 1; i > 0; i--) {
      const j = randomInt(0, i);
      [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    return arr.join('');
  }

  /**
   * 生成简单密码（只包含字母和数字）
   * @param {number} length - 长度
   * @returns {string}
   */
  generateSimple(length = 12) {
    return this.generate({
      length,
      includeUppercase: true,
      includeLowercase: true,
      includeNumbers: true,
      includeSpecial: false
    });
  }

  /**
   * 生成强密码
   * @param {number} length - 长度
   * @returns {string}
   */
  generateStrong(length = 16) {
    return this.generate({
      length,
      includeUppercase: true,
      includeLowercase: true,
      includeNumbers: true,
      includeSpecial: true,
      minUppercase: 2,
      minLowercase: 2,
      minNumbers: 2,
      minSpecial: 2
    });
  }

  /**
   * 批量生成
   * @param {number} count - 数量
   * @param {Object} options - 选项
   * @returns {Array}
   */
  generateBatch(count, options = {}) {
    const passwords = [];
    for (let i = 0; i < count; i++) {
      passwords.push(this.generate(options));
    }
    return passwords;
  }
}

module.exports = PasswordGenerator;
