'use client'

import { useEffect, useMemo, useState } from 'react'
import Link from 'next/link'
import { Card } from '@/libs/frontend-ui-primitives'
import { configApi, type TokenListResponse } from '@/services/api/config'
import {
  aggregateLiquidityPools,
  featuredLiquiditySymbols,
  getLivePlannerProviders,
  getRouteBackedPoolAddresses,
  getTopLiquidityRoutes,
  selectFeaturedLiquidityTokens,
  type AggregatedLiquidityPool,
} from '@/services/api/liquidity'
import { plannerApi, type InternalExecutionPlanResponse, type PlannerCapabilitiesResponse } from '@/services/api/planner'
import { routesApi, type MissionControlLiquidityPool, type RouteMatrixResponse } from '@/services/api/routes'
import { missionControlApi, type MissionControlBridgeStatusResponse } from '@/services/api/missionControl'
import { statsApi, type ExplorerStats } from '@/services/api/stats'
import { summarizeChainActivity } from '@/utils/activityContext'
import ActivityContextPanel from '@/components/common/ActivityContextPanel'
import FreshnessTrustNote from '@/components/common/FreshnessTrustNote'
import { resolveEffectiveFreshness } from '@/utils/explorerFreshness'
import {
  formatCurrency,
  formatNumber,
  relativeAge,
  truncateMiddle,
} from './OperationsPageShell'

const tokenAggregationV1Base = '/token-aggregation/api/v1'
const tokenAggregationV2Base = '/token-aggregation/api/v2'

interface TokenPoolRecord {
  symbol: string
  pools: MissionControlLiquidityPool[]
}

interface EndpointCard {
  name: string
  method: string
  href: string
  notes: string
}

interface LiquidityOperationsPageProps {
  initialTokenList?: TokenListResponse | null
  initialRouteMatrix?: RouteMatrixResponse | null
  initialPlannerCapabilities?: PlannerCapabilitiesResponse | null
  initialInternalPlan?: InternalExecutionPlanResponse | null
  initialTokenPoolRecords?: TokenPoolRecord[]
  initialStats?: ExplorerStats | null
  initialBridgeStatus?: MissionControlBridgeStatusResponse | null
}

function routePairLabel(routeId: string, routeLabel: string, tokenIn?: string, tokenOut?: string): string {
  return [tokenIn, tokenOut].filter(Boolean).join(' / ') || routeLabel || routeId
}

