import { track } from '@amplitude/analytics-browser'
import clsx from 'clsx'
import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract'
import { getBinaryCpmmBetInfo } from 'common/new-bet'
import { APIError } from 'web/lib/firebase/api'
import { useEffect, useState } from 'react'
import { useMutation } from 'react-query'
import { placeBet } from 'web/lib/firebase/api'
import { BuyAmountInput } from './amount-input'
import { Button } from './button'
import { Row } from './layout/row'
import { YesNoSelector } from './yes-no-selector'
import { useUnfilledBets } from 'web/hooks/use-bets'
import { useUser } from 'web/hooks/use-user'
import { BetSignUpPrompt } from './sign-up-prompt'
import { getCpmmProbability } from 'common/calculate-cpmm'
import { Col } from './layout/col'
import { XIcon } from '@heroicons/react/solid'
import { formatMoney } from 'common/util/format'

// adapted from bet-panel.ts
export function BetInline(props: {
  contract: CPMMBinaryContract | PseudoNumericContract
  className?: string
  setProbAfter: (probAfter: number | undefined) => void
  onClose: () => void
}) {
  const { contract, className, setProbAfter, onClose } = props

  const user = useUser()

  const [outcome, setOutcome] = useState<'YES' | 'NO'>('YES')
  const [amount, setAmount] = useState<number>()
  const [error, setError] = useState<string>()

  const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
  const unfilledBets = useUnfilledBets(contract.id) ?? []

  const { newPool, newP } = getBinaryCpmmBetInfo(
    outcome ?? 'YES',
    amount ?? 0,
    contract,
    undefined,
    unfilledBets
  )
  const resultProb = getCpmmProbability(newPool, newP)
  useEffect(() => setProbAfter(resultProb), [setProbAfter, resultProb])

  const submitBet = useMutation(
    () => placeBet({ outcome, amount, contractId: contract.id }),
    {
      onError: (e) =>
        setError(e instanceof APIError ? e.toString() : 'Error placing bet'),
      onSuccess: () => {
        track('bet', {
          location: 'embed',
          outcomeType: contract.outcomeType,
          slug: contract.slug,
          contractId: contract.id,
          amount,
          outcome,
          isLimitOrder: false,
        })
        setAmount(undefined)
      },
    }
  )

  // reset error / success state on user change
  useEffect(() => {
    amount && submitBet.reset()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [outcome, amount])

  const tooFewFunds = error === 'Insufficient balance'

  const betDisabled = submitBet.isLoading || tooFewFunds || !amount

  return (
    <Col className={clsx('items-center', className)}>
      <Row className="h-12 items-stretch gap-3 rounded bg-indigo-200 py-2 px-3">
        <div className="text-xl">Predict</div>
        <YesNoSelector
          className="space-x-0"
          btnClassName="rounded-l-none rounded-r-none first:rounded-l-2xl last:rounded-r-2xl"
          selected={outcome}
          onSelect={setOutcome}
          isPseudoNumeric={isPseudoNumeric}
        />
        <BuyAmountInput
          className="-mb-4"
          inputClassName={clsx(
            'input-sm w-20 !text-base',
            error && 'input-error'
          )}
          amount={amount}
          onChange={setAmount}
          error="" // handle error ourselves
          setError={setError}
        />
        {user && (
          <Button
            color={({ YES: 'green', NO: 'red' } as const)[outcome]}
            size="xs"
            disabled={betDisabled}
            onClick={() => submitBet.mutate()}
          >
            {submitBet.isLoading
              ? 'Submitting'
              : submitBet.isSuccess
              ? 'Success!'
              : 'Submit'}
          </Button>
        )}
        <BetSignUpPrompt size="xs" />
        <button
          onClick={() => {
            setProbAfter(undefined)
            onClose()
          }}
        >
          <XIcon className="ml-1 h-6 w-6" />
        </button>
      </Row>
      {error && (
        <div className="text-error my-1 text-sm">
          {error} {tooFewFunds && `(${formatMoney(user?.balance ?? 0)})`}
        </div>
      )}
    </Col>
  )
}