import React, { useState } from 'react'
import Cookies from 'js-cookie'
import Link from 'next/link'
import { motion } from 'framer-motion'
import { useRouter } from 'next/router'
import { useInterval } from 'beautiful-react-hooks'
import { usePoolBySymbol, useRouterChainId } from '@pooltogether/hooks'
import { useOnboard } from '@pooltogether/bnc-onboard-hooks'
import { PageTitleAndBreadcrumbs } from '@pooltogether/react-components'
import { Button } from '@pooltogether/react-components'
import { Trans, useTranslation } from 'react-i18next'

import {
  COOKIE_OPTIONS,
  SHOW_MANAGE_LINKS,
  WIZARD_REFERRER_HREF,
  WIZARD_REFERRER_AS_PATH
} from 'lib/constants'
import { AddTokenToMetaMaskButton } from 'lib/components/AddTokenToMetaMaskButton'
import { BlockExplorerLink } from 'lib/components/BlockExplorerLink'
import { PoolShowLootBoxTable } from 'lib/components/LootBoxTable'
import { PoolChartsCard } from 'lib/components/PoolChartsCard'
import { PastWinnersCard } from 'lib/components/PastWinnersCard'
import { PrizePlayersQuery } from 'lib/components/PrizePlayersQuery'
import { PrizePlayerListing } from 'lib/components/PrizePlayerListing'
import { PoolPrizeCard } from 'lib/components/PoolPrizeCard'
import { PoolStats } from 'lib/components/PoolStats'
import { PoolShowUILoader } from 'lib/components/loaders/PoolShowUILoader'
import { SablierStreamCard } from 'lib/components/SablierStreamCard'
import { UpcomingPrizeBreakdownCard } from 'lib/components/UpcomingPrizeBreakdownCard'
import { Meta } from 'lib/components/Meta'
import { RevokePoolAllowanceTxButton } from 'lib/components/RevokePoolAllowanceTxButton'
import { useIsPoolYieldSourceKnown } from 'lib/hooks/useIsPoolYieldSourceKnown'
import { useReducedMotion } from 'lib/hooks/useReducedMotion'
import { translatedPoolName } from 'lib/utils/translatedPoolName'
import { getNetworkNiceNameByChainId } from 'lib/utils/networks'

import Bell from 'assets/images/[email protected]'
import { PRIZE_POOL_TYPES } from '@pooltogether/current-pool-data'
import { NETWORK } from '@pooltogether/utilities'
import classNames from 'classnames'

const SOHM_PRIZE_POOL_ADDRESS = '0xeab695a8f5a44f583003a8bc97d677880d528248'
const ETH_POOL_PRIZE_POOL_ADDRESS = '0x396b4489da692788e327e2e4b2b0459a5ef26791'
const POLYGON_POOL_PRIZE_POOL_ADDRESS = '0x2ac049f07d56ed04f84ff80022a71a1a2d8ce19b'

const poolsToAllow = [
  SOHM_PRIZE_POOL_ADDRESS,
  ETH_POOL_PRIZE_POOL_ADDRESS,
  POLYGON_POOL_PRIZE_POOL_ADDRESS
]

