import ExerciseListWrapper from '@/components/ExerciseList/ExerciseListWrapper'
import {
  Button,
  Callout,
  Dialog,
  DialogBody,
  DialogFooter,
} from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import type { Exercise } from '@inject/graphql/fragments/Exercise.generated'
import { useCopyUsersAssignment } from '@inject/graphql/mutations/CopyUsersAssignment.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'

const body = css`
  display: flex;
  flex-direction: column;
  gap: 1rem;
`

const wrapper = css`
  flex: 1;
  overflow-y: auto;
`

interface CopyAssignmentProps {
  exerciseId: string
  teamCount: number
}

const CopyAssignment: FC<CopyAssignmentProps> = ({ exerciseId, teamCount }) => {
  const { notify } = useNotifyContext()

  const [open, setOpen] = useState(false)
  const [selectedExercise, setSelectedExercise] = useState<Exercise>()

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

  const [copyAssignment, { loading }] = useCopyUsersAssignment()
  const handleSubmit = useCallback(() => {
    if (!selectedExercise) return

    copyAssignment({
      variables: {
        fromExerciseId: selectedExercise.id,
        toExerciseId: exerciseId,
      },
      onCompleted: reset,
      onError: err => notify(err.message),
      refetchQueries: [GetExerciseDocument],
    })
  }, [copyAssignment, exerciseId, notify, reset, selectedExercise])

  return (
    <>
      <Button
        icon='duplicate'
        text='Copy assignment'
        onClick={() => setOpen(true)}
        active={open}
      />

      <Dialog
        isOpen={open}
        onClose={reset}
        className={maximizedDialog}
        title='Copy assignment from another exercise'
        icon='duplicate'
      >
        <DialogBody className={cx(dialogBody, body)}>
          <Callout icon='info-sign'>
            {`Only exercises with the same team count (${teamCount}) are shown`}
          </Callout>
          <div className={wrapper}>
            <ExerciseListWrapper
              filter={exercise =>
                exercise.id !== exerciseId &&
                exercise.teams.length === teamCount
              }
              isSelected={exercise => exercise.id === selectedExercise?.id}
              type='selecting'
              details={exercise => ({
                onSelect: () => setSelectedExercise(exercise),
              })}
            />
          </div>
        </DialogBody>
        <DialogFooter
          actions={
            <Button
              onClick={handleSubmit}
              intent='primary'
              disabled={!selectedExercise}
              title={selectedExercise ? undefined : 'Select an exercise'}
              loading={loading}
            >
              Submit
            </Button>
          }
        />
      </Dialog>
    </>
  )
}

export default CopyAssignment
