import clsx from 'clsx'
import React from 'react'
import { formatMoney } from 'common/util/format'
import { Col } from 'web/components/layout/col'
import { Row } from 'web/components/layout/row'
import { Page } from 'web/components/page'
import { SEO } from 'web/components/SEO'
import { Title } from 'web/components/title'
import { useUser } from 'web/hooks/use-user'
import { fromNow } from 'web/lib/util/time'

import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import {
  getChallengeUrl,
  useAcceptedChallenges,
  useUserChallenges,
} from 'web/lib/firebase/challenges'
import { Challenge, CHALLENGES_ENABLED } from 'common/challenge'
import { Tabs } from 'web/components/layout/tabs'
import { SiteLink } from 'web/components/site-link'
import { Avatar } from 'web/components/avatar'
import Router from 'next/router'
import { contractPathWithoutContract } from 'web/lib/firebase/contracts'
import { Button } from 'web/components/button'
import { ClipboardCopyIcon, QrcodeIcon } from '@heroicons/react/outline'
import { copyToClipboard } from 'web/lib/util/copy'
import toast from 'react-hot-toast'
import { Modal } from 'web/components/layout/modal'
import { QRCode } from 'web/components/qr-code'
import { CreateChallengeModal } from 'web/components/challenges/create-challenge-modal'
import { UserLink } from 'web/components/user-link'

dayjs.extend(customParseFormat)
const columnClass = 'sm:px-5 px-2 py-3.5 max-w-[100px] truncate'
const amountClass = columnClass + ' max-w-[75px] font-bold'

export default function ChallengesListPage() {
  const user = useUser()
  const challenges = useAcceptedChallenges()
  const [open, setOpen] = React.useState(false)
  const userChallenges = useUserChallenges(user?.id)
    .concat(
      user ? challenges.filter((c) => c.acceptances[0].userId === user.id) : []
    )
    .sort((a, b) => b.createdTime - a.createdTime)

  const userTab = user
    ? [
        {
          content: <YourChallengesTable links={userChallenges} />,
          title: 'Your Challenges',
        },
      ]
    : []

  const publicTab = [
    {
      content: <PublicChallengesTable links={challenges} />,
      title: 'Public Challenges',
    },
  ]

  return (
    <Page>
      <SEO
        title="Challenges"
        description="Challenge your friends to a bet!"
        url="/send"
      />

      <Col className="w-full px-8">
        <Row className="items-center justify-between">
          <Title text="Challenges" />
          {CHALLENGES_ENABLED && (
            <Button size="lg" color="gradient" onClick={() => setOpen(true)}>
              Create Challenge
              <CreateChallengeModal
                isOpen={open}
                setOpen={setOpen}
                user={user}
              />
            </Button>
          )}
        </Row>
        <p>
          Want to create your own challenge?
          <SiteLink className={'mx-1 font-bold'} href={'/home'}>
            Find
          </SiteLink>
          a market you and a friend disagree on and hit the challenge button, or
          tap the button above to create a new market & challenge in one.
        </p>

        <Tabs className="mb-4" tabs={[...userTab, ...publicTab]} />
      </Col>
    </Page>
  )
}

function YourChallengesTable(props: { links: Challenge[] }) {
  const { links } = props
  return links.length == 0 ? (
    <p>There aren't currently any challenges.</p>
  ) : (
    <div className="overflow-scroll">
      <table className="w-full divide-y divide-gray-300 rounded-lg border border-gray-200">
        <thead className="bg-gray-50 text-left text-sm font-semibold text-gray-900">
          <tr>
            <th className={amountClass}>Amount</th>
            <th
              className={clsx(
                columnClass,
                'text-center sm:pl-10 sm:text-start'
              )}
            >
              Link
            </th>
            <th className={columnClass}>Accepted By</th>
          </tr>
        </thead>
        <tbody className={'divide-y divide-gray-200 bg-white'}>
          {links.map((link) => (
            <YourLinkSummaryRow challenge={link} />
          ))}
        </tbody>
      </table>
    </div>
  )
}

