import { useEffect, useState } from 'react'
import type {
  CapabilitiesCatalog,
  FetchMetadata,
  NetworksCatalog,
  TokenListCatalog,
} from '@/components/wallet/AddToMetaMask'
import { AddToMetaMask } from '@/components/wallet/AddToMetaMask'
import Link from 'next/link'
import { Explain, useUiMode } from '@/components/common/UiModeContext'
import { accessApi, type WalletAccessSession } from '@/services/api/access'
import EntityBadge from '@/components/common/EntityBadge'
import {
  addressesApi,
  type AddressInfo,
  type AddressTokenBalance,
  type AddressTokenTransfer,
  type TransactionSummary,
} from '@/services/api/addresses'
import { formatRelativeAge, formatTokenAmount } from '@/utils/format'
import {
  isWatchlistEntry,
  readWatchlistFromStorage,
  toggleWatchlistEntry,
  writeWatchlistToStorage,
} from '@/utils/watchlist'

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

function shortAddress(value?: string | null): string {
  if (!value) return 'Unknown'
  if (value.length <= 14) return value
  return `${value.slice(0, 6)}...${value.slice(-4)}`
}

export default function WalletPage(props: WalletPageProps) {
  const { mode } = useUiMode()
  const [walletSession, setWalletSession] = useState<WalletAccessSession | null>(null)
  const [connectingWallet, setConnectingWallet] = useState(false)
  const [walletError, setWalletError] = useState<string | null>(null)
  const [copiedAddress, setCopiedAddress] = useState(false)
  const [watchlistEntries, setWatchlistEntries] = useState<string[]>([])
  const [addressInfo, setAddressInfo] = useState<AddressInfo | null>(null)
  const [recentAddressTransactions, setRecentAddressTransactions] = useState<TransactionSummary[]>([])
  const [tokenBalances, setTokenBalances] = useState<AddressTokenBalance[]>([])
  const [tokenTransfers, setTokenTransfers] = useState<AddressTokenTransfer[]>([])

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

    const syncSession = () => {
      setWalletSession(accessApi.getStoredWalletSession())
    }

    const syncWatchlist = () => {
      setWatchlistEntries(readWatchlistFromStorage(window.localStorage))
    }

    syncSession()
    syncWatchlist()
    window.addEventListener('explorer-access-session-changed', syncSession)
    window.addEventListener('storage', syncWatchlist)
    return () => {
      window.removeEventListener('explorer-access-session-changed', syncSession)
      window.removeEventListener('storage', syncWatchlist)
    }
  }, [])

  const handleConnectWallet = async () => {
    setConnectingWallet(true)
    setWalletError(null)
    try {
      const session = await accessApi.connectWalletSession()
      setWalletSession(session)
    } catch (error) {
      setWalletError(error instanceof Error ? error.message : 'Wallet connection failed.')
    } finally {
      setConnectingWallet(false)
    }
  }

  const handleDisconnectWallet = () => {
    accessApi.clearSession()
    accessApi.clearWalletSession()
    setWalletSession(null)
  }

  const handleCopyAddress = async () => {
    if (!walletSession?.address || typeof navigator === 'undefined' || !navigator.clipboard) return
    await navigator.clipboard.writeText(walletSession.address)
    setCopiedAddress(true)
    window.setTimeout(() => setCopiedAddress(false), 1500)
  }

  const handleToggleWatchlist = () => {
    if (!walletSession?.address || typeof window === 'undefined') return
    const nextEntries = toggleWatchlistEntry(watchlistEntries, walletSession.address)
    writeWatchlistToStorage(window.localStorage, nextEntries)
    setWatchlistEntries(nextEntries)
  }

  const isSavedToWatchlist = walletSession?.address
    ? isWatchlistEntry(watchlistEntries, walletSession.address)
    : false

  useEffect(() => {
    let cancelled = false

    if (!walletSession?.address) {
      setAddressInfo(null)
      setRecentAddressTransactions([])
      setTokenBalances([])
      setTokenTransfers([])
      return () => {
        cancelled = true
      }
    }

    Promise.all([
      addressesApi.getSafe(138, walletSession.address),
      addressesApi.getTransactionsSafe(138, walletSession.address, 1, 3),
      addressesApi.getTokenBalancesSafe(walletSession.address),
      addressesApi.getTokenTransfersSafe(walletSession.address, 1, 4),
    ])
      .then(([infoResponse, transactionsResponse, balancesResponse, transfersResponse]) => {
        if (cancelled) return
        setAddressInfo(infoResponse.ok ? infoResponse.data : null)
        setRecentAddressTransactions(transactionsResponse.ok ? transactionsResponse.data : [])
        setTokenBalances(
          balancesResponse.ok
            ? [...balancesResponse.data]
                .filter((balance) => {
                  try {
                    return BigInt(balance.value || '0') > 0n
                  } catch {
                    return Boolean(balance.value)
                  }
                })
                .sort((left, right) => {
                  try {
                    return Number(BigInt(right.value || '0') - BigInt(left.value || '0'))
                  } catch {
                    return 0
                  }
                })
                .slice(0, 4)
            : [],
        )
        setTokenTransfers(transfersResponse.ok ? transfersResponse.data : [])
      })
      .catch(() => {
        if (cancelled) return
        setAddressInfo(null)
        setRecentAddressTransactions([])
        setTokenBalances([])
        setTokenTransfers([])
      })

    return () => {
      cancelled = true
    }
  }, [walletSession?.address])

  return (
    <main className="container mx-auto px-4 py-6 sm:py-8">
      <h1 className="mb-4 text-2xl font-bold sm:text-3xl">Wallet Tools</h1>
      <p className="mb-6 text-sm leading-7 text-gray-600 dark:text-gray-400 sm:text-base">
        {mode === 'guided'
          ? 'Use the explorer-served network catalog, token list, and capability metadata to connect Chain 138 (DeFi Oracle Meta Mainnet) and Ethereum Mainnet to MetaMask and other Web3 wallets.'
          : 'Use explorer-served network and token metadata to connect Chain 138 and Ethereum Mainnet wallets.'}
      </p>
      <div className="mb-6 rounded-2xl border border-sky-200 bg-sky-50/60 p-5 dark:border-sky-900/40 dark:bg-sky-950/20">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
          <div>
            <div className="text-lg font-semibold text-gray-900 dark:text-white">Wallet session</div>
            <p className="mt-2 text-sm leading-6 text-gray-600 dark:text-gray-400">
              {walletSession
                ? mode === 'guided'
                  ? 'This wallet is connected to the same account/access session used by the header. You can jump straight into your explorer address view or the access console from here.'
                  : 'Connected wallet session is active for explorer and access surfaces.'
                : mode === 'guided'
                  ? 'Connect a browser wallet to make this page useful beyond setup: copy your address, open your on-explorer address page, and continue into the access console with the same session.'
                  : 'Connect a wallet to activate account-linked explorer actions.'}
            </p>
          </div>
          <div className="flex flex-wrap gap-2">
            <EntityBadge label={walletSession ? 'connected' : 'disconnected'} tone={walletSession ? 'success' : 'neutral'} />
            {walletSession ? <EntityBadge label={walletSession.track} tone="info" /> : null}
          </div>
        </div>

        <div className="mt-4 grid gap-4 lg:grid-cols-[1.2fr_0.8fr]">
          <div className="rounded-2xl border border-white/60 bg-white/70 p-4 dark:border-white/10 dark:bg-black/10">
            <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Current wallet</div>
            <div className="mt-2 text-xl font-semibold text-gray-900 dark:text-white">
              {walletSession ? shortAddress(walletSession.address) : 'No wallet connected'}
            </div>
            <div className="mt-1 break-all text-sm text-gray-600 dark:text-gray-400">
              {walletSession?.address || 'Use Connect Wallet to start a browser-wallet session.'}
            </div>
            {walletSession?.expiresAt ? (
              <div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
                Session expires {new Date(walletSession.expiresAt).toLocaleString()}
              </div>
            ) : null}
          </div>

          <div className="rounded-2xl border border-white/60 bg-white/70 p-4 dark:border-white/10 dark:bg-black/10">
            <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Quick actions</div>
            <div className="mt-3 flex flex-wrap gap-2">
              {walletSession ? (
                <>
                  <button
                    type="button"
                    onClick={handleCopyAddress}
                    className="rounded-lg border border-primary-300 px-3 py-2 text-sm font-medium text-primary-700 hover:bg-primary-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-primary-800 dark:text-primary-300 dark:hover:bg-primary-950/20"
                  >
                    {copiedAddress ? 'Address copied' : 'Copy address'}
                  </button>
                  <Link
                    href={`/addresses/${walletSession.address}`}
                    className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-900/60"
                  >
                    Open address
                  </Link>
                  <Link
                    href="/access"
                    className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-900/60"
                  >
                    Open access console
                  </Link>
                  <button
                    type="button"
                    onClick={handleToggleWatchlist}
                    className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-900/60"
                  >
                    {isSavedToWatchlist ? 'Remove from watchlist' : 'Save to watchlist'}
                  </button>
                  <Link
                    href="/watchlist"
                    className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-900/60"
                  >
                    Open watchlist
                  </Link>
                  <button
                    type="button"
                    onClick={handleDisconnectWallet}
                    className="rounded-lg border border-red-200 px-3 py-2 text-sm font-medium text-red-700 hover:bg-red-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 dark:border-red-900/60 dark:text-red-200 dark:hover:bg-red-950/30"
                  >
                    Disconnect wallet
                  </button>
                </>
              ) : (
                <>
                  <button
                    type="button"
                    onClick={handleConnectWallet}
                    disabled={connectingWallet}
                    className="rounded-lg bg-primary-600 px-3 py-2 text-sm font-semibold text-white hover:bg-primary-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 disabled:cursor-not-allowed disabled:opacity-70"
                  >
                    {connectingWallet ? 'Connecting wallet…' : 'Connect wallet'}
                  </button>
                  <Link
                    href="/access"
                    className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-900/60"
                  >
                    Open access console
                  </Link>
                </>
              )}
            </div>
            {walletError ? (
              <div className="mt-3 text-sm text-red-700 dark:text-red-300">{walletError}</div>
            ) : null}
            {walletSession ? (
              <div className="mt-3 text-sm text-gray-600 dark:text-gray-400">
                {isSavedToWatchlist
                  ? 'This wallet is already saved in the shared explorer watchlist.'
                  : 'Save this wallet into the shared explorer watchlist to revisit it from addresses and transaction workflows.'}
              </div>
            ) : null}
          </div>
        </div>

        {walletSession ? (
          <div className="mt-4 rounded-2xl border border-white/60 bg-white/70 p-4 dark:border-white/10 dark:bg-black/10">
            <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
              <div>
                <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                  Connected Address Snapshot
                </div>
                <div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
                  {mode === 'guided'
                    ? 'A quick explorer view of the connected wallet so you can jump from connection into browsing and monitoring.'
                    : 'Current explorer snapshot for the connected wallet.'}
                </div>
              </div>
              <Link href={`/addresses/${walletSession.address}`} className="text-sm font-medium text-primary-600 hover:underline">
                Open full address page →
              </Link>
            </div>

            <div className="mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
              <div className="rounded-2xl border border-gray-200 bg-gray-50/70 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/40">
                <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Transactions</div>
                <div className="mt-1 text-lg font-semibold text-gray-900 dark:text-white">
                  {addressInfo ? addressInfo.transaction_count.toLocaleString() : 'Unknown'}
                </div>
              </div>
              <div className="rounded-2xl border border-gray-200 bg-gray-50/70 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/40">
                <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Token Holdings</div>
                <div className="mt-1 text-lg font-semibold text-gray-900 dark:text-white">
                  {addressInfo ? addressInfo.token_count.toLocaleString() : 'Unknown'}
                </div>
              </div>
              <div className="rounded-2xl border border-gray-200 bg-gray-50/70 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/40">
                <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Address Type</div>
                <div className="mt-1 text-lg font-semibold text-gray-900 dark:text-white">
                  {addressInfo ? (addressInfo.is_contract ? 'Contract' : 'EOA') : 'Unknown'}
                </div>
              </div>
              <div className="rounded-2xl border border-gray-200 bg-gray-50/70 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/40">
                <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Recent Indexed Tx</div>
                <div className="mt-1 text-lg font-semibold text-gray-900 dark:text-white">
                  {recentAddressTransactions[0] ? `#${recentAddressTransactions[0].block_number}` : 'None visible'}
                </div>
              </div>
            </div>

            <div className="mt-4 grid gap-3 lg:grid-cols-3">
              {recentAddressTransactions.length === 0 ? (
                <div className="text-sm text-gray-600 dark:text-gray-400 lg:col-span-3">
                  No recent indexed transactions are currently visible for this connected wallet.
                </div>
              ) : (
                recentAddressTransactions.map((transaction) => (
                  <Link
                    key={transaction.hash}
                    href={`/transactions/${transaction.hash}`}
                    className="rounded-2xl border border-gray-200 bg-gray-50/70 px-4 py-3 text-sm hover:border-primary-300 hover:bg-primary-50/60 dark:border-gray-800 dark:bg-gray-900/40 dark:hover:border-primary-700 dark:hover:bg-primary-950/20"
                  >
                    <div className="font-semibold text-gray-900 dark:text-white">
                      {transaction.hash.slice(0, 10)}...{transaction.hash.slice(-8)}
                    </div>
                    <div className="mt-1 text-gray-600 dark:text-gray-400">
                      Block #{transaction.block_number.toLocaleString()}
                    </div>
                  </Link>
                ))
              )}
            </div>

            <div className="mt-6 grid gap-4 xl:grid-cols-[0.9fr_1.1fr]">
              <div className="rounded-2xl border border-gray-200 bg-gray-50/70 p-4 dark:border-gray-800 dark:bg-gray-900/40">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                      Visible Token Balances
                    </div>
                    <div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
                      {mode === 'guided'
                        ? 'These are the first visible non-zero token balances currently indexed for your connected wallet.'
                        : 'Indexed non-zero token balances for this wallet.'}
                    </div>
                  </div>
                  <Link href={`/addresses/${walletSession.address}`} className="text-sm font-medium text-primary-600 hover:underline">
                    Full address detail →
                  </Link>
                </div>

                <div className="mt-4 space-y-3">
                  {tokenBalances.length === 0 ? (
                    <div className="text-sm text-gray-600 dark:text-gray-400">
                      No indexed token balances are currently visible for this wallet.
                    </div>
                  ) : (
                    tokenBalances.map((balance) => (
                      <Link
                        key={balance.token_address}
                        href={`/tokens/${balance.token_address}`}
                        className="block rounded-xl border border-gray-200 bg-white/80 px-4 py-3 hover:border-primary-300 hover:bg-primary-50/60 dark:border-gray-700 dark:bg-black/10 dark:hover:border-primary-700 dark:hover:bg-primary-950/20"
                      >
                        <div className="flex items-start justify-between gap-3">
                          <div>
                            <div className="font-semibold text-gray-900 dark:text-white">
                              {balance.token_symbol || balance.token_name || 'Token'}
                            </div>
                            <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                              {balance.token_type || 'token'} · {balance.token_name || balance.token_address}
                            </div>
                          </div>
                          <div className="text-right text-sm font-medium text-gray-900 dark:text-white">
                            {formatTokenAmount(balance.value, balance.token_decimals, balance.token_symbol, 6)}
                          </div>
                        </div>
                      </Link>
                    ))
                  )}
                </div>
              </div>

              <div className="rounded-2xl border border-gray-200 bg-gray-50/70 p-4 dark:border-gray-800 dark:bg-gray-900/40">
                <div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                  Recent Token Transfers
                </div>
                <div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
                  {mode === 'guided'
                    ? 'Use these token transfers to jump directly into recent visible asset movement for the connected wallet.'
                    : 'Recent indexed token transfer activity for this wallet.'}
                </div>

                <div className="mt-4 space-y-3">
                  {tokenTransfers.length === 0 ? (
                    <div className="text-sm text-gray-600 dark:text-gray-400">
                      No recent token transfers are currently visible for this connected wallet.
                    </div>
                  ) : (
                    tokenTransfers.map((transfer) => {
                      const incoming = transfer.to_address.toLowerCase() === walletSession.address.toLowerCase()
                      const counterparty = incoming ? transfer.from_address : transfer.to_address
                      return (
                        <div
                          key={`${transfer.transaction_hash}-${transfer.token_address}`}
                          className="rounded-xl border border-gray-200 bg-white/80 px-4 py-3 dark:border-gray-700 dark:bg-black/10"
                        >
                          <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                            <div>
                              <div className="font-semibold text-gray-900 dark:text-white">
                                {incoming ? 'Incoming' : 'Outgoing'} {transfer.token_symbol || 'token'} transfer
                              </div>
                              <div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
                                {formatTokenAmount(transfer.value, transfer.token_decimals, transfer.token_symbol, 6)}
                              </div>
                              <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                                Counterparty: {counterparty.slice(0, 6)}...{counterparty.slice(-4)} · {formatRelativeAge(transfer.timestamp)}
                              </div>
                            </div>
                            <div className="flex flex-wrap gap-3 text-sm">
                              <Link href={`/transactions/${transfer.transaction_hash}`} className="text-primary-600 hover:underline">
                                Open tx →
                              </Link>
                              <Link href={`/addresses/${counterparty}`} className="text-primary-600 hover:underline">
                                Counterparty →
                              </Link>
                            </div>
                          </div>
                        </div>
                      )
                    })
                  )}
                </div>
              </div>
            </div>
          </div>
        ) : null}
      </div>
      <AddToMetaMask {...props} />
      <div className="mt-6 rounded-lg border border-gray-200 bg-white p-4 text-sm text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400">
        <Explain>
          <>
            Need swap and liquidity discovery too? Visit the{' '}
            <Link href="/liquidity" className="font-medium text-primary-600 hover:underline dark:text-primary-400">
              Liquidity Access
            </Link>{' '}
            page for live Chain 138 pools, route matrix links, partner payload templates, and the internal fallback execution plan endpoints.
          </>
        </Explain>
        {mode === 'expert' ? (
          <>
            Liquidity and planner posture lives on the{' '}
            <Link href="/liquidity" className="font-medium text-primary-600 hover:underline dark:text-primary-400">
              Liquidity Access
            </Link>{' '}
            surface.
          </>
        ) : null}
      </div>
    </main>
  )
}
