import ContentArea from '@/components/ContentArea'
import FileArea from '@/components/FileArea'
import { Button, ButtonGroup, Divider, FormGroup } from '@blueprintjs/core'
import { css } from '@emotion/css'
import { useTypedMutation, useTypedQuery } from '@inject/graphql/graphql'
import { SendEmail } from '@inject/graphql/mutations'
import { GetEmailContacts } from '@inject/graphql/queries'
import { notify } from '@inject/shared/notification/engine'
import notEmpty from '@inject/shared/utils/notEmpty'
import type { FC } from 'react'
import { memo, useCallback } from 'react'
import TraineeHeaderArea from './TraineeHeaderArea'
import { form } from './classes'
import type { EmailFormProps, OnSendEmailInput } from './typing'
import useThreadSubmission from './useThreadSubmission'

const footer = css`
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
`

const TraineeEmailForm: FC<EmailFormProps> = ({
  exerciseId,
  emailThread,
  teamId,
  onSuccess,
  formState: {
    senderAddress,
    fileInfo,
    setFileInfo,
    content,
    setContent,
    discardDraft,
    storeDraft,
    selectedContacts,
    setSelectedContacts,
    bccSelectedContacts,
    setBccSelectedContacts,
    subject,
    setSubject,
  },
}) => {
  const [{ fetching: loading }, sendEmailMutate] = useTypedMutation(SendEmail)

  const { onSend } = useThreadSubmission({
    ...(emailThread
      ? { existingThreadId: emailThread.id }
      : {
          participantAddresses: [...selectedContacts, senderAddress],
          subject,
          bccAddresses: bccSelectedContacts,
        }),
    exerciseId,
    senderAddress,
    content,
    fileId: fileInfo?.id,
    onSendEmail: ({ threadId }: OnSendEmailInput) => {
      sendEmailMutate({
        sendEmailInput: {
          threadId,
          senderAddress,
          content,
          fileId: fileInfo?.id,
          activateMilestone: null,
          deactivateMilestone: null,
        },
      })
        .then(() => {
          discardDraft()
          onSuccess()
        })
        .catch(err => {
          notify(err.message, {
            intent: 'danger',
          })
        })
    },
  })

  const [{ data: emailContacts }] = useTypedQuery({
    query: GetEmailContacts,
    variables: {
      visibleOnly: true,
    },
    requestPolicy: 'network-only',
  })

  const traineeList = (emailContacts?.emailContacts || []).filter(notEmpty)

  const onDiscard = useCallback(() => {
    discardDraft()
    onSuccess()
  }, [discardDraft, onSuccess])

  const onSave = useCallback(() => {
    storeDraft()
    onSuccess()
  }, [onSuccess, storeDraft])

  return (
    <div className={form}>
      <TraineeHeaderArea
        {...(emailThread
          ? {
              emailThread,
            }
          : {
              selectedContacts,
              setSelectedContacts,
              bccSelectedContacts,
              setBccSelectedContacts,
              subject,
              setSubject,
            })}
        contacts={traineeList}
        teamAddress={senderAddress}
        exerciseId={exerciseId}
      />
      <Divider style={{ margin: '0.5rem 0' }} />

      <ContentArea content={content} setContent={setContent} />

      <Divider style={{ margin: '0.5rem 0' }} />

      <div className={footer}>
        <FileArea
          exerciseId={exerciseId}
          fileInfo={fileInfo}
          setFileInfo={setFileInfo}
          teamId={teamId}
        />

        <FormGroup disabled={loading} style={{ margin: '0' }}>
          <ButtonGroup>
            <Button icon='trash' onClick={onDiscard}>
              Discard
            </Button>
            <Button icon='floppy-disk' onClick={onSave}>
              Save
            </Button>
            <Button
              type='submit'
              rightIcon='send-message'
              onClick={onSend}
              loading={loading}
            >
              Send
            </Button>
          </ButtonGroup>
        </FormGroup>
      </div>
    </div>
  )
}

export default memo(TraineeEmailForm)
