import type { MessageKey } from '../i18n/en' const MAX_MAJOR = 1_000_000 // demo ceiling; backend enforces its own limits /** Validate a SAR major-unit amount string. Returns an i18n error key or undefined. */ export function validateAmount(raw: string): MessageKey | undefined { const s = raw.trim() if (!s) return 'error.amountEmpty' if (!/^\d*\.?\d*$/.test(s) || s === '.') return 'error.amountInvalid' const n = Number(s) if (!Number.isFinite(n)) return 'error.amountInvalid' if (n < 0) return 'error.amountNegative' if (n === 0) return 'error.amountZero' if (n > MAX_MAJOR) return 'error.amountTooLarge' if (!/^\d+(\.\d{1,2})?$/.test(s)) return 'error.amountInvalid' // SAR = 2 decimals max return undefined } /** Saudi IBAN: "SA" + 22 digits (24 chars), ISO 13616 mod-97 check == 1. */ export function isValidSaudiIban(raw: string): boolean { const s = raw.replace(/\s+/g, '').toUpperCase() if (!/^SA\d{22}$/.test(s)) return false const rearranged = s.slice(4) + s.slice(0, 4) let rem = 0 for (const ch of rearranged) { const val = ch >= 'A' && ch <= 'Z' ? String(ch.charCodeAt(0) - 55) : ch for (const d of val) rem = (rem * 10 + (d.charCodeAt(0) - 48)) % 97 } return rem === 1 } export function validateIban(raw: string): MessageKey | undefined { if (!raw.trim()) return 'error.payeeEmpty' return isValidSaudiIban(raw) ? undefined : 'error.ibanInvalid' } export function validateMerchant(raw: string): MessageKey | undefined { return raw.trim() ? undefined : 'error.merchantEmpty' }