/** Base simultaneous opens at key 1 (x10). Each +1 key adds +1 open until x20, then continues +1 per key. */
export const BASE_MAX_OPENS = 10;

/** Keys 1–10 → next key always costs this many opens. */
export const OPENS_PER_KEY_EARLY = 100;

/** From key 11 onward: cost = OPENS_PER_KEY_EARLY × (keys - 9). */
export const ESCALATION_KEY_THRESHOLD = 11;

export function maxOpensForKeys(keys, openBonus = 0) {
  const k = Math.max(1, keys);
  const bonus = Math.max(0, Math.floor(Number(openBonus) || 0));
  return k + (BASE_MAX_OPENS - 1) + bonus;
}

export function opensRequiredForNextKey(keys, keyOpenReduction = 0) {
  const k = Math.max(1, keys);
  const base =
    k < ESCALATION_KEY_THRESHOLD
      ? OPENS_PER_KEY_EARLY
      : OPENS_PER_KEY_EARLY * (k - (ESCALATION_KEY_THRESHOLD - 2));
  const reduction = Math.max(0, Number(keyOpenReduction) || 0);
  return Math.max(1, base - reduction);
}

export function serializeKeyProgress(progress, keyOpenReduction = 0, openBonus = 0) {
  const keys = progress?.keys ?? 1;
  const opensSinceLastKey = progress?.opensSinceLastKey ?? 0;
  const totalOpens = progress?.totalOpens ?? 0;
  const opensRequired = opensRequiredForNextKey(keys, keyOpenReduction);
  return {
    keys,
    maxOpens: maxOpensForKeys(keys, openBonus),
    opensSinceLastKey,
    opensRequired,
    totalOpens,
  };
}

/**
 * Apply opens to progress state. Returns updated fields + keysGained.
 */
export function applyOpens(progress, count, keyOpenReduction = 0) {
  let keys = Math.max(1, progress.keys ?? 1);
  let opensSinceLastKey = progress.opensSinceLastKey ?? 0;
  let totalOpens = progress.totalOpens ?? 0;
  let keysGained = 0;

  opensSinceLastKey += count;
  totalOpens += count;

  while (opensSinceLastKey >= opensRequiredForNextKey(keys, keyOpenReduction)) {
    opensSinceLastKey -= opensRequiredForNextKey(keys, keyOpenReduction);
    keys += 1;
    keysGained += 1;
  }

  return { keys, opensSinceLastKey, totalOpens, keysGained };
}

/**
 * Rebuild keys/opensSinceLastKey from a lifetime open count (backfill).
 * Prestige reduction is ignored here — backfill uses base costs.
 */
export function progressFromTotalOpens(totalOpens) {
  let keys = 1;
  let remaining = totalOpens;

  while (remaining >= opensRequiredForNextKey(keys, 0)) {
    remaining -= opensRequiredForNextKey(keys, 0);
    keys += 1;
  }

  return {
    keys,
    opensSinceLastKey: remaining,
    totalOpens,
  };
}

export async function getOrCreateProgress(tx, userId, caseId) {
  const existing = await tx.caseKeyProgress.findUnique({
    where: { userId_caseId: { userId, caseId } },
  });
  if (existing) return existing;

  return tx.caseKeyProgress.create({
    data: { userId, caseId, keys: 1, opensSinceLastKey: 0, totalOpens: 0 },
  });
}
