import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  FormGroup,
  InputGroup,
} from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import { useAssignUsersByTags } from '@inject/graphql/mutations/AssignUsersByTags.generated'
import { GetExerciseDocument } from '@inject/graphql/queries/GetExercise.generated'
import { dialogBody, maximizedDialog } from '@inject/shared/css/dialog'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import type { FC } from 'react'
import { useCallback, useState } from 'react'
import useUserTableSelection from '../UserTableSelection/useUserTableSelection'

const body = css`
  display: flex;
  flex-direction: column;
  overflow: auto;
`

interface AssignByTagsProps {
  exerciseId: string
}

const AssignByTags: FC<AssignByTagsProps> = ({ exerciseId }) => {
  const { notify } = useNotifyContext()

  const [open, setOpen] = useState(false)
  const [selectedUsers, setSelectedUsers] = useState<string[]>([])
  const [tagPrefix, setTagPrefix] = useState('')

  const reset = useCallback(() => {
    setOpen(false)
    setSelectedUsers([])
  }, [])

  const [AssignByTags, { loading }] = useAssignUsersByTags()
  const handleSubmit = useCallback(() => {
    if (!selectedUsers) return

    AssignByTags({
      variables: {
        exerciseId,
        userIds: selectedUsers,
        tagPrefix,
      },
      onCompleted: reset,
      onError: err => notify(err.message),
      refetchQueries: [GetExerciseDocument],
    })
  }, [AssignByTags, exerciseId, notify, reset, selectedUsers, tagPrefix])

  const { table } = useUserTableSelection({
    groups: ['INSTRUCTOR', 'TRAINEE'],
    onCancel: reset,
    onAdd: (ids: string[]) => setSelectedUsers(ids),
    selectedUsers,
    setSelectedUsers,
  })

  return (
    <>
      <Button
        icon='tag'
        text='Assign by tags'
        onClick={() => setOpen(true)}
        active={open}
      />

      <Dialog
        isOpen={open}
        onClose={reset}
        className={maximizedDialog}
        title='Assign users to teams based on tags'
        icon='tag'
      >
        <DialogBody className={cx(dialogBody, body)}>
          <FormGroup
            label='Tag prefix'
            labelInfo='(optional)'
            labelFor='tag-prefix'
            helperText='Users will be assigned to teams based on tags with this prefix'
          >
            <InputGroup
              id='tag-prefix'
              placeholder='example-prefix'
              value={tagPrefix}
              onChange={e => setTagPrefix(e.target.value)}
            />
          </FormGroup>
          {table}
        </DialogBody>
        <DialogFooter
          actions={
            <Button
              onClick={handleSubmit}
              intent='primary'
              disabled={selectedUsers.length === 0}
              title={selectedUsers.length > 0 ? undefined : 'Select some users'}
              loading={loading}
            >
              {`Assign (${selectedUsers.length})`}
            </Button>
          }
        />
      </Dialog>
    </>
  )
}

export default AssignByTags
