import HelpIcon from '@/components/HelpIcon'
import UsersSelection from '@/users/UsersSelection'
import { NonIdealState, Section, SectionCard } from '@blueprintjs/core'
import Reloader from '@inject/graphql/components/Reloader'
import { useTypedQuery } from '@inject/graphql/graphql'
import {
  AddDefinitionAccess,
  RemoveDefinitionAccess,
} from '@inject/graphql/mutations'
import { GetDefinition } from '@inject/graphql/queries'
import type { FC } from 'react'
import { useCallback, useMemo, useState } from 'react'
import { useClient } from 'urql'
import UserTableSelection from '../UserTableSelection'

interface DefinitionAssignmentProps {
  definitionId: string
}

const DefinitionAssignment: FC<DefinitionAssignmentProps> = ({
  definitionId,
}) => {
  const client = useClient()

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

  const [{ data }, refetch] = useTypedQuery({
    query: GetDefinition,
    variables: {
      definitionId,
    },
    requestPolicy: 'network-only',
    context: useMemo(
      () => ({
        suspense: true,
      }),
      []
    ),
  })
  const { name, maintainers } = data?.definition || {}

  const handleAdd = useCallback(
    (ids: string[]) => {
      client
        .mutation(AddDefinitionAccess, {
          definitionId,
          userIds: ids,
        })
        .toPromise()
        .then(() => {
          setAddOpen(false)
        })
    },
    [client, definitionId]
  )

  const handleRemove = useCallback(
    (ids: string[]) => {
      client
        .mutation(RemoveDefinitionAccess, {
          definitionId,
          userIds: ids,
        })
        .toPromise()
    },
    [client, definitionId]
  )

  if (!data || !data.definition) {
    return (
      <NonIdealState
        icon='low-voltage-pole'
        description='Unable to display users'
      />
    )
  }

  return (
    <>
      <Section
        title='Manage access to definition'
        subtitle={name}
        icon={
          <HelpIcon
            text='Instructors with access to a definition are able to
          create exercises from it. They can also start, stop, and delete
          them, and assign participants to them.'
          />
        }
        rightElement={<Reloader minimal onRefetch={refetch} />}
      >
        <SectionCard padded>
          <UsersSelection
            users={maintainers || []}
            onRemove={(ids: string[]) => handleRemove(ids)}
            onAdd={() => setAddOpen(true)}
          />
        </SectionCard>
      </Section>

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

export default DefinitionAssignment
