import { useEffect, useMemo, useState } from 'react'
import Link from 'next/link'
import { Card } from '@/libs/frontend-ui-primitives'
import {
  getMissionControlRelayLabel,
  getMissionControlRelays,
  missionControlApi,
  type MissionControlBridgeStatusResponse,
  type MissionControlRelayPayload,
  type MissionControlRelaySnapshot,
} from '@/services/api/missionControl'
import { statsApi, type ExplorerStats } from '@/services/api/stats'
import { explorerFeaturePages } from '@/data/explorerOperations'
import { summarizeChainActivity } from '@/utils/activityContext'
import ExplorerFreshnessDisclosure from '@/components/common/ExplorerFreshnessDisclosure'
import CompactMetricBar from '@/components/common/CompactMetricBar'
import DisclosureSection from '@/components/common/DisclosureSection'
import PaginationControls from '@/components/common/PaginationControls'
import MissionDeliveryModePanel from '@/components/common/MissionDeliveryModePanel'
import SubsystemPosturePanel from '@/components/common/SubsystemPosturePanel'
import { resolveEffectiveFreshness } from '@/utils/explorerFreshness'
import { bridgeRoutesApi, normalizeBridgeRouteEntries, type BridgeRoutesResponse } from '@/services/api/bridgeRoutes'
import { createVisibilityAwarePoller } from '@/utils/visibilityRefresh'
import { HOME_DASHBOARD_REFRESH_MS } from '@/utils/featuredTokens'
import BridgeLaneHealthPanel from '@/components/explorer/BridgeLaneHealthPanel'
import OperationsSurfaceNav from './OperationsSurfaceNav'
import OperationsActionGrid from './OperationsActionGrid'
import ClientRelativeTime from '@/components/common/ClientRelativeTime'

type FeedState = 'connecting' | 'live' | 'fallback'

interface RelayLaneCard {
  key: string
  label: string
  status: string
  profile: string
  sourceChain: string
  destinationChain: string
  queueSize: number
  processed: number
  failed: number
  lastPolledAt?: string | null
  bridgeAddress: string
  issueScope: string | null
  issueMessage: string | null
  inventoryShortfallWei: string | null
  inventoryRequiredWei: string | null
  inventoryAvailableWei: string | null
}

const relayOrder = ['mainnet_cw', 'mainnet_weth', 'bsc', 'avax', 'avax_cw', 'avax_to_138']
const BRIDGE_RELAY_PAGE_SIZE = 4

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

function resolveSnapshot(relay?: MissionControlRelayPayload): MissionControlRelaySnapshot | null {
  return relay?.url_probe?.body || relay?.file_snapshot || null
}

function relayPolicyCue(snapshot: MissionControlRelaySnapshot | null): string | null {
  if (!snapshot) return null
  if (snapshot.last_error?.scope === 'bridge_inventory') {
    return 'Queued release waiting on bridge inventory'
  }
  if (snapshot.last_error?.scope === 'bridge_inventory_probe') {
    return 'Bridge inventory check is temporarily unavailable'
  }
  if (String(snapshot.status || '').toLowerCase() === 'paused' && snapshot.monitoring?.delivery_enabled === false) {
    return 'Delivery disabled by policy'
  }
  return null
}

function laneToneClasses(status: string): string {
  const normalized = status.toLowerCase()
  if (['degraded', 'stale', 'stopped', 'down', 'snapshot-error'].includes(normalized)) {
    return 'border-red-200 bg-red-50/80 dark:border-red-900/60 dark:bg-red-950/20'
  }
  if (['paused', 'starting'].includes(normalized)) {
    return 'border-amber-200 bg-amber-50/80 dark:border-amber-900/60 dark:bg-amber-950/20'
  }
  return 'border-emerald-200 bg-emerald-50/80 dark:border-emerald-900/60 dark:bg-emerald-950/20'
}

