import { DotsHorizontalIcon } from '@heroicons/react/outline'
import clsx from 'clsx'
import dayjs from 'dayjs'
import { useState } from 'react'
import { capitalize } from 'lodash'

import { Contract } from 'common/contract'
import { formatMoney, formatPercent } from 'common/util/format'
import { contractPool, updateContract } from 'web/lib/firebase/contracts'
import { Col } from '../layout/col'
import { Modal } from '../layout/modal'
import { Title } from '../title'
import { InfoTooltip } from '../info-tooltip'
import { useAdmin, useDev } from 'web/hooks/use-admin'
import { SiteLink } from '../site-link'
import { firestoreConsolePath } from 'common/envs/constants'
import { deleteField } from 'firebase/firestore'
import ShortToggle from '../widgets/short-toggle'
import { DuplicateContractButton } from '../duplicate-contract-button'
import { Row } from '../layout/row'
import { BETTORS, User } from 'common/user'
import { IconButton } from '../button'
import { AddLiquidityButton } from './add-liquidity-button'
import { Tooltip } from '../tooltip'
import { Table } from '../table'

export function ContractInfoDialog(props: {
  contract: Contract
  user: User | null | undefined
  className?: string
}) {
  const { contract, className, user } = props

  const [open, setOpen] = useState(false)
  const [featured, setFeatured] = useState(
    (contract?.featuredOnHomeRank ?? 0) > 0
  )
  const isDev = useDev()
  const isAdmin = useAdmin()
  const isCreator = user?.id === contract.creatorId
  const isUnlisted = contract.visibility === 'unlisted'
  const wasUnlistedByCreator = contract.unlistedById
    ? contract.unlistedById === contract.creatorId
    : false

  const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a')

  const {
    createdTime,
    closeTime,
    resolutionTime,
    uniqueBettorCount,
    mechanism,
    outcomeType,
    id,
    elasticity,
    pool,
  } = contract

  const typeDisplay =
    outcomeType === 'BINARY'
      ? 'YES / NO'
      : outcomeType === 'FREE_RESPONSE'
      ? 'Free response'
      : outcomeType === 'MULTIPLE_CHOICE'
      ? 'Multiple choice'
      : 'Numeric'

  const onFeaturedToggle = async (enabled: boolean) => {
    if (
      enabled &&
      (contract.featuredOnHomeRank === 0 || !contract?.featuredOnHomeRank)
    ) {
      await updateContract(id, { featuredOnHomeRank: 1 })
      setFeatured(true)
    } else if (!enabled && (contract?.featuredOnHomeRank ?? 0) > 0) {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      await updateContract(id, { featuredOnHomeRank: deleteField() })
      setFeatured(false)
    }
  }

  return (
    <>
      <Tooltip text="Market details" placement="bottom" noTap noFade>
        <IconButton
          size="2xs"
          className={clsx(className)}
          onClick={() => setOpen(true)}
        >
          <DotsHorizontalIcon
            className={clsx('h-5 w-5 flex-shrink-0')}
            aria-hidden="true"
          />
        </IconButton>

        <Modal open={open} setOpen={setOpen}>
          <Col className="gap-4 rounded bg-white p-6">
            <Title className="!mt-0 !mb-0" text="This Market" />

            <Table>
              <tbody>
                <tr>
                  <td>Type</td>
                  <td>{typeDisplay}</td>
                </tr>

                <tr>
                  <td>Payout</td>
                  <td className="flex gap-1">
                    {mechanism === 'cpmm-1' ? (
                      <>
                        Fixed{' '}
                        <InfoTooltip text="Each YES share is worth M$1 if YES wins." />
                      </>
                    ) : (
                      <>
                        Parimutuel{' '}
                        <InfoTooltip text="Each share is a fraction of the pool. " />
                      </>
                    )}
                  </td>
                </tr>

                <tr>
                  <td>Market created</td>
                  <td>{formatTime(createdTime)}</td>
                </tr>

                {closeTime && (
                  <tr>
                    <td>Market close{closeTime > Date.now() ? 's' : 'd'}</td>
                    <td>{formatTime(closeTime)}</td>
                  </tr>
                )}

                {resolutionTime && (
                  <tr>
                    <td>Market resolved</td>
                    <td>{formatTime(resolutionTime)}</td>
                  </tr>
                )}

                <tr>
                  <td>
                    <span className="mr-1">Volume</span>
                    <InfoTooltip text="Total amount bought or sold" />
                  </td>
                  <td>{formatMoney(contract.volume)}</td>
                </tr>

                <tr>
                  <td>{capitalize(BETTORS)}</td>
                  <td>{uniqueBettorCount ?? '0'}</td>
                </tr>

                <tr>
                  <td>
                    <Row>
                      <span className="mr-1">Elasticity</span>
                      <InfoTooltip
                        text={
                          mechanism === 'cpmm-1'
                            ? 'Probability change between a M$50 bet on YES and NO'
                            : 'Probability change from a M$100 bet'
                        }
                      />
                    </Row>
                  </td>
                  <td>{formatPercent(elasticity)}</td>
                </tr>

                <tr>
                  <td>Liquidity subsidies</td>
                  <td>
                    {mechanism === 'cpmm-1'
                      ? formatMoney(contract.totalLiquidity)
                      : formatMoney(100)}
                  </td>
                </tr>

                <tr>
                  <td>Pool</td>
                  <td>
                    {mechanism === 'cpmm-1' && outcomeType === 'BINARY'
                      ? `${Math.round(pool.YES)} YES, ${Math.round(pool.NO)} NO`
                      : mechanism === 'cpmm-1' &&
                        outcomeType === 'PSEUDO_NUMERIC'
                      ? `${Math.round(pool.YES)} HIGHER, ${Math.round(
                          pool.NO
                        )} LOWER`
                      : contractPool(contract)}
                  </td>
                </tr>

                {/* Show a path to Firebase if user is an admin, or we're on localhost */}
                {(isAdmin || isDev) && (
                  <tr>
                    <td>[ADMIN] Firestore</td>
                    <td>
                      <SiteLink href={firestoreConsolePath(id)}>
                        Console link
                      </SiteLink>
                    </td>
                  </tr>
                )}
                {isAdmin && (
                  <tr>
                    <td>[ADMIN] Featured</td>
                    <td>
                      <ShortToggle
                        on={featured}
                        setOn={setFeatured}
                        onChange={onFeaturedToggle}
                      />
                    </td>
                  </tr>
                )}
                {user && (
                  <tr>
                    <td>{isAdmin ? '[ADMIN]' : ''} Unlisted</td>
                    <td>
                      <ShortToggle
                        disabled={
                          isUnlisted
                            ? !(isAdmin || (isCreator && wasUnlistedByCreator))
                            : !(isCreator || isAdmin)
                        }
                        on={contract.visibility === 'unlisted'}
                        setOn={(b) =>
                          updateContract(id, {
                            visibility: b ? 'unlisted' : 'public',
                            unlistedById: b ? user.id : '',
                          })
                        }
                      />
                    </td>
                  </tr>
                )}
              </tbody>
            </Table>

            <Row className="flex-wrap">
              {mechanism === 'cpmm-1' && (
                <AddLiquidityButton contract={contract} className="mr-2" />
              )}
              <DuplicateContractButton contract={contract} />
            </Row>
          </Col>
        </Modal>
      </Tooltip>
    </>
  )
}