import {
  Button,
  Callout,
  Dialog,
  DialogBody,
  DialogFooter,
  FormGroup,
  NumericInput,
} from '@blueprintjs/core'
import { css } from '@emotion/css'
import { useTypedMutation } from '@inject/graphql/graphql'
import { MoveTime } from '@inject/graphql/mutations'
import { useLoopStatus } from '@inject/graphql/utils/useExerciseLoopStatusSubscription'
import { dialog } from '@inject/shared/css/dialog'
import { useCallback, useState, type FC } from 'react'

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

const formGroup = css`
  margin-bottom: 0;
`

interface MoveTimeButtonProps {
  hideLabel: boolean
  exerciseId?: string
  disabledTitle?: string
}

const MoveTimeButton: FC<MoveTimeButtonProps> = ({
  hideLabel,
  exerciseId,
  disabledTitle,
}) => {
  const [open, setOpen] = useState(false)
  const [minutesText, setMinutesText] = useState('')
  const [minutes, setMinutes] = useState<number | undefined>(undefined)

  const [{ fetching: loading }, moveTime] = useTypedMutation(MoveTime)
  const { running } = useLoopStatus()

  const handleSubmit = useCallback(() => {
    // the button should be disabled in this case
    if (!exerciseId || !minutes) return

    moveTime({ exerciseId, timeDiff: minutes }).then(() => {
      setOpen(false)
      setMinutesText('')
      setMinutes(undefined)
    })
  }, [exerciseId, moveTime, minutes])

  return (
    <>
      <Button
        icon='history'
        alignText='left'
        fill
        minimal
        text={!hideLabel && 'Move time'}
        onClick={() => setOpen(true)}
        active={open}
        style={{ whiteSpace: 'nowrap' }}
        title={
          exerciseId && running
            ? 'Move time'
            : disabledTitle || 'The exercise has to be running to move time'
        }
        disabled={!exerciseId || !running}
      />

      <Dialog
        className={dialog}
        title='Move time'
        isOpen={open}
        onClose={() => setOpen(false)}
        icon='history'
      >
        <DialogBody className={body}>
          <Callout intent='warning'>
            <b>
              Moving the in-exercise time will greatly affect the course of the
              exercise!
            </b>
            <br />
            <span>
              Automated injects and other pre-defined actions that rely on
              timing may not work as intended
            </span>
          </Callout>
          <FormGroup
            className={formGroup}
            labelFor='minutes'
            label='Number of minutes'
            helperText='Positive numbers move time forward, negative numbers move it backward'
          >
            <NumericInput
              id='minutes'
              title='Number of minutes'
              fill
              value={minutesText}
              onValueChange={(value, valueString) => {
                setMinutesText(valueString)
                setMinutes(value)
              }}
            />
          </FormGroup>
        </DialogBody>
        <DialogFooter
          actions={
            <Button
              onClick={handleSubmit}
              intent='primary'
              disabled={!exerciseId || !running || !minutes}
              title={
                exerciseId && running
                  ? minutes
                    ? undefined
                    : 'Select the number of minutes'
                  : disabledTitle || 'Move time'
              }
              loading={loading}
            >
              Submit
            </Button>
          }
        />
      </Dialog>
    </>
  )
}

export default MoveTimeButton