function statusPillClasses(status: string): string {
  const normalized = status.toLowerCase()
  if (['degraded', 'stale', 'stopped', 'down', 'snapshot-error'].includes(normalized)) {
    return 'bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-100'
  }
  if (['paused', 'starting'].includes(normalized)) {
    return 'bg-amber-100 text-amber-800 dark:bg-amber-900/50 dark:text-amber-100'
  }
  return 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/50 dark:text-emerald-100'
}

function formatWeiToToken(value?: string | null): string {
  if (!value) return 'Unknown'
  try {
    const raw = BigInt(value)
    const whole = raw / 10n ** 18n
    const fractional = (raw % 10n ** 18n).toString().padStart(18, '0').slice(0, 6).replace(/0+$/, '')
    return fractional ? `${whole.toString()}.${fractional}` : whole.toString()
  } catch {
    return value
  }
}

function ActionLink({
  href,
  label,
  external,
}: {
  href: string
  label: string
  external?: boolean
}) {
  const className = 'inline-flex items-center text-sm font-semibold text-primary-600 hover:underline'
  const text = `${label} ->`

  if (external) {
    return (
      <a href={href} className={className} target="_blank" rel="noopener noreferrer">
        {text}
      </a>
    )
  }

  return (
    <Link href={href} className={className}>
      {text}
    </Link>
  )
}

