import type { TokenListToken } from './config'
import type { MissionControlLiquidityPool, RouteMatrixResponse, RouteMatrixRoute } from './routes'
import type { PlannerCapabilitiesResponse, PlannerProviderCapability } from './planner'

export const featuredLiquiditySymbols = ['cUSDT', 'cUSDC', 'USDT', 'USDC', 'cXAUC', 'cEURT', 'WETH10']

export interface FeaturedLiquidityToken {
  symbol: string
  address: string
  name?: string
}

export interface AggregatedLiquidityPool extends MissionControlLiquidityPool {
  sourceSymbols: string[]
}

export function selectFeaturedLiquidityTokens(tokens: TokenListToken[] = []): FeaturedLiquidityToken[] {
  const selected = new Map<string, FeaturedLiquidityToken>()

  for (const symbol of featuredLiquiditySymbols) {
    const token = tokens.find(
      (entry) => entry.chainId === 138 && entry.symbol === symbol && typeof entry.address === 'string' && entry.address.trim().length > 0
    )

    if (token?.address) {
      selected.set(symbol, {
        symbol,
        address: token.address,
        name: token.name,
      })
    }
  }

  return Array.from(selected.values())
}

export function aggregateLiquidityPools(
  records: Array<{ symbol: string; pools: MissionControlLiquidityPool[] }>
): AggregatedLiquidityPool[] {
  const merged = new Map<string, AggregatedLiquidityPool>()

  for (const record of records) {
    for (const pool of record.pools || []) {
      if (!pool.address) continue
      const key = pool.address.toLowerCase()
      const existing = merged.get(key)

      if (existing) {
        if (!existing.sourceSymbols.includes(record.symbol)) {
          existing.sourceSymbols.push(record.symbol)
        }
        if ((pool.tvl || 0) > (existing.tvl || 0)) {
          existing.tvl = pool.tvl
        }
      } else {
        merged.set(key, {
          ...pool,
          sourceSymbols: [record.symbol],
        })
      }
    }
  }

  return Array.from(merged.values()).sort((left, right) => {
    const tvlDelta = (right.tvl || 0) - (left.tvl || 0)
    if (tvlDelta !== 0) return tvlDelta
    return (left.address || '').localeCompare(right.address || '')
  })
}

export function getRouteBackedPoolAddresses(routeMatrix: RouteMatrixResponse | null | undefined): string[] {
  const addresses = new Set<string>()

  for (const route of routeMatrix?.liveRoutes || []) {
    for (const leg of route.legs || []) {
      if (leg.poolAddress) {
        addresses.add(leg.poolAddress.toLowerCase())
      }
    }
  }

  return Array.from(addresses)
}

export function getTopLiquidityRoutes(
  routeMatrix: RouteMatrixResponse | null | undefined,
  limit = 8
): RouteMatrixRoute[] {
  const liveRoutes = routeMatrix?.liveRoutes || []
  return [...liveRoutes]
    .filter((route) => route.routeType === 'swap')
    .sort((left, right) => {
      const leftPools = (left.legs || []).filter((leg) => leg.poolAddress).length
      const rightPools = (right.legs || []).filter((leg) => leg.poolAddress).length
      if (leftPools !== rightPools) return rightPools - leftPools
      return (left.label || left.routeId).localeCompare(right.label || right.routeId)
    })
    .slice(0, limit)
}

export function getLivePlannerProviders(
  capabilities: PlannerCapabilitiesResponse | null | undefined
): PlannerProviderCapability[] {
  return (capabilities?.providers || []).filter((provider) => provider.live)
}
