import type { GetServerSideProps } from 'next'
import LiquidityOperationsPage from '@/components/explorer/LiquidityOperationsPage'
import type { TokenListResponse } from '@/services/api/config'
import type { InternalExecutionPlanResponse, PlannerCapabilitiesResponse } from '@/services/api/planner'
import type { MissionControlLiquidityPool, RouteMatrixResponse } from '@/services/api/routes'
import type { MissionControlBridgeStatusResponse } from '@/services/api/missionControl'
import type { ExplorerStats } from '@/services/api/stats'
import { fetchPublicJson } from '@/utils/publicExplorer'
import { fetchExplorerTruthContext } from '@/utils/serverExplorerContext'

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

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

const featuredTokenSymbols = new Set(['cUSDT', 'cUSDC', 'USDT', 'USDC', 'cXAUC', 'cXAUT'])

async function fetchPublicPostJson<T>(path: string, body: unknown): Promise<T> {
  const response = await fetch(`https://blockscout.defi-oracle.io${path}`, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
    },
    body: JSON.stringify(body),
  })
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`)
  }
  return (await response.json()) as T
}

export default function LiquidityPage(props: LiquidityPageProps) {
  return <LiquidityOperationsPage {...props} />
}

export const getServerSideProps: GetServerSideProps<LiquidityPageProps> = async () => {
  const [tokenListResult, routeMatrixResult, plannerCapabilitiesResult, internalPlanResult, truthContext] =
    await Promise.all([
      fetchPublicJson<TokenListResponse>('/api/config/token-list').catch(() => null),
      fetchPublicJson<RouteMatrixResponse>('/token-aggregation/api/v1/routes/matrix?includeNonLive=true').catch(() => null),
      fetchPublicJson<PlannerCapabilitiesResponse>('/token-aggregation/api/v2/providers/capabilities?chainId=138').catch(
        () => null,
      ),
      fetchPublicPostJson<InternalExecutionPlanResponse>('/token-aggregation/api/v2/routes/internal-execution-plan', {
        sourceChainId: 138,
        tokenIn: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        tokenOut: '0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1',
        amountIn: '100000000000000000',
      }).catch(() => null),
      fetchExplorerTruthContext(),
    ])

  const featuredTokens = (tokenListResult?.tokens || []).filter(
    (token) => token.chainId === 138 && typeof token.symbol === 'string' && featuredTokenSymbols.has(token.symbol),
  )

  const tokenPoolsResults = await Promise.all(
    featuredTokens.map(async (token) => {
      const response = await fetchPublicJson<{ pools?: MissionControlLiquidityPool[]; data?: { pools?: MissionControlLiquidityPool[] } }>(
        `/explorer-api/v1/mission-control/liquidity/token/${token.address}/pools`,
      ).catch(() => null)
      const pools = Array.isArray(response?.pools)
        ? response.pools
        : Array.isArray(response?.data?.pools)
          ? response.data.pools
          : []
      return { symbol: token.symbol || token.address || 'unknown', pools }
    }),
  ).catch(() => [] as TokenPoolRecord[])

  return {
    props: {
      initialTokenList: tokenListResult,
      initialRouteMatrix: routeMatrixResult,
      initialPlannerCapabilities: plannerCapabilitiesResult,
      initialInternalPlan: internalPlanResult,
      initialTokenPoolRecords: tokenPoolsResults,
      initialStats: truthContext.initialStats,
      initialBridgeStatus: truthContext.initialBridgeStatus,
    },
  }
}
