import React, { useState } from 'react'
import FeatherIcon from 'feather-icons-react'
import classnames from 'classnames'
import { DateTime } from 'luxon'
import {
  Card,
  ButtonLink,
  ExternalLink,
  LoadingDots,
  LinkTheme
} from '@pooltogether/react-components'
import { Trans, useTranslation } from 'react-i18next'

import { PROPOSAL_STATUS } from 'lib/constants'
import { CountDown } from 'lib/components/CountDown'
import { SORTED_STATES, useAllProposalsSorted } from 'lib/hooks/useAllProposalsSorted'
import { useProposalData } from 'lib/hooks/useProposalData'
import { msToSeconds } from 'lib/utils/msToSeconds'

import EmptyBox from 'assets/images/empty-box.png'
import Link from 'next/link'

export const ProposalsList = (props) => {
  const { proposalStates } = props
  const { isFetched, sortedProposals, error } = useAllProposalsSorted()

  if (error) {
    return <ErrorLoadingProposalsList />
  }

  if (!isFetched) {
    return <LoadingProposalsList />
  }

  const proposals = []
  proposalStates.forEach((proposalState) => {
    proposals.push(...sortedProposals[proposalState])
  })

  if (proposals.length === 0) {
    return <EmptyProposalsList />
  }

  return (
    <ProposalListContainer>
      {proposals.map((p) => (
        <ProposalItem key={p.id} proposal={p} />
      ))}
    </ProposalListContainer>
  )
}

export const ProposalListContainer = (props) => <ol className='mb-8 sm:mb-16'>{props.children}</ol>

export const LoadingProposalsList = () => (
  <div className='w-full flex flex-col justify-center p-12 sm:p-24 '>
    <LoadingDots className='mx-auto' />
  </div>
)

export const ErrorLoadingProposalsList = () => (
  <div className='w-full flex flex-col justify-center p-12 sm:p-24 text-center'>
    <FeatherIcon icon='alert-triangle' className='w-12 h-12 mb-4 text-orange mx-auto' />
    <p>
      <Trans i18nKey='errorLoadingProposals' />
    </p>
  </div>
)

export const ProposalItemContainer = (props) => (
  <li className='mb-6 last:mb-0'>
    <Card>{props.children}</Card>
  </li>
)

export const ProposalItem = (props) => {
  const { proposal } = props

  const { t } = useTranslation()

  const { title, id } = proposal

  return (
    <ProposalItemContainer>
      <div className='flex justify-between flex-col-reverse sm:flex-row'>
        <div>
          <h6 className='leading-none mb-2 mt-2 sm:mt-0 break-words'>{title}</h6>
          <p className='mb-4'>{t('proposalId', { id })}</p>
        </div>
        <ProposalStatus proposal={proposal} />
      </div>
      <ViewProposalButton proposal={proposal} />
    </ProposalItemContainer>
  )
}

export const ProposalStatus = (props) => {
  const { proposal } = props

  const { t } = useTranslation()
  const { status } = proposal

  let statusValue
  switch (status) {
    case PROPOSAL_STATUS.executed:
    case PROPOSAL_STATUS.succeeded:
    case PROPOSAL_STATUS.active:
    case PROPOSAL_STATUS.queued: {
      statusValue = 1
      break
    }
    case PROPOSAL_STATUS.expired:
    case PROPOSAL_STATUS.defeated:
    case PROPOSAL_STATUS.cancelled: {
      statusValue = -1
      break
    }
    default:
    case PROPOSAL_STATUS.pending: {
      statusValue = 0
      break
    }
  }

  let icon
  if (statusValue < 0) {
    icon = 'x-circle'
  } else if (statusValue > 0) {
    icon = 'check-circle'
  }

  const showIcon = status !== PROPOSAL_STATUS.active && status !== PROPOSAL_STATUS.pending

  if (status === PROPOSAL_STATUS.active) {
    return <ProposalCountDown proposal={proposal} />
  }

  return (
    <div
      className={classnames(
        'sm:ml-auto text-white sm:ml-0 mb-2 sm:mb-0 flex items-center rounded-lg px-2 py-1 w-fit-content h-fit-content bg-tertiary whitespace-no-wrap',
        {
          'text-orange': statusValue < 0,
          'text-highlight-9': statusValue > 0,
          'text-inverse': statusValue === 0
        }
      )}
    >
      {proposal.endDate && (
        <div className='sm:pl-4 mr-2 sm:mr-4 sm:text-right' style={{ minWidth: 104 }}>
          {proposal.endDate.toLocaleString(DateTime.DATE_MED)}
        </div>
      )}
      {icon && showIcon && (
        <FeatherIcon icon={icon} className='mr-2 stroke-current w-3 h-3 sm:w-4 sm:h-4' />
      )}
      <div className='sm:pr-4 font-bold capitalized'>{t(status)}</div>
    </div>
  )
}

const ProposalCountDown = (props) => {
  const { proposal } = props

  const [seconds] = useState(proposal.endDateSeconds - msToSeconds(Date.now()).toNumber())
  const { refetch } = useProposalData(proposal.id)

  return (
    <CountDown className='sm:ml-auto sm:w-unset mb-4 sm:mb-0' seconds={seconds} onZero={refetch} />
  )
}

const ViewProposalButton = (props) => {
  const { proposal } = props

  const { t } = useTranslation()
  const { status, id } = proposal

  if (status === PROPOSAL_STATUS.active) {
    return (
      <ButtonLink
        Link={Link}
        href={'/proposals/[id]/'}
        as={`/proposals/${id}/`}
        border='green'
        text='primary'
        bg='green'
        hoverBorder='green'
        hoverText='primary'
        hoverBg='green'
      >
        {t('voteNow')}
      </ButtonLink>
    )
  }

  return (
    <ButtonLink Link={Link} textSize='xxs' href={'/proposals/[id]/'} as={`/proposals/${id}/`}>
      {t('viewProposal')}
    </ButtonLink>
  )
}

export const EmptyProposalsList = () => {
  const { t } = useTranslation()

  return (
    <Card className='mb-6'>
      <img src={EmptyBox} className='mx-auto w-16 h-16 sm:w-auto sm:h-auto my-4 sm:my-8' />
      <h4 className='mt-4 mb-2 text-center text-accent-1'>{t('noActiveProposalsAtTheMoment')}</h4>
      <p className='text-center text-accent-1 mb-4 sm:mb-6'>
        <Trans
          i18nKey='discussIdeasOnDiscordOrDiscourse'
          components={{
            LinkToDiscord: (
              <ExternalLink
                theme={LinkTheme.light}
                underline
                href='https://discord.gg/hxPhPDW'
                title='Discord'
              />
            ),
            LinkToDiscourse: (
              <ExternalLink
                theme={LinkTheme.light}
                underline
                href='https://gov.pooltogether.com/'
                title='Discourse'
              />
            )
          }}
        />
      </p>
    </Card>
  )
}