/**
 * 合约错误处理工具
 */

const USER_REJECTION_PATTERNS = [
  'User rejected',
  'User denied',
  'user rejected',
  'rejected the request',
]

/** 判断是否为用户拒绝交易 */
export function isUserRejection(err: unknown): boolean {
  const msg = getErrorMessage(err)
  return USER_REJECTION_PATTERNS.some(pattern => msg.includes(pattern))
}

/** 解析合约 revert 原因 */
export function parseContractError(err: unknown, fallback = 'Transaction failed'): string {
  if (!err) return fallback
  const msg = getErrorMessage(err)
  const match =
    msg.match(/reverted with reason string '(.+?)'/) ||
    msg.match(/execution reverted: (.+?)(?:\n|$)/) ||
    msg.match(/reverted: (.+?)(?:\n|$)/)
  if (match) return match[1]
  const short = getShortMessage(err)
  if (short) return short
  return fallback
}

/** 统一 catch 块处理 */
export function handleContractCatchError(
  err: unknown,
  fallback: string,
  setError: (msg: string) => void,
  setStatus: (status: string) => void,
): void {
  if (isUserRejection(err)) {
    setError('Transaction cancelled')
    setStatus('idle')
  } else {
    setError(parseContractError(err, fallback))
    setStatus('error')
  }
}

/** 校验金额是否为合法正数 */
export function isValidAmount(amount: string): boolean {
  const n = Number(amount)
  return !isNaN(n) && isFinite(n) && n > 0
}

/** 安全解析浮点数，NaN/Infinity → 0 */
export function safeParseFloat(value: string | number): number {
  const n = typeof value === 'string' ? parseFloat(value) : value
  if (isNaN(n) || !isFinite(n)) return 0
  return n
}

function getErrorMessage(err: unknown): string {
  if (err instanceof Error) return err.message
  if (typeof err === 'object' && err !== null) {
    const e = err as Record<string, unknown>
    if (typeof e.message === 'string') return e.message
    if (typeof e.shortMessage === 'string') return e.shortMessage
  }
  return String(err)
}

function getShortMessage(err: unknown): string | undefined {
  if (typeof err === 'object' && err !== null) {
    const e = err as Record<string, unknown>
    if (typeof e.shortMessage === 'string') return e.shortMessage
  }
  return undefined
}