export default function BridgeMonitoringPage({
  initialBridgeStatus = null,
  initialStats = null,
}: {
  initialBridgeStatus?: MissionControlBridgeStatusResponse | null
  initialStats?: ExplorerStats | null
}) {
  const [bridgeStatus, setBridgeStatus] = useState<MissionControlBridgeStatusResponse | null>(initialBridgeStatus)
  const [stats, setStats] = useState<ExplorerStats | null>(initialStats)
  const [bridgeRoutes, setBridgeRoutes] = useState<BridgeRoutesResponse | null>(null)
  const [feedState, setFeedState] = useState<FeedState>(initialBridgeStatus ? 'fallback' : 'connecting')
  const [relayPage, setRelayPage] = useState(1)
  const page = explorerFeaturePages.bridge

  useEffect(() => {
    let cancelled = false

    const loadSnapshot = async () => {
      try {
        const [snapshot, latestStats] = await Promise.all([
          missionControlApi.getBridgeStatus(),
          statsApi.get().catch(() => null),
        ])
        if (!cancelled) {
          setBridgeStatus(snapshot)
          if (latestStats) {
            setStats(latestStats)
          }
        }
      } catch (error) {
        if (!cancelled && process.env.NODE_ENV !== 'production') {
          console.warn('Failed to load bridge monitoring snapshot:', error)
        }
      }
    }

    loadSnapshot()

    const unsubscribe = missionControlApi.subscribeBridgeStatus(
      (status) => {
        if (!cancelled) {
          setBridgeStatus(status)
          setFeedState('live')
        }
      },
      (error) => {
        if (!cancelled) {
          setFeedState('fallback')
        }
        if (process.env.NODE_ENV !== 'production') {
          console.warn('Bridge monitoring live stream issue:', error)
        }
      }
    )

    return () => {
      cancelled = true
      unsubscribe()
    }
  }, [])

  useEffect(() => {
    let cancelled = false

    bridgeRoutesApi.getRoutesSafe().then(({ ok, data }) => {
      if (!cancelled && ok) {
        setBridgeRoutes(data)
      }
    })

    return () => {
      cancelled = true
    }
  }, [])

  useEffect(() => {
    if (feedState !== 'fallback') return

    let cancelled = false

    const refreshSnapshot = async () => {
      try {
        const snapshot = await missionControlApi.getBridgeStatus()
        if (!cancelled) {
          setBridgeStatus(snapshot)
        }
      } catch (error) {
        if (!cancelled && process.env.NODE_ENV !== 'production') {
          console.warn('Failed to refresh bridge monitoring snapshot:', error)
        }
      }
    }

    return createVisibilityAwarePoller({
      intervalMs: HOME_DASHBOARD_REFRESH_MS,
      task: refreshSnapshot,
    })
  }, [feedState])

  const routeEntries = useMemo(
    () => normalizeBridgeRouteEntries(bridgeRoutes?.routes),
    [bridgeRoutes?.routes],
  )

  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 relayLanes = useMemo((): RelayLaneCard[] => {
    const relays = getMissionControlRelays(bridgeStatus)
    if (!relays) return []

    const orderIndex = new Map(relayOrder.map((key, index) => [key, index]))

    return Object.entries(relays)
      .map(([key, relay]) => {
        const snapshot = resolveSnapshot(relay)
        const status = String(snapshot?.status || (relay.file_snapshot_error ? 'snapshot-error' : 'configured')).toLowerCase()
        return {
          key,
          label: getMissionControlRelayLabel(key),
          status:
            snapshot?.last_error?.scope === 'bridge_inventory'
              ? 'underfunded'
              : snapshot?.last_error?.scope === 'bridge_inventory_probe'
                ? 'warning'
                : status,
          profile: snapshot?.service?.profile || key,
          sourceChain: snapshot?.source?.chain_name || 'Unknown',
          destinationChain: snapshot?.destination?.chain_name || 'Unknown',
          queueSize: snapshot?.queue?.size ?? 0,
          processed: snapshot?.queue?.processed ?? 0,
          failed: snapshot?.queue?.failed ?? 0,
          lastPolledAt: snapshot?.last_source_poll?.at || null,
          bridgeAddress:
            snapshot?.destination?.relay_bridge_default ||
            snapshot?.destination?.relay_bridge ||
            snapshot?.source?.bridge_filter ||
            '',
          issueScope: snapshot?.last_error?.scope || null,
          issueMessage: snapshot?.last_error?.message || null,
          inventoryShortfallWei: snapshot?.last_error?.shortfall || null,
          inventoryRequiredWei: snapshot?.last_error?.required_amount || null,
          inventoryAvailableWei: snapshot?.last_error?.available_amount || null,
        }
      })
      .sort((left, right) => {
        const leftIndex = orderIndex.get(left.key) ?? Number.MAX_SAFE_INTEGER
        const rightIndex = orderIndex.get(right.key) ?? Number.MAX_SAFE_INTEGER
        return leftIndex - rightIndex || left.label.localeCompare(right.label)
      })
  }, [bridgeStatus])

  useEffect(() => {
    setRelayPage(1)
  }, [relayLanes.length])

  const relayPageCount = relayLanes.length ? Math.max(1, Math.ceil(relayLanes.length / BRIDGE_RELAY_PAGE_SIZE)) : 1
  const visibleRelayLanes = relayLanes.slice(
    (relayPage - 1) * BRIDGE_RELAY_PAGE_SIZE,
    relayPage * BRIDGE_RELAY_PAGE_SIZE,
  )

  const chainStatus = bridgeStatus?.data?.chains?.['138']
  const overallStatus = bridgeStatus?.data?.status || 'unknown'

  return (
    <div className="container mx-auto px-4 py-4 sm:py-6">
      <div className="mb-4 max-w-4xl">
        <div className="mb-2 inline-flex rounded-full border border-sky-200 bg-sky-50 px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-sky-700 dark:border-sky-900/50 dark:bg-sky-950/30 dark:text-sky-200">
          {page.eyebrow}
        </div>
        <h1 className="mb-2 text-2xl font-bold text-gray-900 dark:text-white sm:text-3xl">
          {page.title}
        </h1>
        <p className="text-sm leading-6 text-gray-600 dark:text-gray-400">
          {page.description}
        </p>
      </div>

      {page.note ? (
        <DisclosureSection title="Bridge scope note" defaultOpen={false} alwaysCollapsible className="mb-4">
          <Card className="border border-amber-200 bg-amber-50/70 dark:border-amber-900/50 dark:bg-amber-950/20">
            <p className="text-sm leading-6 text-amber-950 dark:text-amber-100">
              {page.note}
            </p>
          </Card>
        </DisclosureSection>
      ) : null}

      <OperationsSurfaceNav />

      <ExplorerFreshnessDisclosure
        context={activityContext}
        stats={stats}
        bridgeStatus={bridgeStatus}
        title="Freshness & delivery"
        activityTitle="Bridge recency"
        scopeLabel="Bridge relay posture on this page."
      >
        <MissionDeliveryModePanel className="mt-3" mode={bridgeStatus?.data?.mode} title="Bridge delivery mode" />
        <SubsystemPosturePanel
          className="mt-3"
          subsystems={bridgeStatus?.data?.subsystems}
          title="Bridge subsystem posture"
          preferredKeys={['rpc_head', 'tx_index', 'bridge_relay_monitoring', 'stats_summary', 'freshness_queries']}
          scopeLabel="Bridge-facing subsystem signals."
        />
      </ExplorerFreshnessDisclosure>

      <CompactMetricBar
        metrics={[
          { label: 'Fleet', value: overallStatus },
          { label: 'Lanes', value: String(relayLanes.length) },
          { label: 'Chain 138', value: chainStatus?.status || 'unknown' },
          { label: 'Feed', value: feedState === 'live' ? 'live' : feedState === 'fallback' ? 'snapshot' : 'connecting' },
        ]}
      />

      <DisclosureSection title="Relay lane detail" defaultOpen={false} alwaysCollapsible className="mb-4">
      <div className="grid gap-3 lg:grid-cols-2 xl:grid-cols-3">
        {visibleRelayLanes.map((lane) => (
          <Card key={lane.key} className={`border ${laneToneClasses(lane.status)}`}>
            <div className="flex items-start justify-between gap-3">
              <div>
                <div className="text-base font-semibold text-gray-900 dark:text-white">
                  {lane.label}
                </div>
                <div className="mt-0.5 text-xs text-gray-600 dark:text-gray-400">
                  {`${lane.sourceChain} -> ${lane.destinationChain}`}
                </div>
              </div>
              <div className={`rounded-full px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${statusPillClasses(lane.status)}`}>
                {lane.status}
              </div>
            </div>

            <div className="mt-3 grid grid-cols-2 gap-2 text-xs">
              <div>
                <div className="text-gray-500 dark:text-gray-400">Profile</div>
                <div className="font-medium text-gray-900 dark:text-white">{lane.profile}</div>
              </div>
              <div>
                <div className="text-gray-500 dark:text-gray-400">Queue</div>
                <div className="font-medium text-gray-900 dark:text-white">{lane.queueSize}</div>
              </div>
              <div>
                <div className="text-gray-500 dark:text-gray-400">Processed</div>
                <div className="font-medium text-gray-900 dark:text-white">{lane.processed}</div>
              </div>
              <div>
                <div className="text-gray-500 dark:text-gray-400">Failed</div>
                <div className="font-medium text-gray-900 dark:text-white">{lane.failed}</div>
              </div>
            </div>

            <div className="mt-4 text-sm text-gray-600 dark:text-gray-400">
              Last polled: <ClientRelativeTime value={lane.lastPolledAt} suffix=" ago" />
            </div>
            <div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
              Bridge: {shortAddress(lane.bridgeAddress)}
            </div>
            {relayPolicyCue(resolveSnapshot((getMissionControlRelays(bridgeStatus) || {})[lane.key])) ? (
              <div className="mt-3 text-xs font-medium uppercase tracking-wide text-amber-700 dark:text-amber-300">
                {relayPolicyCue(resolveSnapshot((getMissionControlRelays(bridgeStatus) || {})[lane.key]))}
              </div>
            ) : null}
            {lane.issueScope === 'bridge_inventory' ? (
              <div className="mt-3 rounded-2xl border border-amber-200 bg-amber-50/80 p-3 text-sm text-amber-950 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-100">
                <div className="font-semibold">Bridge inventory below required release amount</div>
                <div className="mt-1">
                  Shortfall: {formatWeiToToken(lane.inventoryShortfallWei)} WETH
                </div>
                <div className="mt-1 text-xs opacity-80">
                  Required: {formatWeiToToken(lane.inventoryRequiredWei)} WETH · Available: {formatWeiToToken(lane.inventoryAvailableWei)} WETH
                </div>
              </div>
            ) : null}
          </Card>
        ))}
      </div>
      {relayLanes.length > BRIDGE_RELAY_PAGE_SIZE ? (
        <PaginationControls
          className="mt-4"
          page={relayPage}
          pageCount={relayPageCount}
          onPageChange={setRelayPage}
          label="Relay lanes"
          ariaLabel="Bridge relay lane pagination"
        />
      ) : null}
      </DisclosureSection>

      <DisclosureSection title="Lane health panel" defaultOpen={false} alwaysCollapsible className="mb-4">
        <BridgeLaneHealthPanel laneHealth={bridgeStatus?.data?.bridge_lanes} />
      </DisclosureSection>

      {routeEntries.length > 0 ? (
        <DisclosureSection title="CCIP route catalog" defaultOpen={false} alwaysCollapsible className="mb-4">
        <Card title="CCIP route catalog">
          <p className="mb-4 text-sm text-gray-600 dark:text-gray-400">
            Destination bridge contracts from{' '}
            <code className="rounded bg-gray-100 px-1.5 py-0.5 text-xs dark:bg-gray-900">
              /token-aggregation/api/v1/bridge/routes
            </code>
            {bridgeRoutes?.lastModified ? (
                  <>
                    {' '}
                    (source: {bridgeRoutes.source} · updated <ClientRelativeTime value={bridgeRoutes.lastModified} suffix=" ago" />)
                  </>
                ) : bridgeRoutes?.source ? (
                  <> (source: {bridgeRoutes.source})</>
                ) : null}
            . Gnosis, Cronos, Celo, and Wemix lanes are aligned to deployed CCIP receivers — fund LINK on each remote bridge before live traffic.
          </p>
          <p className="mb-4 text-sm text-gray-600 dark:text-gray-400">
            Operator runbook:{' '}
            <Link href="/docs/public-api-access" className="text-primary-600 hover:underline">
              public API access
            </Link>{' '}
            · config-ready chain completion in repo{' '}
            <code className="rounded bg-gray-100 px-1.5 py-0.5 text-xs dark:bg-gray-900">CONFIG_READY_CHAINS_COMPLETION_RUNBOOK.md</code>
          </p>
          <div className="overflow-x-auto">
            <table className="min-w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 text-left text-xs uppercase tracking-wide text-gray-500 dark:border-gray-700 dark:text-gray-400">
                  <th className="py-2 pr-4">Bridge</th>
                  <th className="py-2 pr-4">Destination</th>
                  <th className="py-2">Contract</th>
                </tr>
              </thead>
              <tbody>
                {routeEntries.map((entry) => (
                  <tr key={`${entry.bridge}-${entry.destination}`} className="border-b border-gray-100 last:border-0 dark:border-gray-800">
                    <td className="py-2 pr-4 font-medium text-gray-900 dark:text-white">{entry.bridge}</td>
                    <td className="py-2 pr-4 text-gray-700 dark:text-gray-300">{entry.destination}</td>
                    <td className="py-2 font-mono text-xs text-gray-600 dark:text-gray-400">{entry.address}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </Card>
        </DisclosureSection>
      ) : null}

      <OperationsActionGrid actions={page.actions} className="mt-6" />
    </div>
  )
}
