// src/lib/numberToWords.js
// Small, dependency-free integer-to-English-words converter used to print
// the "Amount in words" line on generated invoices. Only needs to handle
// plain positive amounts (invoice totals), not negatives or fractions.

const ONES = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',
  'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
const TENS = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
const SCALES = ['', 'Thousand', 'Million', 'Billion', 'Trillion'];

function threeDigitsToWords(n) {
  let out = '';
  if (n >= 100) {
    out += `${ONES[Math.floor(n / 100)]} Hundred`;
    n %= 100;
    if (n) out += ' ';
  }
  if (n >= 20) {
    out += TENS[Math.floor(n / 10)];
    if (n % 10) out += `-${ONES[n % 10]}`;
  } else if (n > 0) {
    out += ONES[n];
  }
  return out;
}

function integerToWords(value) {
  const n = Math.round(Math.abs(Number(value) || 0));
  if (n === 0) return 'Zero';

  const groups = [];
  let remaining = n;
  while (remaining > 0) {
    groups.push(remaining % 1000);
    remaining = Math.floor(remaining / 1000);
  }

  const parts = [];
  for (let i = groups.length - 1; i >= 0; i--) {
    if (groups[i] === 0) continue;
    const words = threeDigitsToWords(groups[i]);
    parts.push(SCALES[i] ? `${words} ${SCALES[i]}` : words);
  }
  return parts.join(' ');
}

const CURRENCY_WORDS = {
  TZS: 'Tanzanian Shillings',
  USD: 'US Dollars'
};

// e.g. amountInWords(1227500, 'TZS') -> "One Million Two Hundred Twenty-Seven
// Thousand Five Hundred Tanzanian Shillings Only"
function amountInWords(amount, currency) {
  const label = CURRENCY_WORDS[currency] || currency || '';
  return `${integerToWords(amount)} ${label} Only`.replace(/\s+/g, ' ').trim();
}

module.exports = { integerToWords, amountInWords };