export const PoolShow = (props) => {
  const { t } = useTranslation()
  const router = useRouter()
  const shouldReduceMotion = useReducedMotion()
  const chainId = useRouterChainId(router)

  const { data: pool, isFetched: poolIsFetched } = usePoolBySymbol(chainId, router?.query?.symbol)
  const { address: usersAddress, walletName } = useOnboard()
  const [cookieShowAward, setCookieShowAward] = useState(false)

  useInterval(() => {
    setCookieShowAward(Cookies.get(SHOW_MANAGE_LINKS))
  }, 1000)

  if (!poolIsFetched) {
    return <PoolShowUILoader />
  }

  const handleGetTicketsClick = (e) => {
    e.preventDefault()

    Cookies.set(WIZARD_REFERRER_HREF, '/pools/[networkName]/[symbol]', COOKIE_OPTIONS)
    Cookies.set(
      WIZARD_REFERRER_AS_PATH,
      `/pools/${pool.networkName}/${pool.symbol}`,
      COOKIE_OPTIONS
    )

    router.push(
      `/pools/[networkName]/[symbol]/deposit`,
      `/pools/${pool.networkName}/${pool.symbol}/deposit`,
      {
        shallow: true
      }
    )
  }

  const isDepositsEnabled =
    chainId === NETWORK.celo || poolsToAllow.includes(pool.prizePool?.address)

  return (
    <>
      <Meta title={pool.name} />

      <motion.div
        initial='initial'
        animate='enter'
        exit='exit'
        variants={{
          exit: {
            scale: 0.9,
            y: 10,
            opacity: 0,
            transition: {
              duration: shouldReduceMotion ? 0 : 0.5,
              staggerChildren: shouldReduceMotion ? 0 : 0.1
            }
          },
          enter: {
            transition: {
              duration: shouldReduceMotion ? 0 : 0.5,
              staggerChildren: shouldReduceMotion ? 0 : 0.1
            }
          },
          initial: {
            y: 0,
            opacity: 1,
            transition: {
              duration: shouldReduceMotion ? 0 : 0.2
            }
          }
        }}
      >
        <div className='flex flex-col sm:flex-row justify-between sm:items-center mb-4 sm:mb-10'>
          <div className='flex justify-between items-center sm:w-9/12 lg:w-7/12'>
            <PageTitleAndBreadcrumbs
              t={t}
              showPrizeFrequencyChip
              Link={Link}
              title={translatedPoolName(t, pool.name)}
              pool={pool}
              breadcrumbs={[
                {
                  href: '/pools',
                  as: '/pools',
                  name: t('pools')
                },
                {
                  href: '/pools/[networkName]',
                  as: `/pools/${pool.networkName}`,
                  name: getNetworkNiceNameByChainId(pool.chainId)
                },
                {
                  name: translatedPoolName(t, pool.name)
                }
              ]}
            />
          </div>

          <div
            className={classNames(
              'flex sm:w-3/12 lg:w-5/12 sm:justify-end items-start mt-4 sm:mt-0',
              { 'cursor-not-allowed': !isDepositsEnabled }
            )}
          >
            <Button
              id='_getTickets'
              width='w-full sm:w-full lg:w-6/12'
              textSize='lg'
              onClick={handleGetTicketsClick}
              disabled={!Boolean(pool.symbol) || !isDepositsEnabled}
            >
              {t('deposit')}
            </Button>
          </div>
        </div>

        <RebasingWarning pool={pool} />

        <V3Warning pool={pool} isDepositsEnabled={isDepositsEnabled} />

        <PoolPrizeCard pool={pool} />

        <UpcomingPrizeBreakdownCard pool={pool} />

        <PoolShowLootBoxTable pool={pool} />

        <SablierStreamCard pool={pool} />

        <PoolStats pool={pool} />

        <PoolChartsCard pool={pool} />

        <PastWinnersCard pool={pool} />

        <PrizePlayersQuery pool={pool} blockNumber={-1}>
          {({ data, isFetched }) => {
            return (
              <PrizePlayerListing
                baseAsPath={`/pools/${pool.networkName}/${pool.symbol}`}
                baseHref='/pools/[networkName]/[symbol]'
                isFetched={isFetched}
                balances={data}
                pool={pool}
              />
            )
          }}
        </PrizePlayersQuery>

        <div className='flex flex-col  items-center justify-center mt-10'>
          {walletName === 'MetaMask' && pool?.tokens && (
            <div className='m-2'>
              <AddTokenToMetaMaskButton
                noAnim
                textSize='xxxs'
                tokenAddress={pool.tokens.ticket.address}
                tokenDecimals={pool.tokens.ticket.decimals}
                tokenSymbol={pool.tokens.ticket.symbol}
              />
            </div>
          )}

          <div className='m-2'>
            <BlockExplorerLink address={pool?.prizePool?.address} chainId={pool.chainId}>
              {t('viewPoolInEtherscan')}
            </BlockExplorerLink>
          </div>

          <div className='m-2'>
            <BlockExplorerLink
              address={pool?.tokens?.underlyingToken.address}
              chainId={pool?.chainId}
            >
              {t('viewDepositTokenOnEtherscan')}
            </BlockExplorerLink>
          </div>

          {usersAddress && <RevokePoolAllowanceTxButton pool={pool} />}

          {cookieShowAward && (
            <>
              <div className='m-2'>
                <Link
                  textSize='xxxs'
                  href='/pools/[networkName]/[symbol]/manage'
                  as={`/pools/${pool.networkName}/${pool.symbol}/manage`}
                >
                  {t('managePool')}
                </Link>
              </div>
            </>
          )}
        </div>
      </motion.div>
    </>
  )
}

const RebasingWarning = (props) => {
  const { t } = useTranslation()
  const { pool } = props

  const rebasing = pool.prizePool?.address === SOHM_PRIZE_POOL_ADDRESS
  if (!rebasing) {
    return null
  }

  return (
    <div className='text-center bg-default rounded-lg mt-4 pt-4 pb-2 xs:py-4 px-4 text-orange'>
      <div className='flex flex-col xs:flex-row items-center justify-center'>
        <div className='mb-2 xs:mb-0 xs:mr-4'>
          <img className='shake' src={Bell} width='20' height='20' />
        </div>
        {t('rebasingPoolWarning', 'This prize pool uses a rebasing token to generate the prize.')}
      </div>

      <a
        target='_blank'
        rel='noreferrer noopener'
        href='https://academy.binance.com/en/articles/elastic-supply-tokens-explained'
        className='underline text-xs'
      >
        {t('learnMore', 'Learn more')}
      </a>
    </div>
  )
}

const V3Warning = (props) => {
  const { isDepositsEnabled } = props

  if (isDepositsEnabled) {
    return null
  }

  return (
    <div className='text-center bg-default rounded-lg mt-4 pt-4 pb-2 xs:py-4 px-4 text-orange'>
      <div className='flex flex-col xs:flex-row items-center justify-center'>
        <div className='mb-2 xs:mb-0 xs:mr-4'>
          <img className='shake' src={Bell} width='20' height='20' />
        </div>

        <span>
          <Trans
            i18nKey='v3BannerWarning'
            components={{
              a: (
                <a
                  href='http://app.pooltogether.com'
                  className='underline text-xs'
                  target='_blank'
                  rel='noopener noreferrer'
                />
              )
            }}
          />
        </span>
      </div>
    </div>
  )
}