'use client'

import { useEffect, useMemo, useState } from 'react'
import { resolveExplorerApiBase } from '@/libs/frontend-api-client/api-base'

export type WalletChain = {
  chainId: string
  chainIdDecimal?: number
  chainName: string
  rpcUrls: string[]
  blockExplorerUrls: string[]
  iconUrls?: string[]
  nativeCurrency: {
    name: string
    symbol: string
    decimals: number
  }
  shortName?: string
  infoURL?: string
  explorerApiUrl?: string
}

export type TokenListToken = {
  chainId: number
  address: string
  name: string
  symbol: string
  decimals: number
  logoURI?: string
  tags?: string[]
  extensions?: Record<string, unknown>
}

export type NetworksCatalog = {
  name?: string
  version?: {
    major?: number
    minor?: number
    patch?: number
  }
  defaultChainId?: number
  chains?: WalletChain[]
}

export type TokenListCatalog = {
  name?: string
  version?: {
    major?: number
    minor?: number
    patch?: number
  }
  keywords?: string[]
  tokens?: TokenListToken[]
}

export type CapabilitiesCatalog = {
  name?: string
  version?: {
    major?: number
    minor?: number
    patch?: number
  }
  timestamp?: string
  chainId?: number
  chainName?: string
  rpcUrl?: string
  explorerUrl?: string
  explorerApiUrl?: string
  generatedBy?: string
  walletSupport?: {
    walletAddEthereumChain?: boolean
    walletWatchAsset?: boolean
    notes?: string[]
  }
  http?: {
    supportedMethods?: string[]
    unsupportedMethods?: string[]
    notes?: string[]
  }
  tracing?: {
    supportedMethods?: string[]
    unsupportedMethods?: string[]
    notes?: string[]
  }
}

export type FetchMetadata = {
  source?: string | null
  lastModified?: string | null
}

interface AddToMetaMaskProps {
  initialNetworks?: NetworksCatalog | null
  initialTokenList?: TokenListCatalog | null
  initialCapabilities?: CapabilitiesCatalog | null
  initialNetworksMeta?: FetchMetadata | null
  initialTokenListMeta?: FetchMetadata | null
  initialCapabilitiesMeta?: FetchMetadata | null
}

type EthereumProvider = {
  request: (args: { method: string; params?: unknown }) => Promise<unknown>
}

const FALLBACK_CHAIN_138: WalletChain = {
  chainId: '0x8a',
  chainIdDecimal: 138,
  chainName: 'DeFi Oracle Meta Mainnet',
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  rpcUrls: ['https://rpc-http-pub.d-bis.org', 'https://rpc.d-bis.org', 'https://rpc2.d-bis.org'],
  blockExplorerUrls: ['https://explorer.d-bis.org', 'https://blockscout.defi-oracle.io'],
  iconUrls: ['https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png'],
  shortName: 'dbis',
  infoURL: 'https://explorer.d-bis.org',
  explorerApiUrl: 'https://explorer.d-bis.org/api/v2',
}

const FALLBACK_ETHEREUM: WalletChain = {
  chainId: '0x1',
  chainIdDecimal: 1,
  chainName: 'Ethereum Mainnet',
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  rpcUrls: ['https://eth.llamarpc.com', 'https://rpc.ankr.com/eth', 'https://ethereum.publicnode.com'],
  blockExplorerUrls: ['https://etherscan.io'],
  iconUrls: ['https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png'],
  shortName: 'eth',
  infoURL: 'https://ethereum.org',
}

const FALLBACK_ALL_MAINNET: WalletChain = {
  chainId: '0x9f2c4',
  chainIdDecimal: 651940,
  chainName: 'ALL Mainnet',
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  rpcUrls: ['https://mainnet-rpc.alltra.global'],
  blockExplorerUrls: ['https://alltra.global'],
  iconUrls: ['https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png'],
  shortName: 'all',
  infoURL: 'https://alltra.global',
}

const FEATURED_TOKEN_SYMBOLS = ['cUSDT', 'cUSDC', 'USDT', 'USDC', 'cXAUC', 'cXAUT']

/** npm-published Snap using open Snap permissions only; stable MetaMask still requires MetaMask’s install allowlist. */
const CHAIN138_OPEN_SNAP_ID = 'npm:chain138-open-snap' as const

