export function loadBillingConfig() {
  // 默认按人民币分（CNY cents）计费；仅当 H5_USE_BACKEND_COST=1 时才用上游 USD 成本换算。
  const useBackendCost = process.env.H5_USE_BACKEND_COST === '1';
  // 成本模式下的毛利倍数：最终扣费 = 上游真实成本(USD) × 汇率 × marginMultiplier。
  // 默认 1（按成本价卖，零毛利）——启用 useBackendCost 时务必显式设置目标倍数。
  const marginMultiplier = Number(process.env.H5_MARGIN_MULTIPLIER ?? 1);
  return {
    useBackendCost,
    usdCnyRate: Number(process.env.H5_USD_CNY_RATE ?? 7.2),
    marginMultiplier: Number.isFinite(marginMultiplier) && marginMultiplier > 0 ? marginMultiplier : 1,
    inputCentsPer1k: Number(process.env.H5_BILL_INPUT_CENTS_PER_1K ?? 2),
    outputCentsPer1k: Number(process.env.H5_BILL_OUTPUT_CENTS_PER_1K ?? 6),
    minBillCents: Number(process.env.H5_MIN_BILL_CENTS ?? 1),
  };
}

export function normalizeTokenState(raw) {
  if (!raw || typeof raw !== 'object') {
    return {
      inputTokens: 0,
      outputTokens: 0,
      totalTokens: 0,
      accumulatedInputTokens: 0,
      accumulatedOutputTokens: 0,
      accumulatedTotalTokens: 0,
      accumulatedCost: null,
    };
  }
  return {
    inputTokens: Number(raw.inputTokens ?? raw.input_tokens ?? 0),
    outputTokens: Number(raw.outputTokens ?? raw.output_tokens ?? 0),
    totalTokens: Number(raw.totalTokens ?? raw.total_tokens ?? 0),
    accumulatedInputTokens: Number(
      raw.accumulatedInputTokens ?? raw.accumulated_input_tokens ?? raw.inputTokens ?? 0,
    ),
    accumulatedOutputTokens: Number(
      raw.accumulatedOutputTokens ?? raw.accumulated_output_tokens ?? raw.outputTokens ?? 0,
    ),
    accumulatedTotalTokens: Number(
      raw.accumulatedTotalTokens ?? raw.accumulated_total_tokens ?? raw.totalTokens ?? 0,
    ),
    accumulatedCost:
      raw.accumulatedCost ?? raw.accumulated_cost ?? null,
  };
}

export function computeDeltaCostCents(previous, current, config = loadBillingConfig()) {
  const prevCost =
    previous?.lastAccumulatedCost == null ? null : Number(previous.lastAccumulatedCost);
  const currCost =
    current.accumulatedCost == null ? null : Number(current.accumulatedCost);

  // 成本模式：按上游真实成本(USD)增量 × 汇率 × 毛利倍数扣费，自动跟随 provider/模型，
  // 无需为每个模型重调 token 单价。仅在上游确实回传 accumulatedCost 时生效；否则回退 token 路径。
  const margin = config.marginMultiplier ?? 1;
  if (config.useBackendCost && prevCost != null && currCost != null && currCost >= prevCost) {
    const deltaUsd = currCost - prevCost;
    if (deltaUsd <= 0) return 0;
    return Math.max(config.minBillCents, Math.ceil(deltaUsd * config.usdCnyRate * 100 * margin));
  }
  if (config.useBackendCost && prevCost == null && currCost != null && currCost > 0) {
    return Math.max(config.minBillCents, Math.ceil(currCost * config.usdCnyRate * 100 * margin));
  }

  // 默认/回退路径：按 Token 增量 × 人民币单价（分/1k tokens）扣费。
  // 注意：flat 单价与 provider 真实成本脱钩（对 DeepSeek 中继约 20× 超收），
  // 生产应启用 useBackendCost + marginMultiplier 走成本模式，详见 docs/h5-metering-gateway.md。

  const prevIn = Number(previous?.lastInputTokens ?? 0);
  const prevOut = Number(previous?.lastOutputTokens ?? 0);
  const deltaIn = Math.max(0, current.accumulatedInputTokens - prevIn);
  const deltaOut = Math.max(0, current.accumulatedOutputTokens - prevOut);
  if (deltaIn === 0 && deltaOut === 0) return 0;

  const raw =
    (deltaIn / 1000) * config.inputCentsPer1k + (deltaOut / 1000) * config.outputCentsPer1k;
  if (raw <= 0) return 0;
  return Math.max(config.minBillCents, Math.ceil(raw));
}
