import useWiggle, { wiggleClass } from '@/hooks/useWiggle'
import { Button, Callout, FormGroup, InputGroup } from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import type { Tool } from '@inject/graphql/fragment-types'
import { PerformTeamToolAction } from '@inject/graphql/mutations'
import useBlockableMutation from '@inject/graphql/utils/useBlockableMutation'
import { breakWord } from '@inject/shared/css/textOverflow'
import type { FC, FormEvent, KeyboardEventHandler } from 'react'
import { useState } from 'react'

const wrapper = css`
  display: flex;
  flex-direction: column;
`

const submit = css`
  margin-top: 0.2rem;
  align-self: flex-end;
`

interface ToolFormProps {
  tool: Tool
  teamId: string
  setOpen(arg0: boolean): void
  disabled?: boolean
  disabledTitle?: string
}

const ToolForm: FC<ToolFormProps> = ({
  tool,
  teamId,
  setOpen,
  disabled,
  disabledTitle,
}) => {
  const { tooltipDescription, id, requiresInput } = tool
  const [value, setValue] = useState<string>('')
  const [isError, setIsError] = useState(false)
  const [running, { fetching }, mutate] = useBlockableMutation(
    PerformTeamToolAction
  )

  const { beginWiggling, wiggling } = useWiggle()

  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    const data: { argument?: string } = Object.fromEntries(
      new FormData(event.currentTarget).entries()
    )
    if (requiresInput && !data.argument) {
      setIsError(true)
      beginWiggling()
    } else {
      setIsError(false)
      mutateData()
    }
  }

  const mutateData = () => {
    if (requiresInput && value.trim() === '') {
      return
    }
    mutate({
      teamId,
      toolId: id || 'none',
      toolArgument: value.trim(),
    })
    setOpen(false)
    setValue('')
  }
  const handleEnter: KeyboardEventHandler<HTMLInputElement> = e => {
    if (e.key === 'Enter') mutateData()
  }

  return (
    <Callout>
      <p className={breakWord}>{tooltipDescription}</p>
      <form className={wrapper} onSubmit={handleSubmit}>
        {requiresInput && (
          <FormGroup
            helperText={isError && `Enter ${tool.hint || 'Argument'}`}
            intent={isError ? 'danger' : 'none'}
            style={{ marginBottom: '0.3rem' }}
          >
            <InputGroup
              placeholder={tool.hint || 'Argument'}
              name='argument'
              value={value}
              intent={isError ? 'danger' : 'none'}
              onChange={e => setValue(e.currentTarget.value)}
              onKeyDown={handleEnter}
              readOnly={disabled}
              title={disabled ? disabledTitle : tool.hint || 'Argument'}
            />
          </FormGroup>
        )}
        <Button
          type='submit'
          className={cx(submit, {
            [wiggleClass]: wiggling,
          })}
          outlined
          minimal
          disabled={disabled || fetching || !running}
          title={
            disabled
              ? disabledTitle
              : !running
                ? 'The exercise is disabled/paused'
                : undefined
          }
        >
          Submit
        </Button>
      </form>
    </Callout>
  )
}

export default ToolForm