const FALLBACK_CAPABILITIES_138: CapabilitiesCatalog = {
  name: 'Chain 138 RPC Capabilities',
  version: { major: 1, minor: 1, patch: 0 },
  timestamp: '2026-03-28T00:00:00Z',
  generatedBy: 'DBIS Explorer',
  chainId: 138,
  chainName: 'DeFi Oracle Meta Mainnet',
  rpcUrl: 'https://rpc-http-pub.d-bis.org',
  explorerUrl: 'https://explorer.d-bis.org',
  explorerApiUrl: 'https://explorer.d-bis.org/api/v2',
  walletSupport: {
    walletAddEthereumChain: true,
    walletWatchAsset: true,
    notes: [
      'MetaMask primarily relies on JSON-RPC correctness for balances, gas estimation, calls, and transaction submission.',
      'Explorer-served network metadata and token list metadata complement wallet UX but do not replace RPC method support.',
    ],
  },
  http: {
    supportedMethods: [
      'web3_clientVersion',
      'net_version',
      'eth_chainId',
      'eth_blockNumber',
      'eth_syncing',
      'eth_gasPrice',
      'eth_maxPriorityFeePerGas',
      'eth_feeHistory',
      'eth_estimateGas',
      'eth_getCode',
    ],
    unsupportedMethods: [],
    notes: [
      'eth_feeHistory is available for wallet fee estimation.',
      'eth_maxPriorityFeePerGas is exposed on the public RPC for wallet-grade fee suggestion compatibility.',
    ],
  },
  tracing: {
    supportedMethods: ['trace_block', 'trace_replayBlockTransactions'],
    unsupportedMethods: ['debug_traceBlockByNumber'],
    notes: [
      'TRACE support is enabled for explorer-grade indexing and internal transaction analysis.',
      'Debug tracing is intentionally not enabled on the public RPC tier.',
    ],
  },
}

function isTokenListToken(value: unknown): value is TokenListToken {
  if (!value || typeof value !== 'object') return false

  const candidate = value as Partial<TokenListToken>
  return (
    typeof candidate.chainId === 'number' &&
    typeof candidate.address === 'string' &&
    candidate.address.trim().length > 0 &&
    typeof candidate.name === 'string' &&
    typeof candidate.symbol === 'string' &&
    typeof candidate.decimals === 'number'
  )
}

function isCapabilitiesCatalog(value: unknown): value is CapabilitiesCatalog {
  if (!value || typeof value !== 'object') return false

  const candidate = value as Partial<CapabilitiesCatalog>
  return (
    typeof candidate.chainId === 'number' &&
    typeof candidate.chainName === 'string' &&
    candidate.chainName.trim().length > 0 &&
    typeof candidate.rpcUrl === 'string' &&
    candidate.rpcUrl.trim().length > 0
  )
}

function getApiBase() {
  return resolveExplorerApiBase({
    serverFallback: 'https://blockscout.defi-oracle.io',
  })
}

