import { t } from '@lingui/macro'
import { Trade } from '@uniswap/router-sdk'
import { Currency, Percent, TradeType } from '@uniswap/sdk-core'
import { useAtom } from 'jotai'
import { integratorFeeAtom, MIN_HIGH_SLIPPAGE } from 'lib/state/settings'
import { Color, ThemedText } from 'lib/theme'
import { useMemo } from 'react'
import { currencyId } from 'utils/currencyId'
import { computeRealizedLPFeePercent } from 'utils/prices'

import Row from '../../Row'

interface DetailProps {
  label: string
  value: string
  color?: Color
}

function Detail({ label, value, color }: DetailProps) {
  return (
    <ThemedText.Caption color={color}>
      <Row gap={2}>
        <span>{label}</span>
        <span style={{ whiteSpace: 'nowrap' }}>{value}</span>
      </Row>
    </ThemedText.Caption>
  )
}

interface DetailsProps {
  trade: Trade<Currency, Currency, TradeType>
  allowedSlippage: Percent
}

export default function Details({ trade, allowedSlippage }: DetailsProps) {
  const { inputAmount, outputAmount } = trade
  const inputCurrency = inputAmount.currency
  const outputCurrency = outputAmount.currency

  const integrator = window.location.hostname
  const [integratorFee] = useAtom(integratorFeeAtom)

  const priceImpact = useMemo(() => {
    const realizedLpFeePercent = computeRealizedLPFeePercent(trade)
    return trade.priceImpact.subtract(realizedLpFeePercent)
  }, [trade])

  const details = useMemo(() => {
    // @TODO(ianlapham): Check that provider fee is even a valid list item
    return [
      // [t`Liquidity provider fee`, `${swap.lpFee} ${inputSymbol}`],
      [t`${integrator} fee`, integratorFee && `${integratorFee} ${currencyId(inputCurrency)}`],
      [t`Price impact`, `${priceImpact.toFixed(2)}%`],
      trade.tradeType === TradeType.EXACT_INPUT
        ? [t`Maximum sent`, `${trade.maximumAmountIn(allowedSlippage).toSignificant(6)} ${inputCurrency.symbol}`]
        : [],
      trade.tradeType === TradeType.EXACT_OUTPUT
        ? [t`Minimum received`, `${trade.minimumAmountOut(allowedSlippage).toSignificant(6)} ${outputCurrency.symbol}`]
        : [],
      [
        t`Slippage tolerance`,
        `${allowedSlippage.toFixed(2)}%`,
        allowedSlippage.greaterThan(MIN_HIGH_SLIPPAGE) && 'warning',
      ],
    ].filter(isDetail)

    function isDetail(detail: unknown[]): detail is [string, string, Color | undefined] {
      return Boolean(detail[1])
    }
  }, [allowedSlippage, inputCurrency, integrator, integratorFee, outputCurrency.symbol, priceImpact, trade])
  return (
    <>
      {details.map(([label, detail, color]) => (
        <Detail key={label} label={label} value={detail} color={color} />
      ))}
    </>
  )
}
