import type { GetStaticProps } from 'next'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect, useMemo, useState } from 'react'
import { Card } from '@/libs/frontend-ui-primitives'
import PageIntro from '@/components/common/PageIntro'
import EntityBadge from '@/components/common/EntityBadge'
import MarketEvidenceNote from '@/components/common/MarketEvidenceNote'
import { tokensApi } from '@/services/api/tokens'
import type { TokenListToken } from '@/services/api/config'
import { tokenAggregationApi, type TokenAggregationTokenSnapshot } from '@/services/api/tokenAggregation'
import { fetchTokenListForSurface, TOKEN_LIST_SURFACE_LABELS } from '@/services/api/tokenListSurfaces'
import { selectCuratedFeaturedTokens } from '@/utils/featuredTokens'

const quickSearches = [
  { label: 'cUSDT', description: 'Canonical compliant USD treasury / government bond liquidity and address results.' },
  { label: 'cUSDC', description: 'Canonical compliant USD cash electronic-money routes and address coverage.' },
  { label: 'cXAUC', description: 'Gold-backed cXAUC pools and token references.' },
  { label: 'cXAUT', description: 'Gold-backed cXAUT references and search coverage.' },
  { label: 'cEURT', description: 'EUR liquidity and cXAUC-connected route coverage.' },
  { label: 'USDT', description: 'Native-side USDT routes and address discovery.' },
]

function normalizeAddress(value: string) {
  const trimmed = value.trim()
  return /^0x[a-fA-F0-9]{40}$/.test(trimmed) ? trimmed : ''
}

interface TokensPageProps {
  initialCuratedTokens: TokenListToken[]
}

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

function tagPriority(tag: string) {
  const order: Record<string, number> = {
    gru: 0,
    compliant: 1,
    'treasury-bond': 2,
    'electronic-money': 2,
    commodity: 2,
    'reference-asset': 0,
    defi: 4,
  }
  return order[tag] ?? 3
}

