import {
  digitsFaToEn,
  digitsArToEn,
  digitsEnToFa,
  addCommas,
  numberToWords as ptNumberToWords,
  verifyCardNumber,
  isShebaValid,
} from '@persian-tools/persian-tools'

/**
 * Convert Persian/Arabic digits to English digits
 */
export const persianToEnglish = (str: string): string => {
  if (!str) return ''
  // First convert Arabic, then Persian
  return digitsFaToEn(digitsArToEn(str))
}

/**
 * Only digits (0-9): convert Persian/Arabic to English then strip non-digits.
 * Use for: card number, account number, sheba, mobile, etc.
 */
export const toEnglishDigitsOnly = (str: string): string => {
  return persianToEnglish(str || '').replace(/[^\d]/g, '')
}

/**
 * Numeric with optional decimal: convert Persian/Arabic to English then keep only digits and dot.
 * Use for: amount, price, quantity, etc.
 */
export const toEnglishNumeric = (str: string): string => {
  return persianToEnglish(str || '').replace(/[^\d.]/g, '')
}

/**
 * Convert English digits to Persian digits
 */
export const englishToPersian = (str: string): string => {
  if (!str) return ''
  return digitsEnToFa(str)
}

/**
 * Format amount with thousands separators
 */
export const formatAmount = (value: string | number): string => {
  const num = typeof value === 'string' ? parseFloat(persianToEnglish(value)) : value
  if (isNaN(num)) return '0'
  return addCommas(num)
}

/**
 * Convert number to Persian words
 */
export const numberToWords = (num: number | string): string => {
  const n = typeof num === 'string' ? parseFloat(persianToEnglish(num)) : num
  if (isNaN(n) || n === 0) return ''
  try {
    const result = ptNumberToWords(Math.floor(Math.abs(n)))
    return typeof result === 'string' ? result : ''
  } catch {
    return ''
  }
}

/**
 * Format metal purity (0–1 scale) for display: e.g. 0.925 → ".۹۲۵", 0.999 → ".۹۹۹"
 */
export const formatPurity = (p: number | string): string => {
  const n = typeof p === 'string' ? parseFloat(persianToEnglish(p)) : Number(p)
  if (Number.isNaN(n)) return '—'
  if (n >= 1) return digitsEnToFa('1')
  const s = n.toFixed(4).replace(/0+$/, '').replace(/\.$/, '')
  const display = s.startsWith('0.') ? '.' + s.slice(2) : s
  return digitsEnToFa(display)
}

/** طول استاندارد شماره کارت بانکی ایران (بدون خط تیره) */
export const CARD_NUMBER_LENGTH = 16

/** طول استاندارد شبا بدون پیش‌وند IR (۲۴ رقم) */
export const SHEBA_LENGTH = 24

/**
 * اعتبارسنجی شماره کارت بانکی ایران: ۱۶ رقم + الگوی Luhn
 * ورودی: فقط ارقام (بدون خط تیره یا فاصله)
 */
export const validateCardNumber = (card: string): boolean => {
  const digits = toEnglishDigitsOnly(card).replace(/\D/g, '')
  if (digits.length !== CARD_NUMBER_LENGTH) return false
  return verifyCardNumber(Number(digits)) === true
}

/**
 * اعتبارسنجی شبا (IBAN ایران): IR + ۲۴ رقم با چک دیجیت ISO 7064 Mod 97
 * ورودی: ۲۴ رقم (پیش‌وند IR در ورودی نادیده گرفته می‌شود)
 */
export const validateSheba = (sheba: string): boolean => {
  const digits = toEnglishDigitsOnly(sheba).replace(/\D/g, '').replace(/^IR/i, '')
  if (digits.length !== SHEBA_LENGTH) return false
  return isShebaValid('IR' + digits)
}

/**
 * Convert amount to words with currency
 */
export const amountToWords = (amount: number | string, currency: 'rial' | 'toman' = 'rial'): string => {
  const num = typeof amount === 'string' ? parseFloat(persianToEnglish(amount)) : amount
  if (isNaN(num) || num === 0) return ''
  
  const words = numberToWords(num)
  const currencyLabel = currency === 'toman' ? 'تومان' : 'ریال'
  
  return words ? `${words} ${currencyLabel}` : ''
}

