/**
 * Calculates the net amount due and clamped balance for a student fee.
 * @param {object} fee Fee fields; missing monetary fields default to zero.
 * @returns {{total_due: number, outstanding: number, paid: number}} Fee balance.
 */
function outstandingForFee(fee) {
  const amount = Number(fee.amount) || 0;
  const fine = Number(fee.fine_amount) || 0;
  const discount = Number(fee.discount_amount) || 0;
  const paid = Number(fee.paid_amount) || 0;
  const total = amount + fine - discount;
  return { total_due: total, outstanding: Math.max(0, total - paid), paid };
}

/**
 * Calculates the net amount due and clamped balance for an invoice.
 * @param {object} invoice Invoice fields; discount and paid values may be absent.
 * @returns {{net_due: number, outstanding: number, paid: number}} Invoice balance.
 */
function outstandingForInvoice(invoice) {
  const total = Number(invoice.total) || 0;
  const discount = Number(invoice.discount_amount) || 0;
  const paid = Number(invoice.paid_amount) || 0;
  const net = total - discount;
  return { net_due: net, outstanding: Math.max(0, net - paid), paid };
}

/**
 * Maps a paid amount against a due amount to the fee status enum.
 * @param {number} totalDue Due amount; @param {number} paid Amount received.
 * @returns {'pending'|'partial'|'paid'} The corresponding payment status.
 */
function statusForPaid(totalDue, paid) {
  if (paid <= 0) return 'pending';
  if (paid >= totalDue) return 'paid';
  return 'partial';
}

// Legacy amount - paid_amount rollups remain in dashboard.controller.js
// and transfers.controller.js; amount - paid_amount - discount_amount +
// fine_amount checks remain in offboarding.controller.js and
// OffboardingService.js. Client-side formulas remain out of scope here.

module.exports = { outstandingForFee, outstandingForInvoice, statusForPaid };