function YourLinkSummaryRow(props: { challenge: Challenge }) {
  const { challenge } = props
  const { acceptances } = challenge

  const [open, setOpen] = React.useState(false)
  const className = clsx(
    'whitespace-nowrap text-sm hover:cursor-pointer text-gray-500 hover:bg-sky-50 bg-white'
  )
  return (
    <>
      <Modal open={open} setOpen={setOpen} size={'sm'}>
        <Col
          className={
            'items-center justify-center gap-4 rounded-md bg-white p-8 py-8 '
          }
        >
          <span className={'mb-4  text-center text-xl text-indigo-700'}>
            Have your friend scan this to accept the challenge!
          </span>
          <QRCode url={getChallengeUrl(challenge)} />
        </Col>
      </Modal>
      <tr id={challenge.slug} key={challenge.slug} className={className}>
        <td className={amountClass}>
          <SiteLink href={getChallengeUrl(challenge)}>
            {formatMoney(challenge.creatorAmount)}
          </SiteLink>
        </td>
        <td
          className={clsx(
            columnClass,
            'text-center sm:max-w-[200px] sm:text-start'
          )}
        >
          <Row className="items-center gap-2">
            <Button
              color="gray-white"
              size="xs"
              onClick={() => {
                copyToClipboard(getChallengeUrl(challenge))
                toast('Link copied to clipboard!')
              }}
            >
              <ClipboardCopyIcon className={'h-5 w-5 sm:h-4 sm:w-4'} />
            </Button>
            <Button
              color="gray-white"
              size="xs"
              onClick={() => {
                setOpen(true)
              }}
            >
              <QrcodeIcon className="h-5 w-5 sm:h-4 sm:w-4" />
            </Button>
            <SiteLink
              href={getChallengeUrl(challenge)}
              className={'mx-1 mb-1 hidden sm:inline-block'}
            >
              {`...${challenge.contractSlug}/${challenge.slug}`}
            </SiteLink>
          </Row>
        </td>

        <td className={columnClass}>
          <Row className={'items-center justify-start gap-1'}>
            {acceptances.length > 0 ? (
              <>
                <Avatar
                  username={acceptances[0].userUsername}
                  avatarUrl={acceptances[0].userAvatarUrl}
                  size={'sm'}
                />
                <UserLink
                  name={acceptances[0].userName}
                  username={acceptances[0].userUsername}
                />
              </>
            ) : (
              <span>
                No one -
                {challenge.expiresTime &&
                  ` (expires ${fromNow(challenge.expiresTime)})`}
              </span>
            )}
          </Row>
        </td>
      </tr>
    </>
  )
}

function PublicChallengesTable(props: { links: Challenge[] }) {
  const { links } = props
  return links.length == 0 ? (
    <p>There aren't currently any challenges.</p>
  ) : (
    <div className="overflow-scroll">
      <table className="w-full divide-y divide-gray-300 rounded-lg border border-gray-200">
        <thead className="bg-gray-50 text-left text-sm font-semibold text-gray-900">
          <tr>
            <th className={amountClass}>Amount</th>
            <th className={columnClass}>Creator</th>
            <th className={columnClass}>Acceptor</th>
            <th className={columnClass}>Market</th>
          </tr>
        </thead>
        <tbody className={'divide-y divide-gray-200 bg-white'}>
          {links.map((link) => (
            <PublicLinkSummaryRow challenge={link} />
          ))}
        </tbody>
      </table>
    </div>
  )
}

function PublicLinkSummaryRow(props: { challenge: Challenge }) {
  const { challenge } = props
  const {
    acceptances,
    creatorUsername,
    creatorName,
    creatorAvatarUrl,
    contractCreatorUsername,
    contractQuestion,
    contractSlug,
  } = challenge

  const className = clsx(
    'whitespace-nowrap text-sm hover:cursor-pointer text-gray-500 hover:bg-sky-50 bg-white'
  )
  return (
    <tr
      id={challenge.slug + '-public'}
      key={challenge.slug + '-public'}
      className={className}
      onClick={() => Router.push(getChallengeUrl(challenge))}
    >
      <td className={amountClass}>
        <SiteLink href={getChallengeUrl(challenge)}>
          {formatMoney(challenge.creatorAmount)}
        </SiteLink>
      </td>

      <td className={clsx(columnClass)}>
        <Row className={'items-center justify-start gap-1'}>
          <Avatar
            username={creatorUsername}
            avatarUrl={creatorAvatarUrl}
            size={'sm'}
            noLink={true}
          />
          <UserLink name={creatorName} username={creatorUsername} />
        </Row>
      </td>

      <td className={clsx(columnClass)}>
        <Row className={'items-center justify-start gap-1'}>
          {acceptances.length > 0 ? (
            <>
              <Avatar
                username={acceptances[0].userUsername}
                avatarUrl={acceptances[0].userAvatarUrl}
                size={'sm'}
                noLink={true}
              />
              <UserLink
                name={acceptances[0].userName}
                username={acceptances[0].userUsername}
              />
            </>
          ) : (
            <span>
              No one -
              {challenge.expiresTime &&
                ` (expires ${fromNow(challenge.expiresTime)})`}
            </span>
          )}
        </Row>
      </td>
      <td className={clsx(columnClass, 'font-bold')}>
        <SiteLink
          href={contractPathWithoutContract(
            contractCreatorUsername,
            contractSlug
          )}
        >
          {contractQuestion}
        </SiteLink>
      </td>
    </tr>
  )
}