'use client'

import { useCallback, useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/router'
import { Card, Table, Address } from '@/libs/frontend-ui-primitives'
import Link from 'next/link'
import {
  addressesApi,
  AddressInfo,
  AddressTokenBalance,
  AddressTokenTransfer,
  TransactionSummary,
} from '@/services/api/addresses'
import {
  encodeMethodCalldata,
  callSimpleReadMethod,
  contractsApi,
  type ContractMethod,
  type ContractProfile,
} from '@/services/api/contracts'
import { formatTimestamp, formatTokenAmount, formatWeiAsEth } from '@/utils/format'
import { DetailRow } from '@/components/common/DetailRow'
import EntityBadge from '@/components/common/EntityBadge'
import {
  isWatchlistEntry,
  readWatchlistFromStorage,
  writeWatchlistToStorage,
  normalizeWatchlistAddress,
} from '@/utils/watchlist'
import PageIntro from '@/components/common/PageIntro'
import PaginationControls from '@/components/common/PaginationControls'
import SectionTabs, { type SectionTab } from '@/components/common/SectionTabs'
import GruStandardsCard from '@/components/common/GruStandardsCard'
import ContractCodeWorkspace from '@/components/explorer/ContractCodeWorkspace'
import ContractVerificationCallout from '@/components/explorer/ContractVerificationCallout'
import { getGruStandardsProfileSafe, type GruStandardsProfile } from '@/services/api/gru'
import { getGruExplorerMetadata } from '@/services/api/gruExplorerData'
import { tokenAggregationApi, type TokenAggregationTokenSnapshot } from '@/services/api/tokenAggregation'
import { estimateNativeUsdValue, getNativeAssetDescriptor, getNativeAssetMarketSafe } from '@/services/api/nativeAssetPricing'

function isValidAddress(value: string) {
  return /^0x[a-fA-F0-9]{40}$/.test(value)
}

function formatUsd(value: string | number | undefined): string {
  if (value == null) return 'Unavailable'
  const numeric = typeof value === 'number' ? value : Number(value)
  if (!Number.isFinite(numeric)) return 'Unavailable'
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    maximumFractionDigits: numeric >= 100 ? 0 : 2,
  }).format(numeric)
}

