import { InputGroup, NumericInput, 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 EmailAddressSelector from '../EmailAddressSelector'
import FileSelector from '../FileSelector'
import SaveButtonGroup from '../SaveButtonGroup'
import TooltipLabel from '../Tooltips/TooltipLabel'
import { EMAIL_ADDRESS_FORM } from '../assets/pageContent/emails'
import { EMAIL_INJECT_FORM } from '../assets/pageContent/injectSpecification'
import {
  addEmailInject,
  getEmailInjectByInjectInfoId,
  updateEmailInject,
} from '../indexeddb/operations'
import type { EmailInject } from '../indexeddb/types'

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

const EmailInjectForm: FC<EmailInjectFormProps> = ({
  injectInfoId,
  changed,
  onChangedChange,
}) => {
  const emailInject = useLiveQuery(
    () => getEmailInjectByInjectInfoId(injectInfoId),
    [injectInfoId],
    null
  ) as EmailInject

  const [subject, setSubject] = useState<string>('')
  const [content, setContent] = useState<string>('')
  const [selectedAddressId, setSelectedAddressId] = useState<number>(0)
  const [extraCopies, setExtraCopies] = useState<number>(0)
  const [fileId, setFileId] = useState<number>(0)

  useEffect(() => {
    setSubject(emailInject?.subject || '')
    setContent(emailInject?.content || '')
    setSelectedAddressId(emailInject?.emailAddressId || 0)
    setExtraCopies(emailInject?.extraCopies || 0)
    setFileId(emailInject?.fileId || 0)
  }, [emailInject])

  const updateInject = useCallback(
    async (newEmailInject: EmailInject | Omit<EmailInject, 'id'>) => {
      try {
        if (emailInject) {
          await updateEmailInject({ id: emailInject.id, ...newEmailInject })
        } else {
          await addEmailInject(newEmailInject)
        }
      } catch (err) {
        notify(`Failed to update email inject: ${err}`, {
          intent: 'danger',
        })
      }
    },
    [notify, emailInject]
  )

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

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

  return (
    <div>
      <EmailAddressSelector
        label={EMAIL_ADDRESS_FORM.address}
        emailAddressId={selectedAddressId}
        onChange={id => setSelectedAddressId(id)}
      />
      <TooltipLabel label={EMAIL_INJECT_FORM.subject}>
        <InputGroup
          placeholder='Input text'
          value={subject}
          onChange={e => setSubject(e.target.value)}
        />
      </TooltipLabel>
      <TooltipLabel label={EMAIL_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>
      <TooltipLabel label={EMAIL_INJECT_FORM.extraCopies}>
        <NumericInput
          placeholder='Input number'
          min={0}
          value={extraCopies}
          onValueChange={(value: number) => setExtraCopies(value)}
        />
      </TooltipLabel>
      <FileSelector
        label={EMAIL_INJECT_FORM.file}
        fileId={fileId}
        onChange={id => setFileId(id)}
      />
      <SaveButtonGroup
        isValid
        handleUpdate={() => handleUpdate()}
        prevPath='/editor/create/inject-specification'
      />
    </div>
  )
}

export default memo(EmailInjectForm)
