/**
 * ABN (Australian Business Number) validation and formatting utilities
 *
 * Based on the official ABN validation algorithm:
 * https://abr.business.gov.au/Help/AbnFormat
 *
 * Algorithm:
 *   1. Subtract 1 from the first (left-most) digit
 *   2. Multiply each of the 11 digits by its positional weight:
 *      [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
 *   3. Sum all 11 products
 *   4. If sum mod 89 === 0 → valid ABN
 *
 * Worked example — 51 824 753 556:
 *   Step 1: 41 824 753 556
 *   Step 2: 4×10 + 1×1 + 8×3 + 2×5 + 4×7 + 7×9 + 5×11 + 3×13 + 5×15 + 5×17 + 6×19
 *   Step 3: = 534
 *   Step 4: 534 % 89 = 0  ✓
 */

const ABN_WEIGHTS = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19] as const;

/**
 * Strip an ABN string down to just its 11 digits.
 * Returns the cleaned string (may be empty / wrong length if input is garbage).
 */
export function cleanABN(abn: string): string {
  return abn.replace(/\D/g, '');
}

/**
 * Validate an ABN using the modulus-89 checksum algorithm.
 *
 * Accepts any string — spaces, dashes, dots are stripped first.
 * Returns `true` only when the input is exactly 11 digits AND the checksum passes.
 */
export function validateABN(abn: string): boolean {
  const digits = cleanABN(abn);

  if (digits.length !== 11) return false;

  // Convert to number array, subtract 1 from first digit
  const d = digits.split('').map(Number);
  d[0] -= 1;

  // Weighted sum
  let sum = 0;
  for (let i = 0; i < 11; i++) {
    sum += d[i] * ABN_WEIGHTS[i];
  }

  return sum % 89 === 0;
}

/** Convenience alias used by the API route. */
export const isValidABN = validateABN;

/**
 * Format an 11-digit ABN into the standard display format: XX XXX XXX XXX
 * Returns empty string if input doesn't contain exactly 11 digits.
 */
export function formatABN(abn: string): string {
  const d = cleanABN(abn);
  if (d.length !== 11) return '';
  return `${d.slice(0, 2)} ${d.slice(2, 5)} ${d.slice(5, 8)} ${d.slice(8)}`;
}

/**
 * Validate + format in one call.
 */
export function validateAndFormatABN(abn: string): {
  valid: boolean;
  cleaned: string;
  formatted: string;
} {
  const cleaned = cleanABN(abn);
  const valid = validateABN(cleaned);
  return {
    valid,
    cleaned,
    formatted: valid ? formatABN(cleaned) : '',
  };
}

/* ── Test ABNs from ABR documentation ── */
export const TEST_ABNS = {
  /** Valid — passes checksum */
  VALID: '51 824 753 556',
  /** Invalid — fails checksum (last digit changed) */
  INVALID: '51 824 753 557',
  /** Suppressed ABN (details hidden on ABR) */
  SUPPRESSED: '34 241 177 887',
} as const;
