import {
  addEmailAddress,
  updateEmailAddress,
} from '@/editor/indexeddb/operations'
import type { ButtonProps } from '@blueprintjs/core'
import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  InputGroup,
} from '@blueprintjs/core'
import { notify } from '@inject/shared/notification/engine'
import type { FC } from 'react'
import { memo, useCallback, useEffect, useState } from 'react'
import TooltipCheckbox from '../Tooltips/TooltipCheckbox'
import TooltipLabel from '../Tooltips/TooltipLabel'
import { GENERIC_CONTENT } from '../assets/generalContent'
import { EMAIL_ADDRESS_FORM } from '../assets/pageContent/emails'
import type { EmailAddressInfo } from '../indexeddb/types'

interface EmailAddressFormProps {
  emailAddressInfo?: EmailAddressInfo
  buttonProps: ButtonProps
  onAdd?: (id: number) => void
}

const EmailAddressForm: FC<EmailAddressFormProps> = ({
  emailAddressInfo,
  buttonProps,
  onAdd,
}) => {
  const [isOpen, setIsOpen] = useState(false)
  const [address, setAddress] = useState<string>('')
  const [organization, setOrganization] = useState<string>('')
  const [description, setDescription] = useState<string>('')
  const [teamVisible, setTeamVisible] = useState<boolean>(true)

  const clearInput = useCallback(() => {
    setAddress('')
    setOrganization('')
    setDescription('')
    setTeamVisible(true)
  }, [])

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

  const handleUpdateButton = useCallback(
    async (emailAddress: EmailAddressInfo) => {
      try {
        await updateEmailAddress(emailAddress)
        setIsOpen(false)
      } catch (error) {
        notify(
          `Failed to update email address '${emailAddress.address}': ${error}`,
          JSON.stringify(error),
          {
            intent: 'danger',
          }
        )
      }
    },
    []
  )

  useEffect(() => {
    setAddress(emailAddressInfo?.address || '')
    setOrganization(emailAddressInfo?.organization || '')
    setDescription(emailAddressInfo?.description || '')
    setTeamVisible(emailAddressInfo?.teamVisible ?? true)
  }, [emailAddressInfo])

  return (
    <>
      <Button {...buttonProps} onClick={() => setIsOpen(true)} />
      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        icon={emailAddressInfo ? 'edit' : 'plus'}
        title={emailAddressInfo ? 'Edit email address' : 'New email address'}
      >
        <DialogBody>
          <TooltipLabel label={EMAIL_ADDRESS_FORM.address}>
            <InputGroup
              placeholder='Input text'
              value={address}
              onChange={e => setAddress(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={EMAIL_ADDRESS_FORM.organization}>
            <InputGroup
              placeholder='Input text'
              value={organization}
              onChange={e => setOrganization(e.target.value)}
            />
          </TooltipLabel>
          <TooltipLabel label={EMAIL_ADDRESS_FORM.description}>
            <InputGroup
              placeholder='Input text'
              value={description}
              onChange={e => setDescription(e.target.value)}
            />
          </TooltipLabel>
          <TooltipCheckbox
            label={EMAIL_ADDRESS_FORM.teamVisible}
            checkboxProps={{
              checked: teamVisible,
              onChange: () => setTeamVisible(!teamVisible),
            }}
          />
        </DialogBody>
        <DialogFooter
          actions={
            emailAddressInfo ? (
              <Button
                disabled={!address || !description}
                onClick={() =>
                  handleUpdateButton({
                    id: emailAddressInfo.id,
                    address,
                    organization,
                    description,
                    teamVisible,
                  })
                }
                intent='primary'
                icon='edit'
                text={GENERIC_CONTENT.buttons.save}
              />
            ) : (
              <Button
                disabled={!address || !description}
                onClick={() =>
                  handleAddButton({
                    address,
                    organization,
                    description,
                    teamVisible,
                  })
                }
                intent='primary'
                icon='plus'
                text={GENERIC_CONTENT.buttons.add}
              />
            )
          }
        />
      </Dialog>
    </>
  )
}

export default memo(EmailAddressForm)
