/** Round to 2 decimal places (currency-safe for display and API payloads). */
export function roundMoney(value: number): number {
  if (!Number.isFinite(value)) {
    return 0;
  }
  return Math.round((value + Number.EPSILON) * 100) / 100;
}

const MONEY_FIELD_KEYS = new Set([
  "final_price",
  "amount_due_now",
  "total_class_value",
  "total_program_price",
  "discount_amount",
  "per_unit_price",
  "price",
  "amount",
  "tax",
  "subtotal",
  "total",
]);

function shouldRoundKey(key: string): boolean {
  return MONEY_FIELD_KEYS.has(key);
}

/** Round known monetary fields in form submission steps and class_details. */
export function sanitizeMoneyInFormSteps(
  steps: Array<Record<string, unknown>>
): Array<Record<string, unknown>> {
  return steps.map((step) => {
    const next: Record<string, unknown> = { ...step };

    for (const [key, val] of Object.entries(next)) {
      if (key === "class_details" && val && typeof val === "object" && !Array.isArray(val)) {
        next.class_details = sanitizeMoneyObject(val as Record<string, unknown>);
        continue;
      }
      if (shouldRoundKey(key) && (typeof val === "number" || (typeof val === "string" && val !== ""))) {
        const n = typeof val === "number" ? val : parseFloat(val);
        if (Number.isFinite(n)) {
          next[key] = roundMoney(n);
        }
      }
    }

    return next;
  });
}

function sanitizeMoneyObject(obj: Record<string, unknown>): Record<string, unknown> {
  const next: Record<string, unknown> = { ...obj };
  for (const [key, val] of Object.entries(next)) {
    if (shouldRoundKey(key) && (typeof val === "number" || (typeof val === "string" && val !== ""))) {
      const n = typeof val === "number" ? val : parseFloat(val);
      if (Number.isFinite(n)) {
        next[key] = roundMoney(n);
      }
    }
  }
  return next;
}
