import {
  getEmailInjects,
  getInformationInjects,
} from '@/editor/indexeddb/joins'
import {
  type JoinedEmailInject,
  type JoinedEmailInjectCategory,
  type JoinedInformationInject,
  type JoinedInformationInjectCategory,
} from '@/editor/indexeddb/types'
import notEmpty from '@inject/shared/utils/notEmpty'
import { isEmpty, pickBy } from 'lodash'
import { generateContent, generateControl, generateOverlay } from './shared'

const generateInformationInject = async (
  name: string,
  info: JoinedInformationInject
) =>
  pickBy({
    name: name,
    content: await generateContent(`ii_${info.id}`, info.content, info.file),
    control: generateControl(info.activateMilestone, info.milestoneCondition),
    overlay: generateOverlay(info.overlay),
  })

const generateEmailInject = async (name: string, email: JoinedEmailInject) =>
  pickBy({
    name: name,
    sender: email.sender?.address,
    subject: email.subject,
    extra_copies: email.extraCopies,
    content: await generateContent(`ei_${email.id}`, email.content, email.file),
    control: generateControl(email.activateMilestone, email.milestoneCondition),
    overlay: generateOverlay(email.overlay),
  })

export const generateInjects = async () => {
  const informationInjects = await getInformationInjects()
  const emailInjects = await getEmailInjects()

  const generatedInformationInjects = await Promise.all(
    informationInjects
      .filter(notEmpty)
      .map(async (inject: JoinedInformationInjectCategory) =>
        pickBy({
          name: inject.name,
          time: inject.injectControl?.start,
          delay: inject.injectControl?.delay,
          type: 'info',
          alternatives: [
            await generateInformationInject(inject.name, inject.info),
          ],
        })
      )
  )

  const generatedEmailInjects = await Promise.all(
    emailInjects
      .filter(notEmpty)
      .map(async (inject: JoinedEmailInjectCategory) =>
        pickBy({
          name: inject.name,
          time: inject.injectControl?.start,
          delay: inject.injectControl?.delay,
          type: 'email',
          alternatives: [await generateEmailInject(inject.name, inject.email)],
        })
      )
  )

  const generatedInjects = [
    ...generatedInformationInjects,
    ...generatedEmailInjects,
  ].sort((inject1, inject2) => {
    // eslint-disable-next-line no-constant-binary-expression
    const time1 = Number(inject1.time) ?? 0
    // eslint-disable-next-line no-constant-binary-expression
    const time2 = Number(inject2.time) ?? 0
    return time1 - time2
  })

  return isEmpty(generatedInjects) ? undefined : generatedInjects
}
