import type { ButtonProps } from '@blueprintjs/core'
import { Button, Dialog, DialogBody, DialogFooter } from '@blueprintjs/core'
import { notify } from '@inject/shared/notification/engine'
import { memo, useCallback, useEffect, useState, type FC } from 'react'
import useValidateExpression from '../ExpressionBuilder/useValidateExpression'
import ToolResponseForm from '../ToolResponseFormContent'
import { GENERIC_CONTENT } from '../assets/generalContent'
import { addToolResponse, updateToolResponse } from '../indexeddb/operations'
import type { ToolResponse } from '../indexeddb/types'

interface ToolResponseFormDialogProps {
  response?: ToolResponse
  toolId: number
  buttonProps: ButtonProps
}

const ToolResponseFormDialog: FC<ToolResponseFormDialogProps> = ({
  response,
  toolId,
  buttonProps,
}) => {
  const [isOpen, setIsOpen] = useState(false)

  const [parameter, setParameter] = useState<string>('')
  const [content, setContent] = useState<string>('')
  const [isRegex, setIsRegex] = useState<boolean>(false)
  const [selectedToolId, setSelectedToolId] = useState<number>(0)
  const [fileId, setFileId] = useState<number>(0)
  const [time, setTime] = useState<number>(0)
  const [milestoneCondition, setMilestoneCondition] = useState<number[]>([])
  const { isValid } = useValidateExpression(milestoneCondition)

  const clearInput = useCallback(() => {
    setParameter('')
    setContent('')
    setIsRegex(false)
    setTime(0)
    setFileId(0)
    setMilestoneCondition([])
  }, [])

  useEffect(() => {
    setParameter(response?.parameter || '')
    setContent(response?.content || '')
    setIsRegex(response?.isRegex || false)
    setSelectedToolId(response?.toolId || toolId)
    setFileId(response?.fileId || 0)
    setTime(response?.time || 0)
    setMilestoneCondition(response?.milestoneCondition || [])
  }, [toolId, response, isOpen])

  const handleAddButton = useCallback(
    async (toolResponse: Omit<ToolResponse, 'id'>) => {
      try {
        await addToolResponse(toolResponse)
        clearInput()
        setIsOpen(false)
      } catch (err) {
        notify(
          `Failed to add tool response '${toolResponse.parameter}': ${err}`,
          {
            intent: 'danger',
          }
        )
      }
    },
    [notify]
  )

  const handleUpdateButton = useCallback(
    async (toolResponse: ToolResponse) => {
      try {
        await updateToolResponse(toolResponse)
        setIsOpen(false)
      } catch (err) {
        notify(
          `Failed to update tool response '${toolResponse.parameter}': ${err}`,
          {
            intent: 'danger',
          }
        )
      }
    },
    [notify]
  )

  return (
    <>
      <Button {...buttonProps} onClick={() => setIsOpen(true)} />
      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        icon={response ? 'edit' : 'plus'}
        title={response ? 'Edit tool response' : 'New tool response'}
      >
        <DialogBody>
          <ToolResponseForm
            parameter={parameter}
            content={content}
            isRegex={isRegex}
            toolId={selectedToolId}
            fileId={fileId}
            time={time}
            milestoneCondition={response?.milestoneCondition}
            onParameterChange={(value: string) => setParameter(value)}
            onContentChange={(value: string) => setContent(value)}
            onIsRegexChange={(value: boolean) => setIsRegex(value)}
            onToolIdChange={(value: number) => setSelectedToolId(value)}
            onFileIdChange={(value: number) => setFileId(value)}
            onTimeChange={(value: number) => setTime(value)}
            onMilestoneConditionChange={(value: number[]) =>
              setMilestoneCondition(value)
            }
          />
        </DialogBody>
        <DialogFooter
          actions={
            response ? (
              <Button
                disabled={!parameter || !isValid}
                onClick={() =>
                  handleUpdateButton({
                    id: response.id,
                    learningActivityId: response.learningActivityId,
                    parameter,
                    content,
                    isRegex,
                    toolId: selectedToolId,
                    fileId,
                    time,
                    milestoneCondition: isValid ? milestoneCondition : [],
                  })
                }
                intent='primary'
                icon='edit'
                text={GENERIC_CONTENT.buttons.save}
              />
            ) : (
              <Button
                disabled={!parameter}
                onClick={() =>
                  handleAddButton({
                    parameter,
                    content,
                    isRegex,
                    toolId: selectedToolId,
                    fileId,
                    time,
                    milestoneCondition: isValid ? milestoneCondition : [],
                  })
                }
                intent='primary'
                icon='plus'
                text={GENERIC_CONTENT.buttons.add}
              />
            )
          }
        />
      </Dialog>
    </>
  )
}

export default memo(ToolResponseFormDialog)