export default function AddressDetailPage() {
  const router = useRouter()
  const address = typeof router.query.address === 'string' ? router.query.address : ''
  const isValidAddressParam = address !== '' && isValidAddress(address)
  const chainId = parseInt(process.env.NEXT_PUBLIC_CHAIN_ID || '138')

  const [addressInfo, setAddressInfo] = useState<AddressInfo | null>(null)
  const [transactions, setTransactions] = useState<TransactionSummary[]>([])
  const [tokenBalances, setTokenBalances] = useState<AddressTokenBalance[]>([])
  const [tokenTransfers, setTokenTransfers] = useState<AddressTokenTransfer[]>([])
  const [contractProfile, setContractProfile] = useState<ContractProfile | null>(null)
  const [gruProfile, setGruProfile] = useState<GruStandardsProfile | null>(null)
  const [watchlistEntries, setWatchlistEntries] = useState<string[]>([])
  const [methodResults, setMethodResults] = useState<Record<string, { loading: boolean; value?: string; error?: string }>>({})
  const [methodInputs, setMethodInputs] = useState<Record<string, string[]>>({})
  const [tokenMarkets, setTokenMarkets] = useState<Record<string, TokenAggregationTokenSnapshot>>({})
  const [nativeAssetPriceUsd, setNativeAssetPriceUsd] = useState<number | undefined>()
  const [loading, setLoading] = useState(true)
  const [activeTab, setActiveTab] = useState<'contract' | 'balances' | 'transfers' | 'transactions'>('balances')
  const [balancePage, setBalancePage] = useState(1)
  const [transferPage, setTransferPage] = useState(1)
  const [transactionPage, setTransactionPage] = useState(1)
  const pageSize = 8

  const loadAddressInfo = useCallback(async () => {
    try {
      const { ok, data } = await addressesApi.getSafe(chainId, address)
      if (!ok) {
        setAddressInfo(null)
        setContractProfile(null)
        return
      }
      setAddressInfo(data ?? null)
      if (data?.is_contract) {
        const contractResult = await contractsApi.getProfileSafe(address)
        const resolvedContractProfile = contractResult.ok ? contractResult.data : null
        setContractProfile(resolvedContractProfile)
        const gruResult = await getGruStandardsProfileSafe({
          address,
          symbol: data?.token_contract?.symbol || data?.token_contract?.name || '',
          tags: data?.tags || [],
          contractProfile: resolvedContractProfile,
        })
        setGruProfile(gruResult.ok ? gruResult.data : null)
      } else {
        setContractProfile(null)
        setGruProfile(null)
      }
    } catch (error) {
      console.error('Failed to load address info:', error)
      setAddressInfo(null)
      setContractProfile(null)
      setGruProfile(null)
    }
  }, [chainId, address])

  const loadTransactions = useCallback(async () => {
    try {
      const [transactionsResult, balancesResult, transfersResult] = await Promise.all([
        addressesApi.getTransactionsSafe(chainId, address, 1, 20),
        addressesApi.getTokenBalancesSafe(address),
        addressesApi.getTokenTransfersSafe(address, 1, 10),
      ])
      const { ok, data } = transactionsResult
      setTransactions(ok ? data : [])
      setTokenBalances(balancesResult.ok ? balancesResult.data : [])
      setTokenTransfers(transfersResult.ok ? transfersResult.data : [])
    } catch (error) {
      console.error('Failed to load transactions:', error)
      setTransactions([])
      setTokenBalances([])
      setTokenTransfers([])
    } finally {
      setLoading(false)
    }
  }, [chainId, address])

  useEffect(() => {
    if (!router.isReady || !address) {
      setLoading(router.isReady ? false : true)
      if (router.isReady && !address) {
        setAddressInfo(null)
        setTransactions([])
      }
      return
    }
    if (!isValidAddressParam) {
      setLoading(false)
      setAddressInfo(null)
      setTransactions([])
      return
    }
    loadAddressInfo()
    loadTransactions()
  }, [address, isValidAddressParam, loadAddressInfo, loadTransactions, router.isReady])

  useEffect(() => {
    if (typeof window === 'undefined') {
      return
    }

    try {
      setWatchlistEntries(readWatchlistFromStorage(window.localStorage))
    } catch {
      setWatchlistEntries([])
    }
  }, [])

  useEffect(() => {
    let active = true

    const tokenAddresses = [
      ...(addressInfo?.token_contract?.address ? [addressInfo.token_contract.address] : []),
      ...tokenBalances.map((balance) => balance.token_address),
      ...tokenTransfers.map((transfer) => transfer.token_address),
    ].filter((candidate, index, values): candidate is string => typeof candidate === 'string' && candidate.trim().length > 0 && values.indexOf(candidate) === index)

    tokenAggregationApi.getTokensByAddressSafe(chainId, tokenAddresses).then(({ data }) => {
      if (!active) return
      setTokenMarkets(Object.fromEntries(data.map((snapshot) => [snapshot.address.toLowerCase(), snapshot])))
    }).catch(() => {
      if (active) {
        setTokenMarkets({})
      }
    })

    return () => {
      active = false
    }
  }, [addressInfo?.token_contract?.address, chainId, tokenBalances, tokenTransfers])

  useEffect(() => {
    let active = true

    getNativeAssetMarketSafe(chainId).then(({ data }) => {
      if (!active) return
      setNativeAssetPriceUsd(data?.market?.priceUsd)
    }).catch(() => {
      if (active) {
        setNativeAssetPriceUsd(undefined)
      }
    })

    return () => {
      active = false
    }
  }, [chainId])

  const watchlistAddress = normalizeWatchlistAddress(addressInfo?.address || address)
  const isSavedToWatchlist = watchlistAddress
    ? isWatchlistEntry(watchlistEntries, watchlistAddress)
    : false

  const handleWatchlistToggle = () => {
    if (!watchlistAddress || typeof window === 'undefined') {
      return
    }

    setWatchlistEntries((current) => {
      const next = isSavedToWatchlist
        ? current.filter((entry) => entry.toLowerCase() !== watchlistAddress.toLowerCase())
        : [...current, watchlistAddress]

      try {
        writeWatchlistToStorage(window.localStorage, next)
      } catch {}

      return next
    })
  }

  const handleReadMethod = async (method: ContractMethod) => {
    const values = methodInputs[method.signature] || method.inputs.map(() => '')
    setMethodResults((current) => ({
      ...current,
      [method.signature]: { loading: true },
    }))
    try {
      const value = await callSimpleReadMethod(address, method, values)
      setMethodResults((current) => ({
        ...current,
        [method.signature]: { loading: false, value },
      }))
    } catch (error) {
      setMethodResults((current) => ({
        ...current,
        [method.signature]: {
          loading: false,
          error: error instanceof Error ? error.message : 'Read call failed',
        },
      }))
    }
  }

  const handleMethodInputChange = (signature: string, index: number, value: string) => {
    setMethodInputs((current) => {
      const next = [...(current[signature] || [])]
      next[index] = value
      return {
        ...current,
        [signature]: next,
      }
    })
  }

  const handleWriteMethod = async (method: ContractMethod) => {
    const provider = typeof window !== 'undefined'
      ? (window as unknown as { ethereum?: { request: (args: { method: string; params?: unknown[] }) => Promise<unknown> } }).ethereum
      : undefined
    if (!provider) {
      setMethodResults((current) => ({
        ...current,
        [method.signature]: { loading: false, error: 'A wallet provider is required for write methods.' },
      }))
      return
    }

    const values = methodInputs[method.signature] || method.inputs.map(() => '')
    setMethodResults((current) => ({
      ...current,
      [method.signature]: { loading: true },
    }))

    try {
      const data = encodeMethodCalldata(method, values)
      const accounts = (await provider.request({ method: 'eth_requestAccounts' })) as string[]
      const from = accounts?.[0]
      if (!from) {
        throw new Error('No wallet account was returned by the provider.')
      }
      const txHash = await provider.request({
        method: 'eth_sendTransaction',
        params: [
          {
            from,
            to: address,
            data,
          },
        ],
      })

      setMethodResults((current) => ({
        ...current,
        [method.signature]: { loading: false, value: typeof txHash === 'string' ? txHash : 'Transaction submitted' },
      }))
    } catch (error) {
      setMethodResults((current) => ({
        ...current,
        [method.signature]: {
          loading: false,
          error: error instanceof Error ? error.message : 'Write call failed',
        },
      }))
    }
  }

  const transactionColumns = [
    {
      header: 'Hash',
      accessor: (tx: TransactionSummary) => (
        <Link href={`/transactions/${tx.hash}`} className="text-primary-600 hover:underline">
          <Address address={tx.hash} truncate showCopy={false} />
        </Link>
      ),
    },
    {
      header: 'Block',
      accessor: (tx: TransactionSummary) => (
        <Link href={`/blocks/${tx.block_number}`} className="text-primary-600 hover:underline">
          {tx.block_number}
        </Link>
      ),
    },
    {
      header: 'To',
      accessor: (tx: TransactionSummary) => tx.to_address ? (
        <Link href={`/addresses/${tx.to_address}`} className="text-primary-600 hover:underline">
          <Address address={tx.to_address} truncate showCopy={false} />
        </Link>
      ) : 'Contract Creation',
    },
    {
      header: 'Value',
      accessor: (tx: TransactionSummary) => {
        const nativeValueUsd = estimateNativeUsdValue(tx.value, nativeAssetPriceUsd)
        return (
          <div className="space-y-1 text-sm">
            <div>{formatWeiAsEth(tx.value)}</div>
            <div className="text-xs text-gray-500 dark:text-gray-400">
              {nativeValueUsd != null ? `Current USD: ${formatUsd(nativeValueUsd)}` : 'Current USD unavailable'}
            </div>
          </div>
        )
      },
    },
    {
      header: 'Status',
      accessor: (tx: TransactionSummary) => (
        <span className={tx.status === 1 ? 'text-green-600' : 'text-red-600'}>
          {tx.status === 1 ? 'Success' : 'Failed'}
        </span>
      ),
    },
  ]

  const tokenBalanceColumns = [
    {
      header: 'Token',
      accessor: (balance: AddressTokenBalance) => {
        const gruMetadata = getGruExplorerMetadata({
          address: balance.token_address,
          symbol: balance.token_symbol,
        })
        return (
          <div className="space-y-1">
            <div className="flex flex-wrap items-center gap-2">
              {balance.token_address ? (
                <Link href={`/tokens/${balance.token_address}`} className="text-primary-600 hover:underline">
                  {balance.token_symbol || balance.token_name || <Address address={balance.token_address} truncate showCopy={false} />}
                </Link>
              ) : (
                <span>{balance.token_symbol || balance.token_name || 'Token'}</span>
              )}
              {gruMetadata ? <EntityBadge label="GRU" tone="success" /> : null}
              {gruMetadata?.x402Ready ? <EntityBadge label="x402 ready" tone="info" /> : null}
              {gruMetadata?.iso20022Ready ? <EntityBadge label="ISO-20022" tone="info" /> : null}
            </div>
            {balance.token_name && balance.token_symbol && (
              <div className="text-xs text-gray-500 dark:text-gray-400">{balance.token_name}</div>
            )}
          </div>
        )
      },
    },
    {
      header: 'Balance',
      accessor: (balance: AddressTokenBalance) => (
        formatTokenAmount(balance.value, balance.token_decimals, balance.token_symbol)
      ),
    },
    {
      header: 'Supply',
      accessor: (balance: AddressTokenBalance) => (
        balance.total_supply
          ? formatTokenAmount(balance.total_supply, balance.token_decimals, balance.token_symbol)
          : 'N/A'
      ),
    },
    {
      header: 'Current Price',
      accessor: (balance: AddressTokenBalance) => {
        const market = tokenMarkets[balance.token_address.toLowerCase()]?.market
        return (
          <div className="space-y-1 text-sm">
            <div>{formatUsd(market?.priceUsd)}</div>
            <div className="text-xs text-gray-500 dark:text-gray-400">
              Liq. {formatUsd(market?.liquidityUsd)}
            </div>
          </div>
        )
      },
    },
  ]

  const tokenTransferColumns = [
    {
      header: 'Token',
      accessor: (transfer: AddressTokenTransfer) => {
        const gruMetadata = getGruExplorerMetadata({
          address: transfer.token_address,
          symbol: transfer.token_symbol,
        })
        return (
          <div className="space-y-1">
            <div className="flex flex-wrap items-center gap-2">
              <div className="font-medium text-gray-900 dark:text-white">{transfer.token_symbol || transfer.token_name || 'Token'}</div>
              {gruMetadata ? <EntityBadge label="GRU" tone="success" /> : null}
              {gruMetadata?.x402Ready ? <EntityBadge label="x402 ready" tone="info" /> : null}
              {gruMetadata?.iso20022Ready ? <EntityBadge label="ISO-20022" tone="info" /> : null}
              {gruMetadata?.transportActiveVersion ? <EntityBadge label={`cW public-network ${gruMetadata.transportActiveVersion}`} tone="warning" /> : null}
            </div>
            {transfer.token_address && (
              <Link href={`/tokens/${transfer.token_address}`} className="text-primary-600 hover:underline">
                <Address address={transfer.token_address} truncate showCopy={false} />
              </Link>
            )}
          </div>
        )
      },
    },
    {
      header: 'Direction',
      accessor: (transfer: AddressTokenTransfer) =>
        transfer.to_address.toLowerCase() === address.toLowerCase() ? 'Incoming' : 'Outgoing',
    },
    {
      header: 'Counterparty',
      accessor: (transfer: AddressTokenTransfer) => {
        const incoming = transfer.to_address.toLowerCase() === address.toLowerCase()
        const counterparty = incoming ? transfer.from_address : transfer.to_address
        const label = incoming ? transfer.from_label : transfer.to_label
        return (
          <Link href={`/addresses/${counterparty}`} className="text-primary-600 hover:underline">
            {label || <Address address={counterparty} truncate showCopy={false} />}
          </Link>
        )
      },
    },
    {
      header: 'Amount',
      accessor: (transfer: AddressTokenTransfer) => (
        formatTokenAmount(transfer.value, transfer.token_decimals, transfer.token_symbol)
      ),
    },
    {
      header: 'When',
      accessor: (transfer: AddressTokenTransfer) => formatTimestamp(transfer.timestamp),
    },
    {
      header: 'Current Price',
      accessor: (transfer: AddressTokenTransfer) => {
        const market = tokenMarkets[transfer.token_address.toLowerCase()]?.market
        return (
          <div className="space-y-1 text-sm">
            <div>{formatUsd(market?.priceUsd)}</div>
            <div className="text-xs text-gray-500 dark:text-gray-400">
              Liq. {formatUsd(market?.liquidityUsd)}
            </div>
          </div>
        )
      },
    },
  ]

  const incomingTransactions = transactions.filter(
    (tx) => tx.to_address?.toLowerCase() === address.toLowerCase()
  ).length
  const outgoingTransactions = transactions.filter(
    (tx) => tx.from_address.toLowerCase() === address.toLowerCase()
  ).length
  const incomingTokenTransfers = tokenTransfers.filter(
    (transfer) => transfer.to_address.toLowerCase() === address.toLowerCase()
  ).length
  const outgoingTokenTransfers = tokenTransfers.filter(
    (transfer) => transfer.from_address.toLowerCase() === address.toLowerCase()
  ).length
  const gruBalanceCount = tokenBalances.filter((balance) =>
    Boolean(getGruExplorerMetadata({ address: balance.token_address, symbol: balance.token_symbol })),
  ).length
  const gruTransferCount = tokenTransfers.filter((transfer) =>
    Boolean(getGruExplorerMetadata({ address: transfer.token_address, symbol: transfer.token_symbol })),
  ).length
  const nativeAssetSymbol = getNativeAssetDescriptor(chainId).symbol
  const nativeBalanceUsd = estimateNativeUsdValue(addressInfo?.balance, nativeAssetPriceUsd)
  const tabs: SectionTab<typeof activeTab>[] = [
    ...(addressInfo?.is_contract ? [{ id: 'contract' as const, label: 'Contract' }] : []),
    { id: 'balances', label: 'Balances', count: tokenBalances.length },
    { id: 'transfers', label: 'Transfers', count: tokenTransfers.length },
    { id: 'transactions', label: 'Transactions', count: transactions.length },
  ]
  const balancePageCount = Math.max(1, Math.ceil(tokenBalances.length / pageSize))
  const transferPageCount = Math.max(1, Math.ceil(tokenTransfers.length / pageSize))
  const transactionPageCount = Math.max(1, Math.ceil(transactions.length / pageSize))
  const pagedTokenBalances = useMemo(
    () => tokenBalances.slice((balancePage - 1) * pageSize, balancePage * pageSize),
    [balancePage, tokenBalances],
  )
  const pagedTokenTransfers = useMemo(
    () => tokenTransfers.slice((transferPage - 1) * pageSize, transferPage * pageSize),
    [transferPage, tokenTransfers],
  )
  const pagedTransactions = useMemo(
    () => transactions.slice((transactionPage - 1) * pageSize, transactionPage * pageSize),
    [transactionPage, transactions],
  )

  useEffect(() => {
    setBalancePage(1)
    setTransferPage(1)
    setTransactionPage(1)
    setActiveTab(addressInfo?.is_contract ? 'contract' : 'balances')
  }, [address, addressInfo?.is_contract])

  return (
    <div className="container mx-auto px-4 py-6 sm:py-8">
      <PageIntro
        eyebrow="Address Detail"
        title={addressInfo?.label || 'Address'}
        description="Inspect a Chain 138 address, move into related transactions, and save important counterparties into the shared explorer watchlist."
        actions={[
          { href: '/addresses', label: 'All addresses' },
          { href: '/watchlist', label: 'Open watchlist' },
          { href: '/search', label: 'Search explorer' },
        ]}
      />

      <div className="mb-6 flex flex-wrap gap-3 text-sm">
        <Link href="/addresses" className="text-primary-600 hover:underline">
          Back to addresses
        </Link>
        {(addressInfo?.address || address) && (
          <Link href={`/search?q=${encodeURIComponent(addressInfo?.address || address)}`} className="text-primary-600 hover:underline">
            Search this address
          </Link>
        )}
        {watchlistAddress && router.isReady && !loading && (
          <button
            type="button"
            onClick={handleWatchlistToggle}
            className="rounded-full border border-gray-300 px-3 py-1 text-sm font-medium text-gray-700 transition hover:border-primary-400 hover:text-primary-700 dark:border-gray-600 dark:text-gray-300 dark:hover:text-primary-300"
          >
            {isSavedToWatchlist ? 'Remove from watchlist' : 'Add to watchlist'}
          </button>
        )}
      </div>

      {!router.isReady || loading ? (
        <Card className="mb-6">
          <p className="text-sm text-gray-600 dark:text-gray-400">Loading address...</p>
        </Card>
      ) : !isValidAddressParam ? (
        <Card className="mb-6">
          <p className="text-sm text-gray-600 dark:text-gray-400">Invalid address. Please use a full 42-character 0x-prefixed address.</p>
          <div className="mt-4 flex flex-wrap gap-3 text-sm">
            <Link href="/addresses" className="text-primary-600 hover:underline">
              Back to addresses →
            </Link>
            <Link href="/search" className="text-primary-600 hover:underline">
              Search the explorer →
            </Link>
          </div>
        </Card>
      ) : !addressInfo ? (
        <Card className="mb-6">
          <p className="text-sm text-gray-600 dark:text-gray-400">Address not found.</p>
          <div className="mt-4 flex flex-wrap gap-3 text-sm">
            <Link href="/addresses" className="text-primary-600 hover:underline">
              Browse recent addresses →
            </Link>
            <Link href="/watchlist" className="text-primary-600 hover:underline">
              Open watchlist →
            </Link>
          </div>
        </Card>
      ) : (
        <>
          <Card title="Address Information" className="mb-6">
            <dl className="space-y-4">
              <DetailRow label="Address">
                <Address address={addressInfo.address} />
              </DetailRow>
              {addressInfo.balance && (
                <DetailRow label="Coin Balance">
                  {formatWeiAsEth(addressInfo.balance)}
                  {nativeBalanceUsd != null ? ` (${formatUsd(nativeBalanceUsd)})` : ''}
                </DetailRow>
              )}
              <DetailRow label="Current Native Asset Price">
                {nativeAssetPriceUsd != null ? `${formatUsd(nativeAssetPriceUsd)} per ${nativeAssetSymbol}` : 'Unavailable'}
              </DetailRow>
              <DetailRow label="Watchlist">
                {isSavedToWatchlist ? 'Saved for quick access' : 'Not saved yet'}
              </DetailRow>
              <DetailRow label="Verification">
                <div className="flex flex-wrap gap-2">
                  <EntityBadge label={addressInfo.is_contract ? (addressInfo.is_verified ? 'verified' : 'contract') : 'eoa'} />
                  {contractProfile?.source_verified ? <EntityBadge label="source available" tone="success" /> : null}
                  {contractProfile?.abi_available ? <EntityBadge label="abi available" tone="info" /> : null}
                  {addressInfo.token_contract ? <EntityBadge label={addressInfo.token_contract.type || 'token'} tone="info" /> : null}
                </div>
              </DetailRow>
              {addressInfo.token_contract && (
                <DetailRow label="Token Contract">
                  <div className="space-y-2">
                    <div>
                      {addressInfo.token_contract.symbol || addressInfo.token_contract.name || 'Token contract'} · {addressInfo.token_contract.type || 'Token'}
                    </div>
                    <Link href={`/tokens/${addressInfo.token_contract.address}`} className="text-primary-600 hover:underline">
                      Open token detail →
                    </Link>
                  </div>
                </DetailRow>
              )}
              {addressInfo.tags.length > 0 && (
                <DetailRow label="Tags" valueClassName="flex flex-wrap gap-2">
                    {addressInfo.tags.map((tag, i) => (
                      <EntityBadge key={i} label={tag} className="px-2 py-1 text-[11px]" />
                    ))}
                </DetailRow>
              )}
              <DetailRow label="Transactions">{addressInfo.transaction_count}</DetailRow>
              <DetailRow label="Tokens">{addressInfo.token_count}</DetailRow>
              <DetailRow label="Type">{addressInfo.is_contract ? 'Contract' : 'EOA'}</DetailRow>
              <DetailRow label="Recent Activity">
                {incomingTransactions} incoming / {outgoingTransactions} outgoing txs
              </DetailRow>
              {addressInfo.internal_transaction_count != null && (
                <DetailRow label="Internal Calls">{addressInfo.internal_transaction_count}</DetailRow>
              )}
              {addressInfo.logs_count != null && (
                <DetailRow label="Indexed Logs">{addressInfo.logs_count}</DetailRow>
              )}
              <DetailRow label="Token Flow">
                {incomingTokenTransfers} incoming / {outgoingTokenTransfers} outgoing token transfers
                {addressInfo.token_transfer_count != null ? ` · ${addressInfo.token_transfer_count} total indexed` : ''}
              </DetailRow>
              {addressInfo.creation_transaction_hash && (
                <DetailRow label="Created In">
                  <Link href={`/transactions/${addressInfo.creation_transaction_hash}`} className="text-primary-600 hover:underline">
                    <Address address={addressInfo.creation_transaction_hash} truncate showCopy={false} />
                  </Link>
                </DetailRow>
              )}
            </dl>
          </Card>

          {addressInfo.is_contract ? (
            <ContractVerificationCallout address={addressInfo.address} verified={Boolean(addressInfo.is_verified)} />
          ) : null}

          <SectionTabs tabs={tabs} activeTab={activeTab} onChange={setActiveTab} className="mb-6" />

          {activeTab === 'contract' && addressInfo.is_contract && (
            <Card title="Contract Profile" className="mb-6">
              <dl className="space-y-4">
                <DetailRow label="Interaction Surface">
                  <div className="flex flex-wrap gap-2">
                    {contractProfile?.has_custom_methods_read ? <EntityBadge label="read methods" tone="success" /> : <EntityBadge label="read unknown" /> }
                    {contractProfile?.has_custom_methods_write ? <EntityBadge label="write methods" tone="warning" /> : <EntityBadge label="write unknown" /> }
                  </div>
                </DetailRow>
                <DetailRow label="Proxy Type">
                  {contractProfile?.proxy_type || 'Not reported'}
                </DetailRow>
                <DetailRow label="Source Status">
                  <div className="space-y-2">
                    <div>{contractProfile?.source_status_text || 'Verification metadata was not available from the public explorer.'}</div>
                    <div className="flex flex-wrap gap-2">
                      <EntityBadge
                        label={contractProfile?.source_verified ? 'verified source' : 'source unavailable'}
                        tone={contractProfile?.source_verified ? 'success' : 'warning'}
                      />
                      <EntityBadge
                        label={contractProfile?.abi_available ? 'abi present' : 'abi unavailable'}
                        tone={contractProfile?.abi_available ? 'info' : 'warning'}
                      />
                    </div>
                  </div>
                </DetailRow>
                <DetailRow label="Lifecycle">
                  {contractProfile?.is_self_destructed ? 'Self-destructed' : 'Active'}
                </DetailRow>
                {(contractProfile?.contract_name ||
                  contractProfile?.compiler_version ||
                  contractProfile?.license_type ||
                  contractProfile?.evm_version ||
                  contractProfile?.optimization_enabled != null) && (
                  <DetailRow label="Build Metadata">
                    <div className="space-y-2 text-sm text-gray-700 dark:text-gray-300">
                      {contractProfile?.contract_name ? <div>Name: {contractProfile.contract_name}</div> : null}
                      {contractProfile?.compiler_version ? <div>Compiler: {contractProfile.compiler_version}</div> : null}
                      {contractProfile?.license_type ? <div>License: {contractProfile.license_type}</div> : null}
                      {contractProfile?.evm_version ? <div>EVM target: {contractProfile.evm_version}</div> : null}
                      {contractProfile?.optimization_enabled != null ? (
                        <div>
                          Optimization: {contractProfile.optimization_enabled ? 'Enabled' : 'Disabled'}
                          {contractProfile.optimization_runs != null ? ` · ${contractProfile.optimization_runs} runs` : ''}
                        </div>
                      ) : null}
                    </div>
                  </DetailRow>
                )}
                <DetailRow label="Implementations">
                  {contractProfile?.implementations && contractProfile.implementations.length > 0 ? (
                    <div className="space-y-2">
                      {contractProfile.implementations.map((implementation) => (
                        <Link key={implementation} href={`/addresses/${implementation}`} className="block text-primary-600 hover:underline">
                          <Address address={implementation} truncate showCopy={false} />
                        </Link>
                      ))}
                    </div>
                  ) : (
                    'No implementation addresses were reported.'
                  )}
                </DetailRow>
                {contractProfile?.constructor_arguments && (
                  <DetailRow label="Constructor Args">
                    <code className="block break-all rounded bg-gray-50 p-2 text-xs dark:bg-gray-950">
                      {contractProfile.constructor_arguments}
                    </code>
                  </DetailRow>
                )}
                {contractProfile?.read_methods && contractProfile.read_methods.length > 0 && (
                  <DetailRow label="Read Methods">
                    <div className="space-y-3">
                      {contractProfile.read_methods.slice(0, 8).map((method) => {
                        const methodState = methodResults[method.signature]
                        const supportsQuickCall = contractsApi.supportsSimpleReadCall(method)
                        const inputValues = methodInputs[method.signature] || method.inputs.map(() => '')
                        return (
                          <div key={method.signature} className="rounded-xl border border-gray-200 bg-gray-50 p-3 dark:border-gray-700 dark:bg-gray-900/40">
                            <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                              <div className="min-w-0">
                                <div className="font-mono text-sm text-gray-900 dark:text-white">{method.signature}</div>
                                <div className="mt-1 flex flex-wrap gap-2">
                                  <EntityBadge label={method.stateMutability} tone="success" />
                                  {method.outputs[0]?.type ? <EntityBadge label={`returns ${method.outputs[0].type}`} tone="info" className="normal-case tracking-normal" /> : null}
                                  {method.inputs.length > 0 ? <EntityBadge label="inputs required" tone="warning" /> : null}
                                </div>
                              </div>
                              {supportsQuickCall ? (
                                <button
                                  type="button"
                                  onClick={() => void handleReadMethod(method)}
                                  className="rounded-lg bg-primary-600 px-3 py-2 text-sm font-medium text-white hover:bg-primary-700"
                                >
                                  {methodState?.loading ? 'Calling...' : 'Call'}
                                </button>
                              ) : (
                                <span className="text-xs text-gray-500 dark:text-gray-400">Use ABI externally for parameterized reads</span>
                              )}
                            </div>
                            {method.inputs.length > 0 ? (
                              <div className="mt-3 grid gap-2">
                                {method.inputs.map((input, index) => (
                                  <label key={`${method.signature}-${index}`} className="block">
                                    <span className="mb-1 block text-xs font-medium text-gray-600 dark:text-gray-300">
                                      {input.name || `arg${index + 1}`} · {input.type}
                                    </span>
                                    <input
                                      type="text"
                                      value={inputValues[index] || ''}
                                      onChange={(event) => handleMethodInputChange(method.signature, index, event.target.value)}
                                      className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900 dark:text-white"
                                    />
                                  </label>
                                ))}
                              </div>
                            ) : null}
                            {methodState?.value ? (
                              <code className="mt-3 block break-all rounded bg-white p-2 text-xs text-gray-900 dark:bg-gray-950 dark:text-gray-100">
                                {methodState.value}
                              </code>
                            ) : null}
                            {methodState?.error ? (
                              <div className="mt-3 text-xs text-red-600 dark:text-red-300">{methodState.error}</div>
                            ) : null}
                          </div>
                        )
                      })}
                      {contractProfile.read_methods.length > 8 ? (
                        <div className="text-xs text-gray-500 dark:text-gray-400">
                          Showing the first 8 read methods here for sanity. Full ABI preview remains available below.
                        </div>
                      ) : null}
                    </div>
                  </DetailRow>
                )}
                {contractProfile?.write_methods && contractProfile.write_methods.length > 0 && (
                  <DetailRow label="Write Methods">
                    <div className="space-y-2">
                      {contractProfile.write_methods.slice(0, 6).map((method) => (
                        <div key={method.signature} className="rounded-xl border border-gray-200 bg-gray-50 p-3 text-sm dark:border-gray-700 dark:bg-gray-900/40">
                          <div className="font-mono text-gray-900 dark:text-white">{method.signature}</div>
                          <div className="mt-2 flex flex-wrap gap-2">
                            <EntityBadge label={method.stateMutability} tone="warning" />
                            {method.inputs.length > 0 ? <EntityBadge label={`${method.inputs.length} inputs`} /> : null}
                          </div>
                          {method.inputs.length > 0 ? (
                            <div className="mt-3 grid gap-2">
                              {method.inputs.map((input, index) => (
                                <label key={`${method.signature}-${index}`} className="block">
                                  <span className="mb-1 block text-xs font-medium text-gray-600 dark:text-gray-300">
                                    {input.name || `arg${index + 1}`} · {input.type}
                                  </span>
                                  <input
                                    type="text"
                                    value={(methodInputs[method.signature] || [])[index] || ''}
                                    onChange={(event) => handleMethodInputChange(method.signature, index, event.target.value)}
                                    className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900 dark:text-white"
                                  />
                                </label>
                              ))}
                            </div>
                          ) : null}
                          {contractsApi.supportsSimpleWriteCall(method) ? (
                            <div className="mt-3 flex flex-wrap items-center gap-3">
                              <button
                                type="button"
                                onClick={() => void handleWriteMethod(method)}
                                className="rounded-lg bg-primary-600 px-3 py-2 text-sm font-medium text-white hover:bg-primary-700"
                              >
                                {methodResults[method.signature]?.loading ? 'Awaiting wallet...' : 'Send with wallet'}
                              </button>
                              <code className="text-xs text-gray-500 dark:text-gray-400">
                                Wallet confirmation required
                              </code>
                            </div>
                          ) : (
                            <div className="mt-3 text-xs text-gray-500 dark:text-gray-400">
                              This method uses input types the explorer does not encode directly yet. Use the ABI preview with an external contract UI if needed.
                            </div>
                          )}
                          {methodResults[method.signature]?.value ? (
                            <code className="mt-3 block break-all rounded bg-white p-2 text-xs text-gray-900 dark:bg-gray-950 dark:text-gray-100">
                              {methodResults[method.signature]?.value}
                            </code>
                          ) : null}
                          {methodResults[method.signature]?.error ? (
                            <div className="mt-3 text-xs text-red-600 dark:text-red-300">{methodResults[method.signature]?.error}</div>
                          ) : null}
                        </div>
                      ))}
                      <div className="text-xs text-gray-500 dark:text-gray-400">
                        Write methods are surfaced for inspection here, but actual state-changing execution still belongs behind a wallet-confirmed contract interaction flow.
                      </div>
                    </div>
                  </DetailRow>
                )}
                {contractProfile?.creation_bytecode && (
                  <DetailRow label="Creation Bytecode">
                    <code className="block break-all rounded bg-gray-50 p-2 text-xs dark:bg-gray-950">
                      {contractProfile.creation_bytecode}
                    </code>
                  </DetailRow>
                )}
                {contractProfile?.deployed_bytecode && (
                  <DetailRow label="Runtime Bytecode">
                    <code className="block break-all rounded bg-gray-50 p-2 text-xs dark:bg-gray-950">
                      {contractProfile.deployed_bytecode}
                    </code>
                  </DetailRow>
                )}
              </dl>
            </Card>
          )}

          {activeTab === 'contract' && addressInfo.is_contract && contractProfile ? (
            <ContractCodeWorkspace address={addressInfo.address} profile={contractProfile} />
          ) : null}

          {activeTab === 'contract' && gruProfile ? <div className="mb-6"><GruStandardsCard profile={gruProfile} /></div> : null}

          {activeTab === 'balances' ? <Card title="Token Balances" className="mb-6">
            {gruBalanceCount > 0 ? (
              <div className="mb-4 flex flex-wrap items-center gap-3 text-sm text-gray-600 dark:text-gray-400">
                <span>{gruBalanceCount} visible token balance{gruBalanceCount === 1 ? '' : 's'} look GRU-aware.</span>
                <Link href="/docs/gru" className="text-primary-600 hover:underline">
                  GRU guide →
                </Link>
              </div>
            ) : null}
            <Table
              columns={tokenBalanceColumns}
              data={pagedTokenBalances}
              emptyMessage="No token balances were indexed for this address."
              keyExtractor={(balance) => balance.token_address || `${balance.token_symbol}-${balance.value}`}
            />
            <PaginationControls
              page={balancePage}
              pageCount={balancePageCount}
              onPageChange={setBalancePage}
              label="Token balances"
            />
          </Card> : null}

          {activeTab === 'transfers' ? <Card title="Recent Token Transfers" className="mb-6">
            {gruTransferCount > 0 ? (
              <div className="mb-4 flex flex-wrap items-center gap-3 text-sm text-gray-600 dark:text-gray-400">
                <span>{gruTransferCount} recent transfer asset{gruTransferCount === 1 ? '' : 's'} carry GRU posture in the explorer.</span>
                <Link href="/docs/gru" className="text-primary-600 hover:underline">
                  GRU guide →
                </Link>
                <Link href="/docs/transaction-review" className="text-primary-600 hover:underline">
                  Transaction review guide →
                </Link>
              </div>
            ) : null}
            <Table
              columns={tokenTransferColumns}
              data={pagedTokenTransfers}
              emptyMessage="No token transfers were found for this address."
              keyExtractor={(transfer) => `${transfer.transaction_hash}-${transfer.token_address}-${transfer.value}`}
            />
            <PaginationControls
              page={transferPage}
              pageCount={transferPageCount}
              onPageChange={setTransferPage}
              label="Token transfers"
            />
          </Card> : null}

          {activeTab === 'transactions' ? <Card title="Transactions">
            <Table
              columns={transactionColumns}
              data={pagedTransactions}
              emptyMessage="No recent transactions were found for this address."
              keyExtractor={(tx) => tx.hash}
            />
            <PaginationControls
              page={transactionPage}
              pageCount={transactionPageCount}
              onPageChange={setTransactionPage}
              label="Transactions"
            />
          </Card> : null}
        </>
      )}
    </div>
  )
}
