"use client"

import * as React from 'react';

import { cn } from '../../../lib/utils';

export interface TokenIconProps extends React.HTMLAttributes<HTMLDivElement> {
  symbol: string
  variant?: 'branded' | 'mono'
  size?: number
  network?: string
  address?: string
}

/**
 * Get all available token symbols from @web3icons/react
 * Uses dynamic import to avoid bundling all icons
 */
export async function getAllTokenSymbols(): Promise<string[]> {
  try {
    const { tokenIcons } = await import('@web3icons/react')
    return Object.keys(tokenIcons).map(key => 
      key.replace(/^Token/, '').replace(/_/g, '-')
    ).sort()
  } catch {
    return []
  }
}

/**
 * Search tokens by symbol
 */
export async function searchTokens(query: string): Promise<string[]> {
  const allTokens = await getAllTokenSymbols()
  const lowerQuery = query.toLowerCase()
  return allTokens.filter(symbol => 
    symbol.toLowerCase().includes(lowerQuery)
  )
}

/**
 * Get popular tokens grouped by category
 */
export interface TokenCategory {
  name: string
  tokens: string[]
}

export async function getTokensByCategory(): Promise<TokenCategory[]> {
  const allTokens = await getAllTokenSymbols()
  
  // Top tokens by market cap
  const topTokens = ['BTC', 'ETH', 'USDT', 'BNB', 'SOL', 'USDC', 'XRP', 'DOGE', 'ADA', 'TRX']
    .filter(t => allTokens.includes(t))
  
  const stablecoins = ['USDT', 'USDC', 'BUSD', 'DAI', 'TUSD', 'USDP', 'GUSD', 'FRAX']
    .filter(t => allTokens.includes(t))
  
  const defi = ['UNI', 'AAVE', 'MKR', 'CRV', 'CAKE', 'SUSHI', 'BAL', 'COMP', 'YFI', 'SNX', 'LINK']
    .filter(t => allTokens.includes(t))
  
  const layer1 = ['ETH', 'BNB', 'SOL', 'ADA', 'AVAX', 'DOT', 'ATOM', 'NEAR', 'ALGO', 'FTM']
    .filter(t => allTokens.includes(t))
  
  const layer2 = ['MATIC', 'OP', 'ARB', 'IMX', 'LRC', 'METIS']
    .filter(t => allTokens.includes(t))
  
  const memeCoins = ['DOGE', 'SHIB', 'PEPE', 'FLOKI', 'ELON', 'BONK']
    .filter(t => allTokens.includes(t))
  
  return [
    { name: 'Top 10', tokens: topTokens },
    { name: 'Stablecoins', tokens: stablecoins },
    { name: 'DeFi', tokens: defi },
    { name: 'Layer 1', tokens: layer1 },
    { name: 'Layer 2', tokens: layer2 },
    { name: 'Meme Coins', tokens: memeCoins },
  ].filter(cat => cat.tokens.length > 0)
}

export type TokenSymbol = string

// Dynamic import for @web3icons/react tokens
const tokenIconCache = new Map<string, React.ComponentType<any>>()

async function getTokenIcon(symbol: string): Promise<React.ComponentType<any> | null> {
  const normalizedSymbol = symbol.toUpperCase().replace(/[^A-Z0-9]/g, '_')
  const componentName = `Token${normalizedSymbol}`

  if (tokenIconCache.has(componentName)) {
    return tokenIconCache.get(componentName)!
  }

  try {
    const module = await import('@web3icons/react')
    const Component = (module as any)[componentName]
    if (Component) {
      tokenIconCache.set(componentName, Component)
      return Component
    }
  } catch (e) {
    // Token not found
  }

  return null
}

export function TokenIcon({
  symbol,
  variant = 'branded',
  size = 24,
  className,
  network,
  address,
  ...props
}: TokenIconProps) {
  const [IconComponent, setIconComponent] = React.useState<React.ComponentType<any> | null>(null)
  const [_loading, setLoading] = React.useState(true)

  React.useEffect(() => {
    let mounted = true

    getTokenIcon(symbol).then((component) => {
      if (mounted) {
        setIconComponent(() => component)
        setLoading(false)
      }
    })

    return () => {
      mounted = false
    }
  }, [symbol])

  // Pre-compute fallback values
  const fallbackFontSize = Math.max(8, size * 0.4)
  const truncatedSymbol = symbol?.slice(0, 3) || '?'

  return (
    <div
      className={cn("inline-flex items-center justify-center flex-shrink-0", className)}
      style={{ width: size, height: size }}
      {...props}
    >
      {IconComponent ? (
        <IconComponent
          variant={variant}
          size={size}
        />
      ) : (
        // Fallback: show symbol as text
        <span
          className="text-muted-foreground font-medium uppercase"
          style={{ fontSize: fallbackFontSize }}
        >
          {truncatedSymbol}
        </span>
      )}
    </div>
  )
}
