import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useReadContracts } from 'wagmi'
import { fetchProducts, Product } from '@/lib/api/fundmarket'
import { Token } from '@/lib/api/tokens'
import { getDynamicOverride, getDynamicOverrideByName } from '@/lib/contracts/registry'

const ERC20_DECIMALS_ABI = [
  { name: 'decimals', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint8' }] },
] as const

function productToToken(p: Product): Token {
  return {
    symbol: p.tokenSymbol,
    name: p.name,
    decimals: p.decimals ?? 18,
    iconUrl: p.iconUrl,
    contractAddress: p.contractAddress ?? '',
    chainId: p.chainId ?? 0,
    tokenType: p.token_role === 'stablecoin' ? 'stablecoin' : 'yield-token',
  }
}

/**
 * Global token list hook — fetches once, cached 5 min.
 * All components share the same ['token-list'] React Query cache.
 * Each token has onChainDecimals (live from chain) with decimals as fallback.
 */
export function useTokenList() {
  const { data: products = [], isLoading: isProductsLoading } = useQuery({
    queryKey: ['token-list'],
    queryFn: () => fetchProducts(true),
    staleTime: 5 * 60 * 1000,
  })

  const baseTokens: Token[] = useMemo(
    () => products
      .filter(p => p.token_role === 'stablecoin' || p.token_role === 'yt_token')
      .map(productToToken),
    [products]
  )

  // 批量读取每个 token 的链上 decimals，按 token 配置的 chainId 发起请求
  // 仅包含有合约地址的 token，记录原始索引以便回写
  const tokensWithAddress = useMemo(
    () => baseTokens
      .map((t, i) => ({ t, i }))
      .filter(({ t }) => !!t.contractAddress),
    [baseTokens]
  )

  const decimalsContracts = useMemo(
    () => tokensWithAddress.map(({ t }) => ({
      address: t.contractAddress as `0x${string}`,
      abi: ERC20_DECIMALS_ABI,
      functionName: 'decimals' as const,
      chainId: t.chainId,
    })),
    [tokensWithAddress]
  )

  const { data: onChainData } = useReadContracts({
    contracts: decimalsContracts,
    query: { enabled: decimalsContracts.length > 0 },
  })

  // 将链上精度回写到对应 token（按原始索引匹配，避免过滤后索引错位）
  const onChainDecimalsMap = new Map<number, number>()
  tokensWithAddress.forEach(({ i }, j) => {
    if (onChainData?.[j]?.status === 'success') {
      onChainDecimalsMap.set(i, Number(onChainData[j].result))
    }
  })

  // 合并链上精度 + 合约地址（contractAddress 为空时回退到注册表）
  const tokens: Token[] = baseTokens.map((t, i) => {
    // DB 未配置地址/chainId 时，先按精确 chainId 查注册表，再按 name 跨链搜索兜底
    let contractAddress = t.contractAddress || getDynamicOverride(t.symbol, t.chainId) || ''
    let chainId = t.chainId
    if (!contractAddress) {
      const found = getDynamicOverrideByName(t.symbol)
      if (found) {
        contractAddress = found.address
        chainId = found.chainId  // 同时修正 chainId
      }
    }
    const onChainDecimals = onChainDecimalsMap.has(i) ? onChainDecimalsMap.get(i) : undefined
    return { ...t, contractAddress, chainId, onChainDecimals }
  })

  const stablecoins = tokens.filter(t => t.tokenType === 'stablecoin')
  const yieldTokens = tokens.filter(t => t.tokenType === 'yield-token')
  const bySymbol: Record<string, Token> = Object.fromEntries(tokens.map(t => [t.symbol, t]))

  return { tokens, stablecoins, yieldTokens, bySymbol, isLoading: isProductsLoading }
}
