import type { ButtonProps } from '@blueprintjs/core'
import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  HTMLSelect,
  InputGroup,
  TextArea,
} from '@blueprintjs/core'
import { notify } from '@inject/shared/notification/engine'
import type { FC } from 'react'
import { memo, useCallback, useEffect, useState } from 'react'
import TooltipLabel from '../Tooltips/TooltipLabel'
import { GENERIC_CONTENT } from '../assets/generalContent'
import { INJECT_FORM } from '../assets/pageContent/injects'
import { addInjectInfo, updateInjectInfo } from '../indexeddb/operations'
import type { InjectInfo } from '../indexeddb/types'
import { InjectType } from '../indexeddb/types'
import { INJECT_TYPES } from '../utils'

interface InjectFormProps {
  inject?: InjectInfo
  buttonProps: ButtonProps
}

const InjectForm: FC<InjectFormProps> = ({ inject, buttonProps }) => {
  const [isOpen, setIsOpen] = useState(false)
  const [name, setName] = useState<string>('')
  const [description, setDescription] = useState<string>('')
  const [type, setType] = useState<InjectType>(InjectType.INFORMATION)

  const clearInput = useCallback(() => {
    setName('')
    setDescription('')
  }, [])

  const handleAddButton = useCallback(
    async (inject: Omit<InjectInfo, 'id'>) => {
      try {
        await addInjectInfo(inject)
        clearInput()
        setIsOpen(false)
      } catch (err) {
        notify(`Failed to add inject '${inject.name}': ${err}`, {
          intent: 'danger',
        })
      }
    },
    [notify]
  )

  const handleUpdateButton = useCallback(
    async (inject: InjectInfo) => {
      try {
        await updateInjectInfo(inject)
        setIsOpen(false)
      } catch (err) {
        notify(`Failed to update inject '${inject.name}': ${err}`, {
          intent: 'danger',
        })
      }
    },
    [notify]
  )

  useEffect(() => {
    setName(inject?.name || '')
    setDescription(inject?.description || '')
    setType(inject?.type || InjectType.INFORMATION)
  }, [inject])

  return (
    <>
      <Button {...buttonProps} onClick={() => setIsOpen(true)} />
      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        icon={inject ? 'edit' : 'plus'}
        title={inject ? 'Edit inject' : 'New inject'}
      >
        <DialogBody>
          <TooltipLabel label={INJECT_FORM.name}>
            <InputGroup
              placeholder='Input text'
              value={name}
              onChange={e => setName(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={INJECT_FORM.description}>
            <TextArea
              value={description}
              style={{
                width: '100%',
                height: '5rem',
                resize: 'none',
                overflowY: 'auto',
              }}
              placeholder='Input text'
              onChange={e => setDescription(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={INJECT_FORM.channel}>
            <HTMLSelect
              options={INJECT_TYPES}
              value={type}
              onChange={event =>
                setType(event.currentTarget.value as InjectType)
              }
            />
          </TooltipLabel>
        </DialogBody>
        <DialogFooter
          actions={
            inject ? (
              <Button
                disabled={!name}
                onClick={() =>
                  handleUpdateButton({
                    id: inject.id,
                    name,
                    description,
                    type,
                  })
                }
                intent='primary'
                icon='edit'
                text={GENERIC_CONTENT.buttons.save}
              />
            ) : (
              <Button
                disabled={!name}
                onClick={() => handleAddButton({ name, description, type })}
                intent='primary'
                icon='plus'
                text={GENERIC_CONTENT.buttons.add}
              />
            )
          }
        />
      </Dialog>
    </>
  )
}

export default memo(InjectForm)
