import clsx from 'clsx'
import { User } from 'common/user'
import { useState } from 'react'
import { useUser } from 'web/hooks/use-user'
import { withTracking } from 'web/lib/service/analytics'
import { Row } from 'web/components/layout/row'
import { useMemberGroups, useMemberIds } from 'web/hooks/use-group'
import { TextButton } from 'web/components/text-button'
import { Group } from 'common/group'
import { Modal } from 'web/components/layout/modal'
import { Col } from 'web/components/layout/col'
import { joinGroup, leaveGroup } from 'web/lib/firebase/groups'
import { firebaseLogin } from 'web/lib/firebase/users'
import { GroupLinkItem } from 'web/pages/groups'
import toast from 'react-hot-toast'

export function GroupsButton(props: { user: User }) {
  const { user } = props
  const [isOpen, setIsOpen] = useState(false)
  const groups = useMemberGroups(user.id)

  return (
    <>
      <TextButton onClick={() => setIsOpen(true)}>
        <span className="font-semibold">{groups?.length ?? ''}</span> Groups
      </TextButton>

      <GroupsDialog
        user={user}
        groups={groups ?? []}
        isOpen={isOpen}
        setIsOpen={setIsOpen}
      />
    </>
  )
}

function GroupsDialog(props: {
  user: User
  groups: Group[]
  isOpen: boolean
  setIsOpen: (isOpen: boolean) => void
}) {
  const { user, groups, isOpen, setIsOpen } = props

  return (
    <Modal open={isOpen} setOpen={setIsOpen}>
      <Col className="rounded bg-white p-6">
        <div className="p-2 pb-1 text-xl">{user.name}</div>
        <div className="p-2 pt-0 text-sm text-gray-500">@{user.username}</div>
        <GroupsList groups={groups} />
      </Col>
    </Modal>
  )
}

function GroupsList(props: { groups: Group[] }) {
  const { groups } = props
  return (
    <Col className="gap-2">
      {groups.length === 0 && (
        <div className="text-gray-500">No groups yet...</div>
      )}
      {groups
        .sort((group1, group2) => group2.createdTime - group1.createdTime)
        .map((group) => (
          <GroupItem key={group.id} group={group} />
        ))}
    </Col>
  )
}

function GroupItem(props: { group: Group; className?: string }) {
  const { group, className } = props
  const user = useUser()
  const memberIds = useMemberIds(group.id)
  return (
    <Row className={clsx('items-center justify-between gap-2 p-2', className)}>
      <Row className="line-clamp-1 items-center gap-2">
        <GroupLinkItem group={group} />
      </Row>
      <JoinOrLeaveGroupButton
        group={group}
        user={user}
        isMember={user ? memberIds?.includes(user.id) : false}
      />
    </Row>
  )
}

export function JoinOrLeaveGroupButton(props: {
  group: Group
  isMember: boolean
  user: User | undefined | null
  small?: boolean
  className?: string
}) {
  const { group, small, className, isMember, user } = props
  const smallStyle =
    'btn !btn-xs border-2 border-gray-500 bg-white normal-case text-gray-500 hover:border-gray-500 hover:bg-white hover:text-gray-500'

  if (!user) {
    if (!group.anyoneCanJoin)
      return <div className={clsx(className, 'text-gray-500')}>Closed</div>
    return (
      <button
        onClick={firebaseLogin}
        className={clsx('btn btn-sm', small && smallStyle, className)}
      >
        Login to follow
      </button>
    )
  }
  const onJoinGroup = () => {
    joinGroup(group, user.id).catch(() => {
      toast.error('Failed to join group')
    })
  }
  const onLeaveGroup = () => {
    leaveGroup(group, user.id).catch(() => {
      toast.error('Failed to leave group')
    })
  }

  if (isMember) {
    return (
      <button
        className={clsx(
          'btn btn-outline btn-xs',
          small && smallStyle,
          className
        )}
        onClick={withTracking(onLeaveGroup, 'leave group')}
      >
        Unfollow
      </button>
    )
  }

  if (!group.anyoneCanJoin)
    return <div className={clsx(className, 'text-gray-500')}>Closed</div>
  return (
    <button
      className={clsx('btn btn-sm', small && smallStyle, className)}
      onClick={withTracking(onJoinGroup, 'join group')}
    >
      Follow
    </button>
  )
}