import { TextArea } from '@blueprintjs/core'
import { notify } from '@inject/shared/notification/engine'
import { useLiveQuery } from 'dexie-react-hooks'
import { memo, useCallback, useEffect, useState, type FC } from 'react'
import FileSelector from '../FileSelector'
import SaveButtonGroup from '../SaveButtonGroup'
import TooltipLabel from '../Tooltips/TooltipLabel'
import { INFORMATION_INJECT_FORM } from '../assets/pageContent/injectSpecification'
import {
  addInformationInject,
  getInformationInjectByInjectInfoId,
  updateInformationInject,
} from '../indexeddb/operations'
import type { InformationInject } from '../indexeddb/types'

interface InformationInjectFormProps {
  injectInfoId: number
  changed: boolean
  onChangedChange: (value: boolean) => void
}

const InformationInjectForm: FC<InformationInjectFormProps> = ({
  injectInfoId,
  changed,
  onChangedChange,
}) => {
  const informationInject = useLiveQuery(
    () => getInformationInjectByInjectInfoId(injectInfoId),
    [injectInfoId],
    null
  ) as InformationInject

  const [content, setContent] = useState<string>('')
  const [fileId, setFileId] = useState<number>(0)

  useEffect(() => {
    setContent(informationInject?.content || '')
    setFileId(informationInject?.fileId || 0)
  }, [informationInject])

  const updateInject = useCallback(
    async (
      newInformationInject: InformationInject | Omit<InformationInject, 'id'>
    ) => {
      try {
        if (informationInject) {
          await updateInformationInject({
            id: informationInject.id,
            ...newInformationInject,
          })
        } else {
          await addInformationInject(newInformationInject)
        }
      } catch (error) {
        notify(
          `Failed to update information inject: ${error}`,
          JSON.stringify(error),
          {
            intent: 'danger',
          }
        )
      }
    },
    [informationInject]
  )

  const handleUpdate = useCallback(async () => {
    if (!changed) onChangedChange(true)
    await updateInject({
      injectInfoId,
      content,
      fileId,
    })
    onChangedChange(false)
  }, [changed, injectInfoId, content, fileId, updateInject])

  useEffect(() => {
    if (changed) handleUpdate()
  }, [changed, handleUpdate])

  return (
    <div>
      <TooltipLabel label={INFORMATION_INJECT_FORM.content}>
        <TextArea
          value={content}
          style={{
            width: '100%',
            height: '10rem',
            resize: 'none',
            overflowY: 'auto',
          }}
          placeholder='Input text'
          onChange={e => setContent(e.target.value)}
        />
      </TooltipLabel>
      <FileSelector
        label={INFORMATION_INJECT_FORM.file}
        fileId={fileId}
        onChange={id => setFileId(id)}
      />
      <SaveButtonGroup
        isValid
        handleUpdate={() => handleUpdate()}
        prevPath='/editor/create/inject-specification'
      />
    </div>
  )
}

export default memo(InformationInjectForm)
