import { Section, SectionCard } from '@blueprintjs/core'
import type { Team } from '@inject/graphql/fragments/Team.generated'
import { useAssignUsersToTeam } from '@inject/graphql/mutations/AssignUsersToTeam.generated'
import { useRemoveUsersFromTeam } from '@inject/graphql/mutations/RemoveUsersFromTeam.generated'
import { GetExerciseDocument } from '@inject/graphql/queries/GetExercise.generated'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import notEmpty from '@inject/shared/utils/notEmpty'
import type { FC } from 'react'
import { useCallback, useState } from 'react'
import UserTableSelection from '../UserTableSelection'
import UsersSelection from '../UsersSelection'

interface TeamProps {
  team: Team
}

const TeamComponent: FC<TeamProps> = ({ team }) => {
  const { notify } = useNotifyContext()

  const [addOpen, setAddOpen] = useState(false)
  const [selectedUsers, setSelectedUsers] = useState<string[]>([])

  const [assignUsersToTeam] = useAssignUsersToTeam()
  const handleAddToTeam = useCallback(
    (team: Team, userIds: string[]) => {
      assignUsersToTeam({
        variables: {
          teamId: team.id,
          userIds,
        },
        refetchQueries: [GetExerciseDocument],
        onCompleted: () => {
          notify(
            `User${userIds.length > 0 ? 's' : ''} added to team ${team.name}`
          )
          setAddOpen(false)
        },
        onError: error => {
          notify(error.message, {
            intent: 'danger',
          })
        },
      })
    },
    [assignUsersToTeam, notify]
  )

  const [removeUsersFromTeam] = useRemoveUsersFromTeam()
  const handleRemoveFromTeam = useCallback(
    (team: Team, userIds: string[]) => {
      removeUsersFromTeam({
        variables: {
          teamId: team.id,
          userIds,
        },
        refetchQueries: [GetExerciseDocument],
        onCompleted: () => {
          notify(
            `User${userIds.length > 1 ? 's' : ''} removed from team ${team.name}`
          )
        },
        onError: error => {
          notify(error.message, {
            intent: 'danger',
          })
        },
      })
    },
    [removeUsersFromTeam, notify]
  )

  return (
    <>
      <Section
        key={team.id}
        title={`${team.name}${team.role ?? ` - ${team.role}`}`}
      >
        <SectionCard>
          <UsersSelection
            users={team.userSet?.filter(notEmpty) || []}
            onRemove={(ids: string[]) => handleRemoveFromTeam(team, ids)}
            onAdd={() => setAddOpen(true)}
          />
        </SectionCard>
      </Section>

      <UserTableSelection
        groups={['INSTRUCTOR', 'TRAINEE']}
        open={addOpen}
        setOpen={setAddOpen}
        onAdd={(ids: string[]) => handleAddToTeam(team, ids)}
        selectedUsers={selectedUsers}
        setSelectedUsers={setSelectedUsers}
      />
    </>
  )
}

export default TeamComponent
