import { Section, SectionCard } from '@blueprintjs/core'
import type { RestrictedUser } from '@inject/graphql/fragments/RestrictedUser.generated'
import { useAssignInstructorsToExercise } from '@inject/graphql/mutations/AssignInstructorsToExercise.generated'
import { useRemoveInstructorsFromExercise } from '@inject/graphql/mutations/RemoveInstructorsFromExercise.generated'
import { GetExerciseDocument } from '@inject/graphql/queries/GetExercise.generated'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import { useCallback, useState, type FC } from 'react'
import UserTableSelection from '../UserTableSelection'
import UsersSelection from '../UsersSelection'
import { bodySection } from './classes'

interface InstructorsProps {
  users: RestrictedUser[]
  exerciseId: string
}

const Instructors: FC<InstructorsProps> = ({ users, exerciseId }) => {
  const { notify } = useNotifyContext()

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

  const [assignInstructorsToExercise] = useAssignInstructorsToExercise()
  const handleAddInstructors = useCallback(
    (userIds: string[]) => {
      assignInstructorsToExercise({
        variables: {
          exerciseId,
          userIds,
        },
        refetchQueries: [GetExerciseDocument],
        onCompleted: () => {
          notify(`Instructor${userIds.length > 1 ? 's' : ''} added`)
          setAddOpen(false)
        },
        onError: error => {
          notify(error.message, {
            intent: 'danger',
          })
        },
      })
    },
    [assignInstructorsToExercise, exerciseId, notify]
  )

  const [removeInstructorsFromExercise] = useRemoveInstructorsFromExercise()
  const handleRemoveInstructors = useCallback(
    (userIds: string[]) => {
      removeInstructorsFromExercise({
        variables: {
          exerciseId,
          userIds,
        },
        refetchQueries: [GetExerciseDocument],
        onCompleted: () => {
          notify(`Instructor${userIds.length > 1 ? 's' : ''} removed`)
        },
        onError: error => {
          notify(error.message, {
            intent: 'danger',
          })
        },
      })
    },
    [exerciseId, notify, removeInstructorsFromExercise]
  )

  return (
    <>
      <Section title='Instructors' icon='intelligence' className={bodySection}>
        <SectionCard>
          <Section>
            <SectionCard>
              <UsersSelection
                users={users}
                onRemove={ids => handleRemoveInstructors(ids)}
                onAdd={() => setAddOpen(true)}
              />
            </SectionCard>
          </Section>
        </SectionCard>
      </Section>

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

export default Instructors
