import { TFunction } from 'i18next'
import { PropsWithChildren, useMemo } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Flex, Text } from 'ui/src'
import { Flag } from 'ui/src/components/icons/Flag'
import { CurrencyInfo, TokenList } from 'uniswap/src/features/dataApi/types'
import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext'
import { WarningModalInfoContainer } from 'uniswap/src/features/tokens/WarningInfoModalContainer'
import { TokenProtectionWarning, getFeeColor } from 'uniswap/src/features/tokens/safetyUtils'

function getWarningFlags({
  currencyInfo,
  formatPercent,
  t,
  tokenProtectionWarning,
}: {
  currencyInfo: CurrencyInfo
  formatPercent: (value: Maybe<string | number>) => string
  t: TFunction
  tokenProtectionWarning: TokenProtectionWarning
}): JSX.Element[] {
  const flags: JSX.Element[] = []

  const isToken = currencyInfo.currency.isToken

  if (isToken && currencyInfo.currency.buyFeeBps) {
    const buyFeePercent = currencyInfo.currency.buyFeeBps.toNumber() / 100
    const buyFeeColor = getFeeColor(buyFeePercent)

    flags.push(
      <WarningFlag key="buy-fee">
        <Trans
          i18nKey="token.safety.warning.feeDescription"
          components={{
            fee: (
              <Text variant="body3" color={buyFeeColor}>
                {formatPercent(buyFeePercent)} {t('common.fee').toLowerCase()}
              </Text>
            ),
          }}
          values={{
            action: t('common.bought').toLowerCase(),
          }}
        />
      </WarningFlag>,
    )
  }

  if (isToken && currencyInfo.currency.sellFeeBps) {
    const sellFeePercent = currencyInfo.currency.sellFeeBps.toNumber() / 100
    const sellFeeColor = getFeeColor(sellFeePercent)

    flags.push(
      <WarningFlag key="sell-fee">
        <Trans
          i18nKey="token.safety.warning.feeDescription"
          components={{
            fee: (
              <Text variant="body3" color={sellFeeColor}>
                {formatPercent(sellFeePercent)} {t('common.fee').toLowerCase()}
              </Text>
            ),
          }}
          values={{
            action: t('common.sold').toLowerCase(),
          }}
        />
      </WarningFlag>,
    )
  }

  if (tokenProtectionWarning === TokenProtectionWarning.SpamAirdrop) {
    flags.push(<WarningFlag key="spam-warning">{t('token.safety.warning.spamsUsers')}</WarningFlag>)
  }

  if (tokenProtectionWarning === TokenProtectionWarning.MaliciousImpersonator) {
    flags.push(<WarningFlag key="impersonator-warning">{t('token.safety.warning.impersonator')}</WarningFlag>)
  }

  if (tokenProtectionWarning === TokenProtectionWarning.MaliciousGeneral) {
    flags.push(
      <WarningFlag key="malicious-general-warning">{t('token.safety.warning.flaggedAsMalicious')}</WarningFlag>,
    )
  }

  if (currencyInfo.safetyInfo?.tokenList === TokenList.NonDefault) {
    flags.push(<WarningFlag key="exchange-warning">{t('token.safety.warning.notListedOnExchanges')}</WarningFlag>)
  }

  return flags
}

function WarningFlag({ children }: PropsWithChildren): JSX.Element {
  return (
    <Flex row width="100%" alignItems="center" justifyContent="flex-start" gap="$spacing8">
      <Flag size="$icon.16" color="$neutral2" />
      <Text variant="body3" color="$neutral2">
        {children}
      </Text>
    </Flex>
  )
}

export function TokenWarningFlagsTable({
  currencyInfo,
  tokenProtectionWarning,
}: {
  currencyInfo: CurrencyInfo
  tokenProtectionWarning: TokenProtectionWarning
}): JSX.Element | null {
  const { t } = useTranslation()
  const { formatPercent } = useLocalizationContext()
  const flags = useMemo(
    () => getWarningFlags({ currencyInfo, formatPercent, t, tokenProtectionWarning }),
    [currencyInfo, formatPercent, t, tokenProtectionWarning],
  )

  if (flags.length === 0) {
    return null
  }

  return (
    <WarningModalInfoContainer gap="$spacing8" py="$spacing12">
      {flags}
    </WarningModalInfoContainer>
  )
}
