import Mailgun from 'mailgun.js'
import formData from 'form-data'
import type {
  EmailService,
  SendEmailInput,
  SendEmailResult,
} from '@pikku/core/services'

const isProduction = process.env.NODE_ENV === 'production'

export class MailgunEmailService implements EmailService {
  private readonly mg: ReturnType<Mailgun['client']> | undefined

  constructor(
    apiKey: string | undefined,
    private readonly domain: string,
  ) {
    if (apiKey) {
      const mailgun = new Mailgun(formData)
      this.mg = mailgun.client({
        username: 'api',
        key: apiKey,
        url: 'https://api.eu.mailgun.net',
      })
    }
  }

  async send(input: SendEmailInput): Promise<SendEmailResult> {
    if ('template' in input) {
      throw new Error('MailgunEmailService expects rendered email content, not template references')
    }

    if (!isProduction || !this.mg) {
      const recipients = normalizeRecipients(input.to)
      console.log(
        `Would have sent email to ${recipients.join(', ')} with subject "${input.subject || ''}"`
      )
      return {}
    }

    const result = await this.mg.messages.create('mail.hey-germany.com', {
      from: input.from || `HeyGermany <info@${this.domain}>`,
      to: normalizeRecipients(input.to),
      cc: normalizeRecipients(input.cc),
      bcc: normalizeRecipients(input.bcc),
      subject: input.subject,
      html: 'html' in input ? input.html : undefined,
      text: 'text' in input ? input.text : undefined,
      h: input.headers,
    } as any)

    return {
      messageId: typeof result === 'object' && result && 'id' in result
        ? String(result.id)
        : undefined,
    }
  }
}

const normalizeRecipients = (value?: string | string[]) => {
  if (!value) {
    return []
  }

  return Array.isArray(value) ? value : [value]
}
