import { Button, Dialog, NonIdealState } from '@blueprintjs/core'
import type { EmailTemplate, FileInfo } from '@inject/graphql/fragment-types'
import { useTypedQuery } from '@inject/graphql/graphql'
import { GetEmailTemplates, GetThreadTemplates } from '@inject/graphql/queries'
import { maximizedDialog } from '@inject/shared/css/dialog'
import notEmpty from '@inject/shared/utils/notEmpty'
import type { Dispatch, FC, SetStateAction } from 'react'
import { memo, useMemo, useState } from 'react'
import TemplateCard from './TemplateCard'

type EmailTemplatesProps = {
  setSenderAddress: Dispatch<SetStateAction<string>>
  setContent: Dispatch<SetStateAction<string>>
  setActivateMilestone: Dispatch<SetStateAction<string>>
  setDeactivateMilestone: Dispatch<SetStateAction<string>>
  setFileInfo: Dispatch<SetStateAction<FileInfo | undefined>>
  template: EmailTemplate | undefined
  setTemplate: Dispatch<SetStateAction<EmailTemplate | undefined>>
  teamId: string
  exerciseId: string
} & (
  | {
      // new thread
      setSubject: Dispatch<SetStateAction<string | undefined>>
      emailAddresses: string[]
      threadId?: undefined
    }
  | {
      // existing thread
      setSubject?: undefined
      emailAddresses?: undefined
      threadId: string
    }
)

const EmailTemplates: FC<EmailTemplatesProps> = ({
  setSubject,
  setSenderAddress,
  setContent,
  setActivateMilestone,
  setDeactivateMilestone,
  setFileInfo,
  template,
  setTemplate,
  teamId,
  exerciseId,
  emailAddresses,
  threadId,
}) => {
  const [{ data: newThreadData }] = useTypedQuery({
    query: GetEmailTemplates,
    pause: exerciseId === undefined || emailAddresses === undefined,
    variables: {
      exerciseId: exerciseId || '-1',
      emailAddresses: emailAddresses || [],
    },
  })
  const [{ data: existingThreadData }] = useTypedQuery({
    query: GetThreadTemplates,
    pause: threadId === undefined,
    variables: {
      threadId: threadId || '-1',
    },
  })

  const templates = (
    (threadId === undefined
      ? newThreadData?.emailTemplates
      : existingThreadData?.threadTemplates) || []
  ).filter(notEmpty)

  const [open, setOpen] = useState(false)

  const selectTemplate = (template: EmailTemplate) => {
    if (template.sender) {
      setSenderAddress(template.sender)
    }
    if (setSubject) {
      setSubject(template.subject)
    }
    setContent(template.content.raw)
    setActivateMilestone(template.control.activateMilestone)
    setDeactivateMilestone(template.control.deactivateMilestone)
    setFileInfo(template.content.fileInfo || undefined)
    setTemplate(template)

    setOpen(false)
  }

  const text = useMemo(() => {
    if (template) {
      return template.context
    }

    if (templates.length === 0) {
      return 'No templates available'
    }

    return 'Select a template...'
  }, [template, templates.length])

  return (
    <>
      <Button
        active={open}
        outlined
        minimal
        rightIcon='search-template'
        disabled={templates.length === 0}
        title={
          templates.length === 0
            ? 'No templates available for the selected recipients'
            : undefined
        }
        onClick={() => setOpen(true)}
        alignText='left'
      >
        {text}
      </Button>

      <Dialog
        className={maximizedDialog}
        icon='search-template'
        isOpen={open}
        onClose={() => setOpen(false)}
        title='Templates'
      >
        <div style={{ overflow: 'auto' }}>
          {templates.length === 0 ? (
            <div style={{ margin: '1rem' }}>
              <NonIdealState
                icon='low-voltage-pole'
                title='No templates'
                description='No email templates available for this thread'
              />
            </div>
          ) : (
            templates.map(template => (
              <TemplateCard
                key={template.context}
                template={template}
                teamId={teamId}
                exerciseId={exerciseId}
                onClick={() => {
                  selectTemplate(template)
                }}
              />
            ))
          )}
        </div>
      </Dialog>
    </>
  )
}

export default memo(EmailTemplates)