export default function TokensPage({ initialCuratedTokens }: TokensPageProps) {
  const router = useRouter()
  const [query, setQuery] = useState('')
  const [curatedTokens, setCuratedTokens] = useState<TokenListToken[]>(initialCuratedTokens)
  const [featuredMarkets, setFeaturedMarkets] = useState<Record<string, TokenAggregationTokenSnapshot>>({})

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault()
    const normalized = normalizeAddress(query)
    router.push(normalized ? `/tokens/${normalized}` : `/search?q=${encodeURIComponent(query.trim())}`)
  }

  useEffect(() => {
    if (initialCuratedTokens.length > 0) {
      setCuratedTokens(initialCuratedTokens)
      return
    }

    let active = true
    tokensApi.listForSurface('catalog', 138).then(({ ok, data }) => {
      if (active) {
        setCuratedTokens(ok ? data : [])
      }
    }).catch(() => {
      if (active) {
        setCuratedTokens([])
      }
    })
    return () => {
      active = false
    }
  }, [initialCuratedTokens])

  const featuredCuratedTokens = useMemo(
    () => selectCuratedFeaturedTokens(curatedTokens) as TokenListToken[],
    [curatedTokens],
  )

  useEffect(() => {
    let active = true

    const featuredAddresses = featuredCuratedTokens
      .map((token) => token.address)
      .filter((address): address is string => typeof address === 'string' && address.trim().length > 0)

    tokenAggregationApi.getTokensByAddressSafe(138, featuredAddresses).then(({ data }) => {
      if (!active) return
      const next = Object.fromEntries(data.map((snapshot) => [snapshot.address.toLowerCase(), snapshot]))
      setFeaturedMarkets(next)
    }).catch(() => {
      if (active) {
        setFeaturedMarkets({})
      }
    })

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

  return (
    <div className="container mx-auto px-4 py-8">
      <PageIntro
        eyebrow="Token Discovery"
        title="Tokens"
        description="Browse the canonical Chain 138 trading set, open token contracts directly, and review holders, transfers, liquidity, and provenance from the same institutional explorer surface."
        actions={[
          { href: '/wallet', label: 'Wallet tools' },
          { href: '/liquidity', label: 'Liquidity access' },
          { href: '/search', label: 'Explorer search' },
        ]}
      />

      <Card className="mb-5" title="Find a token">
        <form onSubmit={handleSubmit} className="flex flex-col gap-2 sm:flex-row">
          <input
            type="text"
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            placeholder="Token symbol, name, or contract address"
            className="min-h-10 flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 dark:border-gray-700 dark:bg-gray-950"
          />
          <button
            type="submit"
            disabled={!query.trim()}
            className="min-h-10 rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:cursor-not-allowed disabled:opacity-50"
          >
            Search
          </button>
        </form>
      </Card>

      <div className="mt-5">
        <Card title="Curated Chain 138 tokens">
          <p className="mb-4 text-sm text-gray-600 dark:text-gray-400">
            {TOKEN_LIST_SURFACE_LABELS.catalog}. Showing {featuredCuratedTokens.length} featured tokens from the live report list.
          </p>
          <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
            {featuredCuratedTokens
              .filter((token): token is TokenListToken & { address: string } => typeof token.address === 'string' && token.address.trim().length > 0)
              .map((token) => {
                const market = featuredMarkets[token.address.toLowerCase()]?.market
                return (
                  <Link
                    key={token.address}
                    href={`/tokens/${token.address}`}
                    className="rounded-lg border border-gray-200 p-4 transition hover:border-primary-400 hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-950/50"
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0">
                        <div className="text-sm font-semibold text-gray-900 dark:text-white">{token.symbol || token.name || 'Token'}</div>
                        <p className="mt-1 line-clamp-2 text-sm leading-5 text-gray-600 dark:text-gray-400">
                      {token.name || 'Listed in the Chain 138 token registry.'}
                        </p>
                      </div>
                    </div>
                    {market ? (
                      <div className="mt-3 grid grid-cols-2 gap-2 text-sm text-gray-700 dark:text-gray-300">
                        <div className="rounded-lg bg-gray-50 px-3 py-2 dark:bg-gray-950/60">
                          <div className="text-[11px] font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Price</div>
                          <div className="mt-1 font-semibold text-gray-950 dark:text-white">{formatUsd(market.priceUsd)}</div>
                        </div>
                        <div className="rounded-lg bg-gray-50 px-3 py-2 dark:bg-gray-950/60">
                          <div className="text-[11px] font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Liquidity</div>
                          <div className="mt-1 font-semibold text-gray-950 dark:text-white">{formatUsd(market.liquidityUsd)}</div>
                        </div>
                        <div className="col-span-2">
                        <MarketEvidenceNote lastUpdated={market.lastUpdated} compact />
                        </div>
                      </div>
                    ) : null}
                    {token.tags && token.tags.length > 0 && (
                      <div className="mt-3 flex flex-wrap gap-2">
                        {[...token.tags].sort((a, b) => tagPriority(a) - tagPriority(b)).slice(0, 3).map((tag) => (
                          <EntityBadge key={`${token.address}-${tag}`} label={tag} className="px-2 py-1 text-[11px]" />
                        ))}
                      </div>
                    )}
                  </Link>
                )
              })}
          </div>
        </Card>
      </div>

      <div className="mt-5">
        <Card title="Common token searches">
          <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
            {quickSearches.map((token) => (
              <Link
                key={token.label}
                href={`/search?q=${encodeURIComponent(token.label)}`}
                className="rounded-lg border border-gray-200 px-3 py-2 transition hover:border-primary-400 hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-950/50"
              >
                <div className="text-sm font-semibold text-gray-900 dark:text-white">{token.label}</div>
                <p className="mt-1 line-clamp-2 text-xs leading-5 text-gray-600 dark:text-gray-400">{token.description}</p>
              </Link>
            ))}
          </div>
        </Card>
      </div>
    </div>
  )
}

export const getStaticProps: GetStaticProps<TokensPageProps> = async () => {
  const { tokens } = await fetchTokenListForSurface('catalog', 138)

  return {
    props: {
      initialCuratedTokens: tokens,
    },
    revalidate: 300,
  }
}
