import { addTool, updateTool } from '@/editor/indexeddb/operations'
import type { ButtonProps } from '@blueprintjs/core'
import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  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 { TOOL_FORM } from '../assets/pageContent/tools'
import type { ToolInfo } from '../indexeddb/types'

interface ToolFormProps {
  toolInfo?: ToolInfo
  buttonProps: ButtonProps
  onAdd?: (id: number) => void
}

const ToolForm: FC<ToolFormProps> = ({ toolInfo, buttonProps, onAdd }) => {
  const [isOpen, setIsOpen] = useState(false)
  const [name, setName] = useState<string>('')
  const [tooltipDescription, setTooltipDescription] = useState<string>('')
  const [hint, setHint] = useState<string>('')
  const [defaultResponse, setDefaultResponse] = useState<string>('')

  const clearInput = useCallback(() => {
    setName('')
    setTooltipDescription('')
    setHint('')
    setDefaultResponse('')
  }, [])

  const handleAddButton = useCallback(async (tool: Omit<ToolInfo, 'id'>) => {
    try {
      const id = await addTool(tool)
      if (onAdd) onAdd(Number(id))
      clearInput()
      setIsOpen(false)
    } catch (error) {
      notify(
        `Failed to add tool '${tool.name}': ${error}`,
        JSON.stringify(error),
        {
          intent: 'danger',
        }
      )
    }
  }, [])

  const handleUpdateButton = useCallback(async (tool: ToolInfo) => {
    try {
      await updateTool(tool)
      setIsOpen(false)
    } catch (error) {
      notify(
        `Failed to update tool '${tool.name}': ${error}`,
        JSON.stringify(error),
        {
          intent: 'danger',
        }
      )
    }
  }, [])

  useEffect(() => {
    setName(toolInfo?.name || '')
    setTooltipDescription(toolInfo?.tooltipDescription || '')
    setHint(toolInfo?.hint || '')
    setDefaultResponse(toolInfo?.defaultResponse || '')
  }, [toolInfo])

  return (
    <>
      <Button {...buttonProps} onClick={() => setIsOpen(true)} />
      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        icon={toolInfo ? 'edit' : 'plus'}
        title={toolInfo ? 'Edit tool' : 'New tool'}
      >
        <DialogBody>
          <TooltipLabel label={TOOL_FORM.name}>
            <InputGroup
              placeholder='Input text'
              value={name}
              onChange={e => setName(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={TOOL_FORM.tooltip}>
            <InputGroup
              placeholder='Input text'
              value={tooltipDescription}
              onChange={e => setTooltipDescription(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={TOOL_FORM.hint}>
            <InputGroup
              placeholder='Input text'
              value={hint}
              onChange={e => setHint(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={TOOL_FORM.defaultResponse}>
            <TextArea
              value={defaultResponse}
              style={{
                width: '100%',
                height: '10rem',
                resize: 'none',
                overflowY: 'auto',
              }}
              placeholder='Input text'
              onChange={e => setDefaultResponse(e.target.value)}
            />
          </TooltipLabel>
        </DialogBody>
        <DialogFooter
          actions={
            toolInfo ? (
              <Button
                disabled={!name || !defaultResponse}
                onClick={() =>
                  handleUpdateButton({
                    id: toolInfo.id,
                    name,
                    tooltipDescription,
                    hint,
                    defaultResponse,
                  })
                }
                intent='primary'
                icon='edit'
                text={GENERIC_CONTENT.buttons.save}
              />
            ) : (
              <Button
                disabled={!name || !defaultResponse}
                onClick={() =>
                  handleAddButton({
                    name,
                    tooltipDescription,
                    hint,
                    defaultResponse,
                  })
                }
                intent='primary'
                icon='plus'
                text={GENERIC_CONTENT.buttons.add}
              />
            )
          }
        />
      </Dialog>
    </>
  )
}

export default memo(ToolForm)
