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 { Button } from '../button'
import { AddLiquidityButton } from './add-liquidity-button'
import { Table } from '../table'

export const contractDetailsButtonClassName =
  'group flex items-center rounded-md px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-100 text-gray-400 hover:text-gray-500'

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 (
    <>
      <Button
        size="sm"
        color="gray-white"
        className={clsx(contractDetailsButtonClassName, className)}
        onClick={() => setOpen(true)}
      >
        <DotsHorizontalIcon
          className={clsx('h-5 w-5 flex-shrink-0')}
          aria-hidden="true"
        />
      </Button>

      <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>
    </>
  )
}
