import CryptoJS from 'crypto-js'
import RsaEncryptJS from 'jsencrypt'

export default {
  /**
   * AES加密
   * @param word
   * @returns {*}
   */
  AESEncrypt(word, encryKey) {
    const key = CryptoJS.enc.Utf8.parse(encryKey)
    const srcs = CryptoJS.enc.Utf8.parse(word)
    const encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
    return encrypted.toString()
  },
  /**
   * AES解密
   * @param word
   * @returns {*}
   */
  AESDecrypt(word, encryKey) {
    const key = CryptoJS.enc.Utf8.parse(encryKey)
    const decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
    const ret = CryptoJS.enc.Utf8.stringify(decrypt).toString()
    try {
      return JSON.parse(ret)
    } catch (e) {
      return ret
    }
  },
  /**
   * RSA加密
   * @param word
   * @returns {*}
   */
  RSAEncrypt(word) {
    const encrypt = new RsaEncryptJS()
    encrypt.setPublicKey('MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqPvovSfXcwBbW8cKMCgwqNpsYuzF8RPAPFb7LGsnVo44JhM/xxzDyzoYtdfNmtbIuKVi9PzIsyp6rg+09gbuI6UGwBZ5DWBDBMqv5MPdOF5dCQkB2Bbr5yPfURPENypUz+pBFBg41d+BC+rwRiXELwKy7Y9caD/MtJyHydj8OUwIDAQAB')
    const resdata = encrypt.encrypt(word)
    return resdata.toString()
  },
  /**
   * RSA解密
   * @param word
   * @returns {*}
   */
  RSADecrypt(word) {
    const encrypt = new RsaEncryptJS()
    encrypt.setPrivateKey('MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKo++i9J9dzAFtbxwowKDCo2mxi7MXxE8A8VvssaydWjjgmEz/HHMPLOhi1182a1si4pWL0/MizKnquD7T2Bu4jpQbAFnkNYEMEyq/kw904Xl0JCQHYFuvnI99RE8Q3KlTP6kEUGDjV34EL6vBGJcQvArLtj1xoP8y0nIfJ2Pw5TAgMBAAECgYAGGB8IllMwxceLhjf6n1l0IWRH7FuHIUieoZ6k0p6rASHSgWiYNRMxfecbtX8zDAoG0QAWNi7rn40ygpR5gS1fWDAKhmnhKgQIT6wW0VmD4hraaeyP78iy8BLhlvblri2nCPIhDH5+l96v7D47ZZi3ZSOzcj89s1eS/k7/N4peEQJBAPEtGGJY+lBoCxQMhGyzuzDmgcS1Un1ZE2pt+XNCVl2b+T8fxWJH3tRRR8wOY5uvtPiK1HM/IjT0T5qwQeH8Yk0CQQC0tcv3d/bDb7bOe9QzUFDQkUSpTdPWAgMX2OVPxjdq3Sls9oA5+fGNYEy0OgyqTjde0b4iRzlD1O0OhLqPSUMfAkEAh5FIvqezdRU2/PsYSR4yoAdCdLdT+h/jGRVefhqQ/6eYUJJkWp15tTFHQX3pIe9/s6IeT/XyHYAjaxmevxAmlQJBAKSdhvQjf9KAjZKDEsa7vyJ/coCXuQUWSCMNHbcR5aGfXgE4e45UtUoIE1eKGcd6AM6LWhx3rR6xdFDpb9je8BkCQB0SpevGfOQkMk5i8xkEt9eeYP0fi8nv6eOUcK96EXbzs4jV2SAoQJ9oJegPtPROHbhIvVUmNQTbuP10Yjg59+8=')
    const resdata = encrypt.decrypt(word)
    return JSON.parse(resdata.toString())
  },
  /**
   * RSA 私钥解密，返回明文字符串（不做 JSON 解析）
   *
   * @param {string} encryptedData Base64 密文
   * @param {string} privateKey PKCS#8 格式的私钥
   * @returns {string|null} 解密失败时返回 null
   */
  RSADecryptRaw(encryptedData, privateKey) {
    try {
      const encrypt = new RsaEncryptJS()
      encrypt.setPrivateKey(privateKey)
      const decrypted = encrypt.decrypt(encryptedData)
      if (!decrypted) return null
      return decrypted
    } catch {
      return null
    }
  },

  AESEncryptCBC(data, CRYPTO_KEY) {
    // 生成随机IV（每次加密不同）
    const iv = CryptoJS.lib.WordArray.random(16)

    // 使用 AES CBC 模式进行加密
    const encrypted = CryptoJS.AES.encrypt(
      JSON.stringify(data),
      CryptoJS.enc.Hex.parse(CRYPTO_KEY),
      {
        iv: iv, // IV
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      }
    )

    // 组合IV和密文，分别Base64编码：IV(base64) + : + 密文(base64)
    const ivBase64 = iv.toString(CryptoJS.enc.Base64)
    const encryptedBase64 = encrypted.toString()

    return `${ivBase64}:${encryptedBase64}`
  },
  /**
   * AES CBC模式解密
   *
   * @param combinedText 格式：Base64(iv):Base64(ciphertext)
   * @param hexKey 十六进制格式的加密密钥
   * @returns 解密后的原始字符串
   */
  AESDecryptCBC(combinedText, hexKey) {
    try {
      // 分离 IV 和 密文
      const parts = combinedText.split(':')
      if (parts.length !== 2) {
        throw new Error('Invalid encrypted data format')
      }

      const ivBase64 = parts[0]
      const encryptedBase64 = parts[1]

      // 解析IV和密文
      const iv = CryptoJS.enc.Base64.parse(ivBase64)
      const key = CryptoJS.enc.Hex.parse(hexKey)

      // 解密
      const decrypted = CryptoJS.AES.decrypt(encryptedBase64, key, {
        iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      })

      // 将解密后的数据转换为字符串
      return decrypted.toString(CryptoJS.enc.Utf8)
    } catch (error) {
      throw new Error(`AES-CBC解密失败: ${error}`)
    }
  },
  /**
   * 安全的AES-CBC解密（失败时返回null） 用于响应自动解密，解密失败时不抛出异常
   *
   * @param combinedText 格式：Base64(iv):Base64(ciphertext)
   * @param hexKey 十六进制格式的密钥
   * @returns 解密后的字符串，失败时返回null
   */
  safeAESDecryptCBC(combinedText, hexKey) {
    try {
      return this.AESDecryptCBC(combinedText, hexKey)
    } catch {
      // AES-CBC解密失败，静默处理
      return null
    }
  },
  /**
   * 智能响应解密 自动检测响应数据格式并进行解密
   *
   * @param responseData 响应数据
   * @param sessionKey 会话密钥
   * @returns 解密后的数据，失败时返回原数据
   */
  decryptResponse(responseData, sessionKey) {
    try {
      let dataStr = ''

      // 处理不同类型的响应数据
      if (typeof responseData === 'string') {
        dataStr = responseData
      } else if (typeof responseData === 'object') {
        dataStr = JSON.stringify(responseData)
      } else {
        dataStr = String(responseData)
      }

      // 尝试解密
      const decryptedStr = this.safeAESDecryptCBC(dataStr, sessionKey)
      if (decryptedStr) {
        try {
          return JSON.parse(decryptedStr)
        } catch {
          return decryptedStr
        }
      }
    } catch (e) {
      console.warn(e)
      // 响应解密处理失败，静默处理
    }

    // 解密失败或数据格式不正确时，返回原数据
    return responseData
  }
}