export function AddToMetaMask({
  initialNetworks = null,
  initialTokenList = null,
  initialCapabilities = null,
  initialNetworksMeta = null,
  initialTokenListMeta = null,
  initialCapabilitiesMeta = null,
}: AddToMetaMaskProps) {
  const [status, setStatus] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [networks, setNetworks] = useState<NetworksCatalog | null>(initialNetworks)
  const [tokenList, setTokenList] = useState<TokenListCatalog | null>(initialTokenList)
  const [capabilities, setCapabilities] = useState<CapabilitiesCatalog | null>(
    initialCapabilities || FALLBACK_CAPABILITIES_138,
  )
  const [networksMeta, setNetworksMeta] = useState<FetchMetadata | null>(initialNetworksMeta)
  const [tokenListMeta, setTokenListMeta] = useState<FetchMetadata | null>(initialTokenListMeta)
  const [capabilitiesMeta, setCapabilitiesMeta] = useState<FetchMetadata | null>(
    initialCapabilitiesMeta ||
      (initialCapabilities
        ? {
            source: 'explorer-api',
            lastModified: initialCapabilities.timestamp || null,
          }
        : {
            source: 'frontend-fallback',
            lastModified: FALLBACK_CAPABILITIES_138.timestamp || null,
          }),
  )

  const ethereum = typeof window !== 'undefined'
    ? (window as unknown as { ethereum?: EthereumProvider }).ethereum
    : undefined

  const apiBase = getApiBase().replace(/\/$/, '')
  const tokenListUrl = `${apiBase}/api/config/token-list`
  const networksUrl = `${apiBase}/api/config/networks`
  const capabilitiesUrl = `${apiBase}/api/config/capabilities`
  const staticCapabilitiesUrl =
    typeof window !== 'undefined'
      ? `${window.location.origin.replace(/\/$/, '')}/config/CHAIN138_RPC_CAPABILITIES.json`
      : `${apiBase}/config/CHAIN138_RPC_CAPABILITIES.json`

  useEffect(() => {
    let active = true
    let timer: ReturnType<typeof setTimeout> | null = null

    async function fetchJson(url: string) {
      const response = await fetch(url, {
        cache: 'no-store',
        headers: {
          'Cache-Control': 'no-cache',
        },
      })
      const json = response.ok ? await response.json() : null
      const meta: FetchMetadata = {
        source: response.headers.get('X-Config-Source') || 'explorer-api',
        lastModified: response.headers.get('Last-Modified'),
      }
      return { json, meta }
    }

    async function loadCatalogs() {
      try {
        const [networksResponse, tokenListResponse, capabilitiesResponse] = await Promise.all([
          fetchJson(networksUrl),
          fetchJson(tokenListUrl),
          fetchJson(capabilitiesUrl),
        ])

        let resolvedCapabilities = capabilitiesResponse
        if (!isCapabilitiesCatalog(resolvedCapabilities.json)) {
          const staticCapabilitiesResponse = await fetchJson(staticCapabilitiesUrl)
          if (isCapabilitiesCatalog(staticCapabilitiesResponse.json)) {
            resolvedCapabilities = {
              json: staticCapabilitiesResponse.json,
              meta: {
                source: staticCapabilitiesResponse.meta.source || 'public-static-fallback',
                lastModified: staticCapabilitiesResponse.meta.lastModified,
              },
            }
          } else {
            resolvedCapabilities = {
              json: FALLBACK_CAPABILITIES_138,
              meta: {
                source: 'frontend-fallback',
                lastModified: FALLBACK_CAPABILITIES_138.timestamp || null,
              },
            }
          }
        }

        if (!active) return
        setNetworks(networksResponse.json)
        setTokenList(tokenListResponse.json)
        setCapabilities(resolvedCapabilities.json)
        setNetworksMeta(networksResponse.meta)
        setTokenListMeta(tokenListResponse.meta)
        setCapabilitiesMeta(resolvedCapabilities.meta)
      } catch {
        if (!active) return
        setNetworks((current) => current)
        setTokenList((current) => current)
        setCapabilities((current) => current || FALLBACK_CAPABILITIES_138)
        setNetworksMeta((current) => current)
        setTokenListMeta((current) => current)
        setCapabilitiesMeta((current) =>
          current || {
            source: 'frontend-fallback',
            lastModified: FALLBACK_CAPABILITIES_138.timestamp || null,
          },
        )
      } finally {
        if (active) {
          timer = setTimeout(() => {
            void loadCatalogs()
          }, 60_000)
        }
      }
    }

    void loadCatalogs()

    return () => {
      active = false
      if (timer) clearTimeout(timer)
    }
  }, [capabilitiesUrl, networksUrl, staticCapabilitiesUrl, tokenListUrl])

  const catalogTokens = useMemo(
    () => (Array.isArray(tokenList?.tokens) ? tokenList.tokens.filter(isTokenListToken) : []),
    [tokenList],
  )

  const chains = useMemo(() => {
    const chainMap = new Map<number, WalletChain>()
    for (const chain of networks?.chains || []) {
      if (typeof chain.chainIdDecimal === 'number') {
        chainMap.set(chain.chainIdDecimal, chain)
      }
    }

    return {
      chain138: chainMap.get(138) || FALLBACK_CHAIN_138,
      ethereum: chainMap.get(1) || FALLBACK_ETHEREUM,
      allMainnet: chainMap.get(651940) || FALLBACK_ALL_MAINNET,
      total: (networks?.chains || []).length,
    }
  }, [networks])

  const featuredTokens = useMemo(() => {
    const tokenMap = new Map<string, TokenListToken>()
    for (const token of catalogTokens) {
      if (token.chainId !== 138) continue
      if (!FEATURED_TOKEN_SYMBOLS.includes(token.symbol)) continue
      tokenMap.set(token.symbol, token)
    }

    return FEATURED_TOKEN_SYMBOLS
      .map((symbol) => tokenMap.get(symbol))
      .filter((token): token is TokenListToken => !!token)
  }, [catalogTokens])

  const addChain = async (chain: WalletChain) => {
    setError(null)
    setStatus(null)

    if (!ethereum) {
      setError('MetaMask or another Web3 wallet is not installed.')
      return
    }

    try {
      await ethereum.request({
        method: 'wallet_addEthereumChain',
        params: [chain],
      })
      setStatus(`Added ${chain.chainName}. You can switch to it in your wallet.`)
    } catch (e) {
      const err = e as { code?: number; message?: string }
      if (err.code === 4902) {
        setStatus(`Added ${chain.chainName}. You can switch to it in your wallet.`)
      } else {
        setError(err.message || `Failed to add ${chain.chainName}.`)
      }
    }
  }

  const installOpenSnap = async () => {
    setError(null)
    setStatus(null)

    if (!ethereum) {
      setError('MetaMask or another Web3 wallet is not installed.')
      return
    }

    try {
      await ethereum.request({
        method: 'wallet_requestSnaps',
        params: { [CHAIN138_OPEN_SNAP_ID]: {} },
      })
      setStatus(
        `Installed or connected to ${CHAIN138_OPEN_SNAP_ID}. In MetaMask, open Snaps → Chain 138 Open for the home page (token list URL, network info).`,
      )
    } catch (e) {
      const err = e as { message?: string }
      const msg = err.message || ''
      const allowlistBlocked = /allowlist/i.test(msg)
      if (allowlistBlocked && msg) {
        setError(
          `${msg} Production MetaMask only installs allowlisted Snaps from npm. Use MetaMask Flask for unrestricted installs during development, or request allowlisting via MetaMask’s Snaps documentation.`,
        )
      } else {
        setError(
          msg ||
            `Could not install Snap. Enable MetaMask Snaps and ensure ${CHAIN138_OPEN_SNAP_ID} is published on npm.`,
        )
      }
    }
  }

  const watchToken = async (token: TokenListToken) => {
    setError(null)
    setStatus(null)

    if (!isTokenListToken(token)) {
      setError('Token metadata is incomplete right now. Refresh the page and try again.')
      return
    }

    if (!ethereum) {
      setError('MetaMask or another Web3 wallet is not installed.')
      return
    }

    try {
      const added = await ethereum.request({
        method: 'wallet_watchAsset',
        params: {
          type: 'ERC20',
          options: {
            address: token.address,
            symbol: token.symbol,
            decimals: token.decimals,
            image: token.logoURI,
          },
        },
      })

      setStatus(added ? `Added ${token.symbol} to your wallet.` : `${token.symbol} request was dismissed.`)
    } catch (e) {
      const err = e as { message?: string }
      setError(err.message || `Failed to add ${token.symbol}.`)
    }
  }

  const copyText = async (value: string, label: string) => {
    setError(null)
    setStatus(null)

    try {
      await navigator.clipboard.writeText(value)
      setStatus(`Copied ${label}.`)
    } catch {
      setError(`Could not copy ${label}.`)
    }
  }

  const tokenCount138 = catalogTokens.filter((token) => token.chainId === 138).length
  const metadataKeywordString = (tokenList?.keywords || []).join(', ')
  const supportedHTTPMethods = capabilities?.http?.supportedMethods || []
  const unsupportedHTTPMethods = capabilities?.http?.unsupportedMethods || []
  const supportedTraceMethods = capabilities?.tracing?.supportedMethods || []
  const displayedCapabilitiesUrl =
    capabilitiesMeta?.source === 'public-static-fallback' || capabilitiesMeta?.source === 'frontend-fallback'
      ? staticCapabilitiesUrl
      : capabilitiesUrl

  return (
    <div className="space-y-4 rounded-xl border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-800 sm:p-5">
      <h2 className="text-lg font-semibold">Add to MetaMask</h2>
      <p className="text-sm text-gray-600 dark:text-gray-400">
        The wallet tools now read the same explorer-served network catalog and token list that MetaMask can consume.
        That keeps chain metadata, token metadata, and optional extensions aligned with the live explorer API instead of
        relying on stale frontend-only defaults. MetaMask does not run built-in token detection on custom networks such
        as Chain 138: add the token list URL below under Settings → Security & privacy → Token lists so tokens and
        icons load automatically when you are on this chain.
      </p>

      <div className="grid gap-3 md:grid-cols-3">
        <button
          type="button"
          onClick={() => addChain(chains.chain138)}
          className="rounded bg-primary-600 px-4 py-2 text-sm font-medium text-white hover:bg-primary-700"
        >
          Add Chain 138
        </button>
        <button
          type="button"
          onClick={() => addChain(chains.ethereum)}
          className="rounded bg-gray-600 px-4 py-2 text-sm font-medium text-white hover:bg-gray-700"
        >
          Add Ethereum Mainnet
        </button>
        <button
          type="button"
          onClick={() => addChain(chains.allMainnet)}
          className="rounded bg-gray-600 px-4 py-2 text-sm font-medium text-white hover:bg-gray-700"
        >
          Add ALL Mainnet
        </button>
      </div>

      <div className="rounded-lg border border-primary-200 bg-primary-50/40 p-4 dark:border-primary-900 dark:bg-primary-950/20">
        <div className="text-sm font-semibold text-gray-900 dark:text-white">Chain 138 Open Snap</div>
        <p className="mt-2 text-sm text-gray-600 dark:text-gray-400">
          Optional MetaMask Snap that uses{' '}
          <span className="font-medium text-gray-800 dark:text-gray-200">only open Snap permissions</span> (minimal
          privileged APIs in the Snap itself).{' '}
          <span className="font-medium text-gray-800 dark:text-gray-200">Stable MetaMask</span> still only installs npm
          Snaps that appear on MetaMask&apos;s install allowlist; if install fails with &quot;not on the allowlist&quot;,
          use <span className="font-medium text-gray-800 dark:text-gray-200">MetaMask Flask</span> for development or apply
          for allowlisting. It adds in-wallet weekly reminders, Chain 138 transaction/signature hints, and the token list
          URL on the Snap home page. The package on npm is{' '}
          <code className="break-all rounded bg-gray-100 px-1 text-xs dark:bg-gray-900">{CHAIN138_OPEN_SNAP_ID}</code>
          — publish from the repo with <code className="break-all rounded bg-gray-100 px-1 text-xs dark:bg-gray-900">scripts/deployment/publish-chain138-open-snap.sh</code> after{' '}
          <code className="rounded bg-gray-100 px-1 text-xs dark:bg-gray-900">npm login</code>.
        </p>
        <button
          type="button"
          onClick={() => void installOpenSnap()}
          className="mt-3 rounded bg-primary-600 px-4 py-2 text-sm font-medium text-white hover:bg-primary-700"
        >
          Install Open Snap
        </button>
      </div>

      <div className="grid gap-4 lg:grid-cols-2">
        <div className="rounded-lg border border-gray-200 p-4 dark:border-gray-700">
          <div className="text-sm font-semibold text-gray-900 dark:text-white">Explorer-served MetaMask metadata</div>
          <div className="mt-3 space-y-2 text-sm text-gray-600 dark:text-gray-400">
            <p>Networks catalog: {chains.total > 0 ? `${chains.total} chains` : 'using frontend fallback values'}</p>
            <p>Chain 138 token entries: {tokenCount138}</p>
            <p>Networks source: {networksMeta?.source || 'unknown'}</p>
            <p>Token list source: {tokenListMeta?.source || 'unknown'}</p>
            {metadataKeywordString ? <p>Keywords: {metadataKeywordString}</p> : null}
          </div>
          <div className="mt-4 space-y-3">
            <div>
              <p className="mb-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Networks config URL</p>
              <code className="block break-all rounded bg-gray-100 p-2 text-xs dark:bg-gray-900">{networksUrl}</code>
              <div className="mt-2 flex flex-wrap gap-2">
                <button type="button" onClick={() => copyText(networksUrl, 'networks config URL')} className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-700">
                  Copy URL
                </button>
                <a href={networksUrl} target="_blank" rel="noopener noreferrer" className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-700">
                  Open JSON
                </a>
              </div>
            </div>
            <div>
              <p className="mb-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Capabilities URL</p>
              <code className="block break-all rounded bg-gray-100 p-2 text-xs dark:bg-gray-900">{displayedCapabilitiesUrl}</code>
              <div className="mt-2 flex flex-wrap gap-2">
                <button type="button" onClick={() => copyText(displayedCapabilitiesUrl, 'capabilities URL')} className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-700">
                  Copy URL
                </button>
                <a href={displayedCapabilitiesUrl} target="_blank" rel="noopener noreferrer" className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-700">
                  Open JSON
                </a>
              </div>
            </div>
            <div>
              <p className="mb-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Token list URL</p>
              <code className="block break-all rounded bg-gray-100 p-2 text-xs dark:bg-gray-900">{tokenListUrl}</code>
              <div className="mt-2 flex flex-wrap gap-2">
                <button type="button" onClick={() => copyText(tokenListUrl, 'token list URL')} className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-700">
                  Copy URL
                </button>
                <a href={tokenListUrl} target="_blank" rel="noopener noreferrer" className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-700">
                  Open JSON
                </a>
              </div>
            </div>
          </div>
        </div>

        <div className="rounded-lg border border-gray-200 p-4 dark:border-gray-700">
          <div className="text-sm font-semibold text-gray-900 dark:text-white">Chain 138 RPC capabilities</div>
          <p className="mt-2 text-sm text-gray-600 dark:text-gray-400">
            This capability matrix documents what public RPC methods wallets can rely on today, what tracing the explorer
            can use, and where MetaMask will still fall back because the public node does not expose every optional fee method.
          </p>
          <div className="mt-4 space-y-3 text-sm text-gray-600 dark:text-gray-400">
            <p>
              RPC endpoint:{' '}
              <span className="font-medium text-gray-900 dark:text-white">
                {capabilities?.rpcUrl || 'using published explorer fallback'}
              </span>
            </p>
            <p>
              Capabilities source:{' '}
              <span className="font-medium text-gray-900 dark:text-white">
                {capabilitiesMeta?.source || 'unknown'}
              </span>
            </p>
            <p>
              HTTP methods: {supportedHTTPMethods.length > 0 ? supportedHTTPMethods.join(', ') : 'metadata unavailable'}
            </p>
            <p>
              Missing wallet-facing methods:{' '}
              {unsupportedHTTPMethods.length > 0 ? unsupportedHTTPMethods.join(', ') : 'none listed'}
            </p>
            <p>
              Trace methods: {supportedTraceMethods.length > 0 ? supportedTraceMethods.join(', ') : 'metadata unavailable'}
            </p>
            {capabilities?.walletSupport?.notes?.map((note) => (
              <p key={note} className="text-xs">
                {note}
              </p>
            ))}
            {capabilities?.http?.notes?.map((note) => (
              <p key={note} className="text-xs">
                {note}
              </p>
            ))}
            {capabilitiesMeta?.lastModified ? (
              <p className="text-xs">
                Last modified: {new Date(capabilitiesMeta.lastModified).toLocaleString()}
              </p>
            ) : null}
          </div>
        </div>

        <div className="rounded-lg border border-gray-200 p-4 dark:border-gray-700">
          <div className="text-sm font-semibold text-gray-900 dark:text-white">Featured Chain 138 tokens</div>
          <p className="mt-2 text-sm text-gray-600 dark:text-gray-400">
            These tokens come from the explorer token list and use `wallet_watchAsset` so the wallet gets the same symbol,
            decimals, image, and optional token metadata that the explorer publishes.
          </p>
          <div className="mt-4 space-y-3">
            {featuredTokens.length === 0 ? (
              <p className="text-sm text-gray-600 dark:text-gray-400">Featured token metadata is not available right now.</p>
            ) : featuredTokens.map((token) => (
              <div key={token.address} className="rounded-lg border border-gray-200 p-3 dark:border-gray-700">
                <div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
                  <div>
                    <div className="text-sm font-semibold text-gray-900 dark:text-white">
                      {token.symbol} <span className="font-normal text-gray-500 dark:text-gray-400">({token.name})</span>
                    </div>
                    <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                      {token.address}
                    </div>
                    <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                      Decimals: {token.decimals}
                      {token.tags?.length ? ` • Tags: ${token.tags.join(', ')}` : ''}
                    </div>
                    {typeof token.extensions?.unitDescription === 'string' ? (
                      <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">{token.extensions.unitDescription}</div>
                    ) : null}
                  </div>
                  <button
                    type="button"
                    onClick={() => watchToken(token)}
                    className="rounded bg-primary-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-primary-700"
                  >
                    Add {token.symbol}
                  </button>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {status ? <p className="text-sm text-green-600 dark:text-green-400">{status}</p> : null}
      {error ? <p className="text-sm text-red-600 dark:text-red-400">{error}</p> : null}
    </div>
  )
}
