import ContentArea from '@/components/ContentArea'
import FileArea from '@/components/FileArea'
import {
  Button,
  ButtonGroup,
  Divider,
  FormGroup,
  NonIdealState,
} from '@blueprintjs/core'
import { css } from '@emotion/css'
import type { FileInfo } from '@inject/graphql/fragments/FileInfo.generated'
import { useSendCustomInject } from '@inject/graphql/mutations/SendCustomInject.generated'
import { useGetExercise } from '@inject/graphql/queries/GetExercise.generated'
import CenteredSpinner from '@inject/shared/components/CenteredSpinner'
import ErrorMessage from '@inject/shared/components/ErrorMessage'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import notEmpty from '@inject/shared/utils/notEmpty'
import type { Dispatch, SetStateAction } from 'react'
import { useState } from 'react'
import OverlayForm from './OverlayForm'
import TeamSelector from './TeamSelector'

export const MainDrawer = css`
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
`

const footer = css`
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  flex-direction: row-reverse;
  gap: 0.5rem;
`

const teamSelector = css`
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 0.5rem;
`

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

interface InjectComposerProps {
  teamId: string
  exerciseId: string
  setIsOpen: Dispatch<SetStateAction<boolean>>
}

const InjectForm = ({ teamId, exerciseId, setIsOpen }: InjectComposerProps) => {
  const { notify } = useNotifyContext()
  const [mutate, { loading }] = useSendCustomInject()

  const [selectedTeamIds, setSelectedTeamIds] = useState<string[]>([teamId])
  const [content, setContent] = useState('')
  const [isOverlay, setIsOverlay] = useState(false)
  const [duration, setDuration] = useState<number | undefined>()
  const [fileInfo, setFileInfo] = useState<FileInfo>()

  const {
    data,
    loading: getExerciseLoading,
    error,
  } = useGetExercise({ variables: { exerciseId } })

  if (getExerciseLoading) {
    return <CenteredSpinner />
  }
  if (error) {
    return (
      <ErrorMessage>
        <h1>Error occurred!</h1>
        <p>{error.message}</p>
      </ErrorMessage>
    )
  }
  if (!data?.exerciseId) {
    return (
      <NonIdealState
        icon='low-voltage-pole'
        title='No data'
        description='Please wait for the data to come in'
      />
    )
  }
  const teams = data.exerciseId.teams.filter(notEmpty)

  const onSend = () => {
    if (!content && !fileInfo) {
      notify('Add a message or an attachment', {
        intent: 'danger',
      })
      return
    }
    if (selectedTeamIds.length === 0) {
      notify('Select at least one team', {
        intent: 'danger',
      })
      return
    }
    if (isOverlay && !duration) {
      notify('Set the duration', { intent: 'danger' })
      return
    }

    mutate({
      variables: {
        customInjectInput: {
          teamIds: selectedTeamIds,
          content,
          exerciseId,
          fileId: fileInfo?.id,
          overlay:
            isOverlay && duration
              ? {
                  duration,
                }
              : undefined,
        },
      },
      onCompleted: () => {
        setIsOpen(false)
      },
      onError: err => {
        notify(err.message, { intent: 'danger' })
      },
    })
  }

  return (
    <div className={MainDrawer}>
      <div className={teamSelector}>
        <span style={{ textWrap: 'nowrap' }}>Send to teams:</span>
        <TeamSelector
          teams={teams}
          selectedTeamIds={selectedTeamIds}
          setSelectedTeamIds={setSelectedTeamIds}
        />
      </div>

      <OverlayForm
        isOverlay={isOverlay}
        setIsOverlay={setIsOverlay}
        duration={duration}
        setDuration={setDuration}
      />

      <Divider style={{ margin: '0.5rem 0' }} />

      <div className={body}>
        <ContentArea content={content} setContent={setContent} />
        <FileArea
          exerciseId={exerciseId}
          fileInfo={fileInfo}
          setFileInfo={setFileInfo}
          teamId={teamId}
        />
      </div>

      <Divider style={{ margin: '0.5rem 0' }} />

      <div className={footer}>
        <FormGroup disabled={loading} style={{ margin: '0' }}>
          <ButtonGroup>
            <Button icon='trash' onClick={() => setIsOpen(false)}>
              Discard
            </Button>
            <Button
              type='submit'
              rightIcon='send-message'
              onClick={onSend}
              loading={loading}
            >
              Send
            </Button>
          </ButtonGroup>
        </FormGroup>
      </div>
    </div>
  )
}

export default InjectForm
