/**
 * License Key 加密/解密模块
 * 使用 HMAC-SHA256 + Base32 (Crockford 变体) 编码
 */

const crypto = require("crypto");

// Base32 Crockford 字符集 — 排除 I, L, O, U 避免混淆
const BASE32_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
const DECODE_MAP = {};
for (let i = 0; i < BASE32_ALPHABET.length; i++) {
  DECODE_MAP[BASE32_ALPHABET[i]] = i;
  // 混淆字符映射
  DECODE_MAP[BASE32_ALPHABET[i].toLowerCase()] = i;
}
DECODE_MAP["I"] = 1; DECODE_MAP["i"] = 1;
DECODE_MAP["L"] = 1; DECODE_MAP["l"] = 1;
DECODE_MAP["O"] = 0; DECODE_MAP["o"] = 0;
DECODE_MAP["U"] = 27; DECODE_MAP["u"] = 27;

// 格式：AINEOS-XXXX-XXXX-... (至少2组，最后一组1-4字符)
// base32 编码长度可能不是4的倍数，最后一组允许1-4字符
const KEY_FORMAT = /^AINEOS-[A-Z0-9]{4}(-[A-Z0-9]{4})*(-[A-Z0-9]{1,4})$/;
const SIG_BYTES = 32; // HMAC-SHA256 signature length

function getSecret() {
  return process.env.AINEOS_LICENSE_SECRET || "aineos-default-dev-secret-do-not-use-in-prod";
}

function base32Encode(buf) {
  let bits = 0, value = 0, output = "";
  for (let i = 0; i < buf.length; i++) {
    value = (value << 8) | buf[i];
    bits += 8;
    while (bits >= 5) {
      output += BASE32_ALPHABET[(value >>> (bits - 5)) & 31];
      bits -= 5;
    }
  }
  if (bits > 0) {
    output += BASE32_ALPHABET[(value << (5 - bits)) & 31];
  }
  return output;
}

function base32Decode(str) {
  const clean = str.replace(/[^0-9a-zA-Z]/g, "");
  let bits = 0, value = 0;
  const bytes = [];
  for (let i = 0; i < clean.length; i++) {
    const idx = DECODE_MAP[clean[i]];
    if (idx === undefined) throw new Error(`Invalid Base32 character: ${clean[i]}`);
    value = (value << 5) | idx;
    bits += 5;
    if (bits >= 8) {
      bytes.push((value >>> (bits - 8)) & 255);
      bits -= 8;
    }
  }
  return Buffer.from(bytes);
}

/**
 * 签名载荷
 */
function signPayload(payloadJson, secret) {
  const hmac = crypto.createHmac("sha256", secret);
  hmac.update(payloadJson);
  return hmac.digest();
}

/**
 * 编码载荷为 License Key 字符串
 */
function encodeLicenseKey(payload, secret) {
  const payloadJson = JSON.stringify(payload);
  const payloadBuf = Buffer.from(payloadJson, "utf-8");
  const sig = signPayload(payloadJson, secret || getSecret());
  const combined = Buffer.concat([payloadBuf, sig]);
  const encoded = base32Encode(combined);
  // 每4字符分组
  const chunks = [];
  for (let i = 0; i < encoded.length; i += 4) {
    chunks.push(encoded.slice(i, i + 4));
  }
  return "AINEOS-" + chunks.join("-");
}

/**
 * 解码 License Key 字符串，返回 { valid, payload, error }
 */
function decodeLicenseKey(key, secret) {
  if (!KEY_FORMAT.test(key)) {
    return { valid: false, error: "无效的 License Key 格式" };
  }
  try {
    // 去掉 "AINEOS-" 前缀和所有分隔符
    const clean = key.replace(/^AINEOS-/, "").replace(/-/g, "");
    const combined = base32Decode(clean);
    if (combined.length < SIG_BYTES + 1) {
      return { valid: false, error: "License Key 数据不完整" };
    }
    const payloadBuf = combined.slice(0, combined.length - SIG_BYTES);
    const sig = combined.slice(combined.length - SIG_BYTES);
    const payloadJson = payloadBuf.toString("utf-8");
    const payload = JSON.parse(payloadJson);
    const expectedSig = signPayload(payloadJson, secret || getSecret());
    if (!crypto.timingSafeEqual(sig, expectedSig)) {
      return { valid: false, error: "License Key 签名验证失败" };
    }
    if (payload.v !== 1) {
      return { valid: false, error: "不支持的密钥版本" };
    }
    return { valid: true, payload };
  } catch (e) {
    return { valid: false, error: `解码失败: ${e.message}` };
  }
}

module.exports = { encodeLicenseKey, decodeLicenseKey, getSecret, KEY_FORMAT };
