export interface GruCatalogPosture {
  isGru: boolean
  isWrappedTransport: boolean
  isX402Ready: boolean
  isForwardCanonical: boolean
  currencyCode?: string
  activeVersion?: string
  forwardVersion?: string
}

interface GruCatalogEntry extends GruCatalogPosture {
  symbol: string
  addresses?: string[]
}

const GRU_X402_READY_SYMBOLS = new Set([
  'CAUDC',
  'CCADC',
  'CCHFC',
  'CEURC',
  'CEURT',
  'CGBPC',
  'CGBPT',
  'CJPYC',
  'CUSDC',
  'CUSDT',
  'CXAUC',
  'CXAUT',
])

const GRU_CATALOG: GruCatalogEntry[] = [
  {
    symbol: 'cUSDC',
    currencyCode: 'USD',
    isGru: true,
    isWrappedTransport: false,
    isX402Ready: true,
    isForwardCanonical: true,
    activeVersion: 'v1',
    forwardVersion: 'v2',
    addresses: [
      '0xf22258f57794cc8e06237084b353ab30fffa640b',
      '0x219522c60e83dee01fc5b0329d6fa8fd84b9d13d',
    ],
  },
  {
    symbol: 'cUSDT',
    currencyCode: 'USD',
    isGru: true,
    isWrappedTransport: false,
    isX402Ready: true,
    isForwardCanonical: true,
    activeVersion: 'v1',
    forwardVersion: 'v2',
    addresses: [
      '0x93e66202a11b1772e55407b32b44e5cd8eda7f22',
      '0x9fbfab33882efe0038daa608185718b772ee5660',
    ],
  },
  ...['cAUDC', 'cCADC', 'cCHFC', 'cEURC', 'cEURT', 'cGBPC', 'cGBPT', 'cJPYC', 'cXAUC', 'cXAUT'].map((symbol) => ({
    symbol,
    currencyCode: symbol.slice(1, 4).replace('XAU', 'XAU'),
    isGru: true,
    isWrappedTransport: false,
    isX402Ready: true,
    isForwardCanonical: true,
    forwardVersion: 'v2',
  })),
]

function normalizeSymbol(symbol?: string | null): string {
  return (symbol || '').trim().toUpperCase()
}

function normalizeAddress(address?: string | null): string {
  return (address || '').trim().toLowerCase()
}

export function getGruCatalogPosture(input: {
  symbol?: string | null
  address?: string | null
  tags?: string[] | null
}): GruCatalogPosture | null {
  const symbol = normalizeSymbol(input.symbol)
  const address = normalizeAddress(input.address)
  const tags = (input.tags || []).map((tag) => tag.toLowerCase())

  const matched = GRU_CATALOG.find((entry) => {
    if (symbol && normalizeSymbol(entry.symbol) === symbol) return true
    if (address && entry.addresses?.includes(address)) return true
    return false
  })

  if (matched) {
    return {
      isGru: true,
      isWrappedTransport: matched.isWrappedTransport,
      isX402Ready: matched.isX402Ready,
      isForwardCanonical: matched.isForwardCanonical,
      currencyCode: matched.currencyCode,
      activeVersion: matched.activeVersion,
      forwardVersion: matched.forwardVersion,
    }
  }

  const looksWrapped = symbol.startsWith('CW')
  const looksGru = looksWrapped || symbol.startsWith('C') || tags.includes('compliant') || tags.includes('wrapped') || tags.includes('bridge')
  if (!looksGru) return null

  return {
    isGru: true,
    isWrappedTransport: looksWrapped || tags.includes('wrapped') || tags.includes('bridge'),
    isX402Ready: GRU_X402_READY_SYMBOLS.has(symbol),
    isForwardCanonical: GRU_X402_READY_SYMBOLS.has(symbol) && !looksWrapped,
  }
}
