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 EmailTemplateFormContent from '../EmailTemplateFormContent'
import { GENERIC_CONTENT } from '../assets/generalContent'
import { addEmailTemplate, updateEmailTemplate } from '../indexeddb/operations'
import type { EmailTemplate } from '../indexeddb/types'

interface EmailTemplateFormDialogProps {
  template?: EmailTemplate
  emailAddressId: number
  buttonProps: ButtonProps
}

const EmailTemplateFormDialog: FC<EmailTemplateFormDialogProps> = ({
  template,
  emailAddressId,
  buttonProps,
}) => {
  const [isOpen, setIsOpen] = useState(false)

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

  useEffect(() => {
    setContext(template?.context || '')
    setContent(template?.content || '')
    setSelectedAddressId(template?.emailAddressId || emailAddressId)
    setFileId(template?.fileId || 0)
  }, [template, isOpen, emailAddressId])

  const clearInput = useCallback(() => {
    setContext('')
    setContent('')
    setFileId(0)
  }, [])

  const handleAddButton = useCallback(
    async (emailTemplate: Omit<EmailTemplate, 'id'>) => {
      try {
        await addEmailTemplate(emailTemplate)
        clearInput()
        setIsOpen(false)
      } catch (error) {
        notify(
          `Failed to add template '${emailTemplate.context}': ${error}`,
          JSON.stringify(error),
          {
            intent: 'danger',
          }
        )
      }
    },
    []
  )

  const handleUpdateButton = useCallback(
    async (emailTemplate: EmailTemplate) => {
      try {
        await updateEmailTemplate(emailTemplate)
        setIsOpen(false)
      } catch (error) {
        notify(
          `Failed to update template '${emailTemplate.context}': ${error}`,
          JSON.stringify(error),
          {
            intent: 'danger',
          }
        )
      }
    },
    []
  )

  return (
    <>
      <Button {...buttonProps} onClick={() => setIsOpen(true)} />
      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        icon={template ? 'edit' : 'plus'}
        title={template ? 'Edit template' : 'New template'}
      >
        <DialogBody>
          <EmailTemplateFormContent
            context={context}
            content={content}
            emailAddressId={selectedAddressId}
            fileId={fileId}
            onContextChange={(value: string) => setContext(value)}
            onContentChange={(value: string) => setContent(value)}
            onEmailAddressIdChange={(value: number) =>
              setSelectedAddressId(value)
            }
            onFileIdChange={(value: number) => setFileId(value)}
          />
        </DialogBody>
        <DialogFooter
          actions={
            template ? (
              <Button
                disabled={!context || !selectedAddressId}
                onClick={() =>
                  handleUpdateButton({
                    id: template.id,
                    learningActivityId: template.learningActivityId,
                    context,
                    content,
                    emailAddressId: selectedAddressId,
                    fileId,
                  })
                }
                intent='primary'
                icon='edit'
                text={GENERIC_CONTENT.buttons.save}
              />
            ) : (
              <Button
                disabled={!context || !selectedAddressId}
                onClick={() =>
                  handleAddButton({
                    context,
                    content,
                    emailAddressId: selectedAddressId,
                    fileId,
                  })
                }
                intent='primary'
                icon='plus'
                text={GENERIC_CONTENT.buttons.add}
              />
            )
          }
        />
      </Dialog>
    </>
  )
}

export default memo(EmailTemplateFormDialog)
