import type { GetServerSideProps } from 'next'
import HomePage from '@/components/home/HomePage'
import { normalizeBlock } from '@/services/api/blockscout'
import {
  normalizeTransactionTrend,
  summarizeRecentTransactions,
  type ExplorerRecentActivitySnapshot,
  type ExplorerStats,
  type ExplorerTransactionTrendPoint,
} from '@/services/api/stats'
import {
  summarizeMissionControlRelay,
  type MissionControlBridgeStatusResponse,
  type MissionControlRelaySummary,
} from '@/services/api/missionControl'
import type { Block } from '@/services/api/blocks'
import type { Transaction } from '@/services/api/transactions'
import { fetchPublicJson } from '@/utils/publicExplorer'
import { fetchExplorerTruthContext } from '@/utils/serverExplorerContext'
import { normalizeTransaction } from '@/services/api/blockscout'

interface IndexPageProps {
  initialStats: ExplorerStats | null
  initialRecentBlocks: Block[]
  initialRecentTransactions: Transaction[]
  initialTransactionTrend: ExplorerTransactionTrendPoint[]
  initialActivitySnapshot: ExplorerRecentActivitySnapshot | null
  initialBridgeStatus: MissionControlBridgeStatusResponse | null
  initialRelaySummary: MissionControlRelaySummary | null
}

export default function IndexPage(props: IndexPageProps) {
  return <HomePage {...props} />
}

function serializeTransactions(transactions: Transaction[]): Transaction[] {
  return JSON.parse(
    JSON.stringify(
      transactions.map((transaction) => ({
        hash: transaction.hash,
        block_number: transaction.block_number,
        from_address: transaction.from_address,
        to_address: transaction.to_address ?? null,
        value: transaction.value,
        status: transaction.status ?? null,
        contract_address: transaction.contract_address ?? null,
        fee: transaction.fee ?? null,
        created_at: transaction.created_at,
      })),
    ),
  ) as Transaction[]
}

export const getServerSideProps: GetServerSideProps<IndexPageProps> = async () => {
  const chainId = Number(process.env.NEXT_PUBLIC_CHAIN_ID || '138')

  const [truthContextResult, blocksResult, transactionsResult, trendResult, activityResult] = await Promise.allSettled([
    fetchExplorerTruthContext(),
    fetchPublicJson<{ items?: unknown[] }>('/api/v2/blocks?page=1&page_size=10'),
    fetchPublicJson<{ items?: unknown[] }>('/api/v2/transactions?page=1&page_size=5'),
    fetchPublicJson<{ chart_data?: Array<{ date?: string | null; transaction_count?: number | string | null }> }>(
      '/api/v2/stats/charts/transactions'
    ),
    fetchPublicJson<
      Array<{
        status?: string | null
        transaction_types?: string[] | null
        gas_used?: number | string | null
        fee?: { value?: string | number | null } | string | null
      }>
    >('/api/v2/main-page/transactions'),
  ])

  return {
    props: {
      initialStats: truthContextResult.status === 'fulfilled' ? truthContextResult.value.initialStats : null,
      initialRecentBlocks:
        blocksResult.status === 'fulfilled' && Array.isArray(blocksResult.value?.items)
          ? blocksResult.value.items.map((item) => normalizeBlock(item as never, chainId))
          : [],
      initialRecentTransactions:
        transactionsResult.status === 'fulfilled' && Array.isArray(transactionsResult.value?.items)
          ? serializeTransactions(
              transactionsResult.value.items.map((item) => normalizeTransaction(item as never, chainId)),
            )
          : [],
      initialTransactionTrend:
        trendResult.status === 'fulfilled' ? normalizeTransactionTrend(trendResult.value) : [],
      initialActivitySnapshot:
        activityResult.status === 'fulfilled' ? summarizeRecentTransactions(activityResult.value) : null,
      initialBridgeStatus:
        truthContextResult.status === 'fulfilled' ? truthContextResult.value.initialBridgeStatus : null,
      initialRelaySummary:
        truthContextResult.status === 'fulfilled' && truthContextResult.value.initialBridgeStatus
          ? summarizeMissionControlRelay(truthContextResult.value.initialBridgeStatus as never)
          : null,
    },
  }
}