export default function LiquidityOperationsPage({
  initialTokenList = null,
  initialRouteMatrix = null,
  initialPlannerCapabilities = null,
  initialInternalPlan = null,
  initialTokenPoolRecords = [],
  initialStats = null,
  initialBridgeStatus = null,
}: LiquidityOperationsPageProps) {
  const [tokenList, setTokenList] = useState<TokenListResponse | null>(initialTokenList)
  const [routeMatrix, setRouteMatrix] = useState<RouteMatrixResponse | null>(initialRouteMatrix)
  const [plannerCapabilities, setPlannerCapabilities] = useState<PlannerCapabilitiesResponse | null>(initialPlannerCapabilities)
  const [internalPlan, setInternalPlan] = useState<InternalExecutionPlanResponse | null>(initialInternalPlan)
  const [tokenPoolRecords, setTokenPoolRecords] = useState<TokenPoolRecord[]>(initialTokenPoolRecords)
  const [stats, setStats] = useState<ExplorerStats | null>(initialStats)
  const [bridgeStatus, setBridgeStatus] = useState<MissionControlBridgeStatusResponse | null>(initialBridgeStatus)
  const [loadingError, setLoadingError] = useState<string | null>(null)
  const [copiedEndpoint, setCopiedEndpoint] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false

    if (
      initialTokenList &&
      initialRouteMatrix &&
      initialPlannerCapabilities &&
      initialInternalPlan &&
      initialTokenPoolRecords.length > 0 &&
      initialStats &&
      initialBridgeStatus
    ) {
      return () => {
        cancelled = true
      }
    }

    const load = async () => {
      const [tokenListResult, routeMatrixResult, plannerCapabilitiesResult, planResult, statsResult, bridgeResult] =
        await Promise.allSettled([
          configApi.getTokenList(),
          routesApi.getRouteMatrix(),
          plannerApi.getCapabilities(),
          plannerApi.getInternalExecutionPlan(),
          statsApi.get(),
          missionControlApi.getBridgeStatus(),
        ])

      if (cancelled) return

      if (tokenListResult.status === 'fulfilled') setTokenList(tokenListResult.value)
      if (routeMatrixResult.status === 'fulfilled') setRouteMatrix(routeMatrixResult.value)
      if (plannerCapabilitiesResult.status === 'fulfilled') setPlannerCapabilities(plannerCapabilitiesResult.value)
      if (planResult.status === 'fulfilled') setInternalPlan(planResult.value)
      if (statsResult.status === 'fulfilled') setStats(statsResult.value)
      if (bridgeResult.status === 'fulfilled') setBridgeStatus(bridgeResult.value)

      if (tokenListResult.status === 'fulfilled') {
        const featuredTokens = selectFeaturedLiquidityTokens(tokenListResult.value.tokens || [])
        const poolResults = await Promise.allSettled(
          featuredTokens.map(async (token) => ({
            symbol: token.symbol,
            pools: (await routesApi.getTokenPools(token.address)).pools || [],
          }))
        )

        if (!cancelled) {
          setTokenPoolRecords(
            poolResults
              .filter((result): result is PromiseFulfilledResult<TokenPoolRecord> => result.status === 'fulfilled')
              .map((result) => result.value)
          )
        }
      }

      const results = [tokenListResult, routeMatrixResult, plannerCapabilitiesResult, planResult, statsResult, bridgeResult] as const
      const failedCount = results.filter((result) => result.status === 'rejected').length

      if (failedCount === results.length) {
        setLoadingError('Live liquidity data is temporarily unavailable from the public explorer APIs.')
      }
    }

    load().catch((error) => {
      if (!cancelled) {
        setLoadingError(
          error instanceof Error ? error.message : 'Live liquidity data is temporarily unavailable from the public explorer APIs.'
        )
      }
    })

    return () => {
      cancelled = true
    }
  }, [
    initialBridgeStatus,
    initialInternalPlan,
    initialPlannerCapabilities,
    initialRouteMatrix,
    initialStats,
    initialTokenList,
    initialTokenPoolRecords,
  ])

  const featuredTokens = useMemo(
    () => selectFeaturedLiquidityTokens(tokenList?.tokens || []),
    [tokenList?.tokens]
  )
  const aggregatedPools = useMemo(
    () => aggregateLiquidityPools(tokenPoolRecords),
    [tokenPoolRecords]
  )
  const livePlannerProviders = useMemo(
    () => getLivePlannerProviders(plannerCapabilities),
    [plannerCapabilities]
  )
  const routeBackedPoolAddresses = useMemo(
    () => getRouteBackedPoolAddresses(routeMatrix),
    [routeMatrix]
  )
  const highlightedRoutes = useMemo(
    () => getTopLiquidityRoutes(routeMatrix, 6),
    [routeMatrix]
  )
  const dexCount = useMemo(
    () => new Set(aggregatedPools.map((pool) => pool.dex).filter(Boolean)).size,
    [aggregatedPools]
  )
  const activityContext = useMemo(
    () =>
      summarizeChainActivity({
        blocks: [],
        transactions: [],
        latestBlockNumber: stats?.latest_block,
        latestBlockTimestamp: null,
        freshness: resolveEffectiveFreshness(stats, bridgeStatus),
        diagnostics: stats?.diagnostics ?? bridgeStatus?.data?.diagnostics ?? null,
      }),
    [bridgeStatus, stats],
  )

  const insightLines = useMemo(
    () => [
      `${formatNumber(routeMatrix?.counts?.liveSwapRoutes)} live swap routes and ${formatNumber(routeMatrix?.counts?.liveBridgeRoutes)} bridge routes are currently published in the public route matrix.`,
      `${formatNumber(aggregatedPools.length)} unique pools were discovered across ${formatNumber(featuredTokens.length)} featured Chain 138 liquidity tokens.`,
      `${formatNumber(livePlannerProviders.length)} planner providers are live, and the current internal fallback decision is ${internalPlan?.plannerResponse?.decision || 'unknown'}.`,
      `${formatNumber(routeBackedPoolAddresses.length)} unique pool addresses are referenced directly by the current live route legs.`,
    ],
    [routeMatrix, aggregatedPools.length, featuredTokens.length, livePlannerProviders.length, internalPlan?.plannerResponse?.decision, routeBackedPoolAddresses.length]
  )

  const endpointCards: EndpointCard[] = [
    {
      name: 'Canonical route matrix',
      method: 'GET',
      href: `${tokenAggregationV1Base}/routes/matrix?includeNonLive=true`,
      notes: 'All live and non-live route inventory with counts and pool-backed legs.',
    },
    {
      name: 'Planner capabilities',
      method: 'GET',
      href: `${tokenAggregationV2Base}/providers/capabilities?chainId=138`,
      notes: 'Live provider inventory, published pair coverage, and execution modes.',
    },
    {
      name: 'Internal execution plan',
      method: 'POST',
      href: `${tokenAggregationV2Base}/routes/internal-execution-plan`,
      notes: 'Returns the direct-pool fallback posture that the operator surfaces already verify.',
    },
    {
      name: 'Mission-control token pools',
      method: 'GET',
      href: `/explorer-api/v1/mission-control/liquidity/token/${featuredTokens[0]?.address || '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22'}/pools`,
      notes: 'Cached public pool inventory for a specific Chain 138 token.',
    },
  ]

  const copyEndpoint = async (endpoint: EndpointCard) => {
    try {
      await navigator.clipboard.writeText(endpoint.href)
      setCopiedEndpoint(endpoint.name)
      window.setTimeout(() => {
        setCopiedEndpoint((current) => (current === endpoint.name ? null : current))
      }, 1500)
    } catch {
      setCopiedEndpoint(null)
    }
  }

  return (
    <main className="container mx-auto px-4 py-6 sm:py-8">
      <div className="mb-8 max-w-4xl">
        <div className="mb-3 inline-flex rounded-full border border-amber-200 bg-amber-50 px-3 py-1 text-xs font-semibold uppercase tracking-[0.2em] text-amber-700">
          Chain 138 Liquidity Access
        </div>
        <h1 className="mb-3 text-3xl font-bold text-gray-900 dark:text-white sm:text-4xl">
          Public liquidity, route discovery, and execution access points
        </h1>
        <p className="text-base leading-7 text-gray-600 dark:text-gray-400 sm:text-lg sm:leading-8">
          This page now reads the live explorer APIs instead of hardcoded pool snapshots. It pulls the
          public route matrix, planner capabilities, and mission-control token pool inventory together
          so integrators can inspect what Chain 138 is actually serving right now.
        </p>
      </div>

      {loadingError ? (
        <Card className="mb-6 border border-red-200 bg-red-50/70 dark:border-red-900/50 dark:bg-red-950/20">
          <p className="text-sm leading-6 text-red-900 dark:text-red-100">{loadingError}</p>
        </Card>
      ) : null}

      <div className="mb-6">
        <ActivityContextPanel context={activityContext} title="Liquidity Freshness Context" />
        <FreshnessTrustNote
          className="mt-3"
          context={activityContext}
          stats={stats}
          bridgeStatus={bridgeStatus}
          scopeLabel="Liquidity inventory and planner posture are shown alongside the same explorer freshness model used on the homepage and core explorer routes"
        />
      </div>

      <div className="mb-8 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <Card className="border border-emerald-200 bg-emerald-50/70 dark:border-emerald-900/50 dark:bg-emerald-950/20">
          <div className="text-sm font-semibold uppercase tracking-wide text-emerald-800 dark:text-emerald-100">
            Live Pools
          </div>
          <div className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">
            {formatNumber(aggregatedPools.length)}
          </div>
          <div className="mt-2 text-sm text-gray-700 dark:text-gray-300">
            Dedupe of mission-control pool inventory across featured Chain 138 tokens.
          </div>
        </Card>
        <Card className="border border-sky-200 bg-sky-50/70 dark:border-sky-900/50 dark:bg-sky-950/20">
          <div className="text-sm font-semibold uppercase tracking-wide text-sky-800 dark:text-sky-100">
            Route Coverage
          </div>
          <div className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">
            {formatNumber(routeMatrix?.counts?.filteredLiveRoutes)}
          </div>
          <div className="mt-2 text-sm text-gray-700 dark:text-gray-300">
            {formatNumber(routeMatrix?.counts?.liveSwapRoutes)} swaps and {formatNumber(routeMatrix?.counts?.liveBridgeRoutes)} bridges.
          </div>
        </Card>
        <Card>
          <div className="text-sm text-gray-500 dark:text-gray-400">Planner providers</div>
          <div className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">
            {formatNumber(livePlannerProviders.length)}
          </div>
          <div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
            {formatNumber(dexCount)} DEX families in the current discovered pools.
          </div>
        </Card>
        <Card>
          <div className="text-sm text-gray-500 dark:text-gray-400">Fallback posture</div>
          <div className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">
            {internalPlan?.plannerResponse?.decision || 'unknown'}
          </div>
          <div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
            Execution contract {truncateMiddle(internalPlan?.execution?.contractAddress)}
          </div>
        </Card>
      </div>

      <div className="mb-8 grid gap-6 lg:grid-cols-[1.2fr_0.8fr]">
        <Card title="Live Pool Snapshot">
          <div className="space-y-4">
            {aggregatedPools.slice(0, 8).map((pool) => (
              <div
                key={pool.address}
                className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40"
              >
                <div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
                  <div>
                    <div className="text-base font-semibold text-gray-900 dark:text-white">
                      {(pool.token0?.symbol || '?') + ' / ' + (pool.token1?.symbol || '?')}
                    </div>
                    <div className="mt-1 break-all text-xs text-gray-500 dark:text-gray-400">
                      Pool: {pool.address}
                    </div>
                  </div>
                  <div className="text-sm font-medium text-gray-700 dark:text-gray-300">
                    {pool.dex || 'Unknown DEX'} · TVL {formatCurrency(pool.tvl)}
                  </div>
                </div>
                <div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
                  Seen from {pool.sourceSymbols.join(', ')}
                </div>
              </div>
            ))}
            {aggregatedPools.length === 0 ? (
              <div className="rounded-2xl border border-amber-200 bg-amber-50/70 p-4 dark:border-amber-900/50 dark:bg-amber-950/20">
                <p className="text-sm leading-6 text-amber-900 dark:text-amber-100">
                  Mission-control pool inventory is currently empty, but the live route matrix still references{' '}
                  {formatNumber(routeBackedPoolAddresses.length)} pool-backed legs across{' '}
                  {formatNumber(routeMatrix?.counts?.filteredLiveRoutes)} published live routes.
                </p>
                <p className="mt-2 text-sm leading-6 text-amber-900/80 dark:text-amber-100/80">
                  Use the highlighted route-backed paths below and the public route matrix endpoint while pool inventory catches up.
                </p>
              </div>
            ) : null}
          </div>
        </Card>

        <Card title="What Integrators Need To Know">
          <div className="space-y-3 text-sm leading-6 text-gray-600 dark:text-gray-400">
            {insightLines.map((item) => (
              <p key={item}>{item}</p>
            ))}
            <p>
              Featured symbols in this view: {featuredLiquiditySymbols.join(', ')}.
            </p>
          </div>
        </Card>
      </div>

      <div className="mb-8 grid gap-6 lg:grid-cols-[1fr_1fr]">
        <Card title="Top Route-Backed Liquidity Paths">
          <div className="space-y-4">
            {highlightedRoutes.map((route) => (
              <div
                key={route.routeId}
                className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40"
              >
                <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                  <div>
                    <div className="text-base font-semibold text-gray-900 dark:text-white">
                      {routePairLabel(route.routeId, route.label || '', route.tokenInSymbol, route.tokenOutSymbol)}
                    </div>
                    <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                      {formatNumber((route.legs || []).length)} legs · {formatNumber((route.legs || []).filter((leg) => leg.poolAddress).length)} pool-backed
                    </div>
                  </div>
                  <div className="text-sm text-gray-600 dark:text-gray-400">
                    {route.aggregatorFamilies?.join(', ') || 'No provider families listed'}
                  </div>
                </div>
                <div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
                  {(route.legs || [])
                    .map((leg) => leg.poolAddress)
                    .filter(Boolean)
                    .map((address) => truncateMiddle(address))
                    .join(' · ') || 'No pool addresses published'}
                </div>
              </div>
            ))}
          </div>
        </Card>

        <Card title="Featured Token Coverage">
          <div className="space-y-4">
            {featuredTokens.map((token) => {
              const matchingRecord = tokenPoolRecords.find((record) => record.symbol === token.symbol)
              return (
                <div
                  key={token.address}
                  className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40"
                >
                  <div className="text-base font-semibold text-gray-900 dark:text-white">
                    {token.symbol}
                  </div>
                  <div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
                    {token.name || 'Unnamed token'} · {formatNumber(matchingRecord?.pools.length || 0)} mission-control pools
                  </div>
                  <div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                    {truncateMiddle(token.address, 10, 8)}
                  </div>
                </div>
              )
            })}
          </div>
        </Card>
      </div>

      <div className="mb-8">
        <Card title="Explorer Access Points">
          <div className="grid gap-4 md:grid-cols-2">
            {endpointCards.map((endpoint) => (
              <div
                key={endpoint.href}
                className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-700 dark:bg-gray-800"
              >
                <div className="flex flex-col items-start gap-3 sm:flex-row sm:items-center sm:justify-between">
                  <div className="text-base font-semibold text-gray-900 dark:text-white">{endpoint.name}</div>
                  <span className="rounded-full bg-primary-50 px-2.5 py-1 text-xs font-semibold uppercase tracking-wide text-primary-700 dark:bg-primary-900/30 dark:text-primary-300">
                    {endpoint.method}
                  </span>
                </div>
                <div className="mt-3 break-all rounded-xl bg-gray-50 p-3 text-xs text-gray-700 dark:bg-gray-900 dark:text-gray-300">
                  {endpoint.href}
                </div>
                <div className="mt-3 text-sm leading-6 text-gray-600 dark:text-gray-400">{endpoint.notes}</div>
                <div className="mt-4 flex flex-wrap gap-3">
                  <button
                    type="button"
                    onClick={() => void copyEndpoint(endpoint)}
                    className="rounded-full border border-gray-300 px-4 py-2 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"
                  >
                    {copiedEndpoint === endpoint.name ? 'Copied' : 'Copy endpoint'}
                  </button>
                  {endpoint.name === 'Mission-control token pools' ? (
                    <Link
                      href="/pools"
                      className="rounded-full border border-gray-300 px-4 py-2 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"
                    >
                      Open pools page
                    </Link>
                  ) : null}
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>

      <div className="mb-8 grid gap-6 lg:grid-cols-[1fr_1fr]">
        <Card title="Quick Request Examples">
          <div className="space-y-4">
            {[
              `GET ${tokenAggregationV1Base}/routes/matrix?includeNonLive=true`,
              `GET ${tokenAggregationV2Base}/providers/capabilities?chainId=138`,
              `POST ${tokenAggregationV2Base}/routes/internal-execution-plan`,
              `GET /explorer-api/v1/mission-control/liquidity/token/${featuredTokens[0]?.address || '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22'}/pools`,
            ].map((example) => (
              <div key={example} className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40">
                <code className="block break-all text-xs leading-6 text-gray-700 dark:text-gray-300">
                  {example}
                </code>
              </div>
            ))}
          </div>
        </Card>

        <Card title="Related Explorer Tools">
          <div className="space-y-4 text-sm leading-6 text-gray-600 dark:text-gray-400">
            <p>
              Use the wallet page for network onboarding, the pools page for a tighter live inventory
              view, and this page for the broader route and execution surfaces.
            </p>
            <p>
              The live route matrix was updated {relativeAge(routeMatrix?.updated)}, and the current
              route-backed pool set references {formatNumber(routeBackedPoolAddresses.length)} unique
              pool addresses.
            </p>
            <div className="flex flex-wrap gap-3">
              <Link
                href="/pools"
                className="rounded-full bg-primary-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-primary-700"
              >
                Open pools page
              </Link>
              <Link
                href="/wallet"
                className="rounded-full border border-gray-300 px-4 py-2 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"
              >
                Open wallet tools
              </Link>
              <Link
                href="/docs"
                className="rounded-full border border-gray-300 px-4 py-2 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"
              >
                Explorer docs
              </Link>
            </div>
          </div>
        </Card>
      </div>
    </main>
  )
}
