import { config } from '../config.js'
import { prisma } from '../db.js'
import { audit } from './audit.js'
import nodemailer from 'nodemailer'

type LicenseEmailInput = {
  licenseId: string
  customerEmail: string | null
  customerName: string | null
  licenseKey: string
  adminId?: string
  resend?: boolean
}

function licenseEmailText(input: LicenseEmailInput) {
  return `Thank you for purchasing StackLogic Professional.

Your lifetime license key is:

${input.licenseKey}

Enter this license key into StackLogic Professional when prompted.

Download StackLogic:
${config.STACKLOGIC_DOWNLOAD_URL}

If you have any questions or problems using your license, reply to this email or contact StackLogic support.

Thank you,
StackLogic`
}

async function postJson(url: string, body: unknown, headers: Record<string, string>) {
  const response = await fetch(url, {
    method: 'POST',
    headers: { 'content-type': 'application/json', ...headers },
    body: JSON.stringify(body),
  })

  if (!response.ok) {
    throw new Error(`Email provider returned ${response.status}: ${await response.text()}`)
  }
}

export async function sendLicenseEmail(input: LicenseEmailInput) {
  if (!input.customerEmail) {
    const message = 'Customer email is missing.'
    await prisma.license.update({
      where: { id: input.licenseId },
      data: { emailStatus: 'failed', lastEmailError: message },
    })
    throw new Error(message)
  }

  const subject = 'Your StackLogic Professional License'
  const text = licenseEmailText(input)

  try {
    if (config.EMAIL_PROVIDER === 'postmark') {
      if (!config.POSTMARK_SERVER_TOKEN) throw new Error('POSTMARK_SERVER_TOKEN is not configured.')
      await postJson('https://api.postmarkapp.com/email', {
        From: config.EMAIL_FROM,
        To: input.customerEmail,
        Subject: subject,
        TextBody: text,
      }, { 'X-Postmark-Server-Token': config.POSTMARK_SERVER_TOKEN })
    } else if (config.EMAIL_PROVIDER === 'resend') {
      if (!config.RESEND_API_KEY) throw new Error('RESEND_API_KEY is not configured.')
      await postJson('https://api.resend.com/emails', {
        from: config.EMAIL_FROM,
        to: input.customerEmail,
        subject,
        text,
      }, { authorization: `Bearer ${config.RESEND_API_KEY}` })
    } else if (config.EMAIL_PROVIDER === 'smtp') {
      if (!config.SMTP_HOST) throw new Error('SMTP_HOST is not configured.')
      if (!config.SMTP_PORT) throw new Error('SMTP_PORT is not configured.')
      if (!config.SMTP_USER) throw new Error('SMTP_USER is not configured.')
      if (!config.SMTP_PASSWORD) throw new Error('SMTP_PASSWORD is not configured.')

      const transporter = nodemailer.createTransport({
        host: config.SMTP_HOST,
        port: config.SMTP_PORT,
        secure: config.SMTP_SECURE,
        auth: {
          user: config.SMTP_USER,
          pass: config.SMTP_PASSWORD,
        },
      })

      await transporter.sendMail({
        from: config.EMAIL_FROM,
        to: input.customerEmail,
        subject,
        text,
      })
    } else {
      console.log(`[license-email:${config.EMAIL_PROVIDER}] To=${input.customerEmail}\n${text}`)
    }

    const sentAt = new Date()
    await prisma.license.update({
      where: { id: input.licenseId },
      data: { emailStatus: 'sent', emailSentAt: sentAt, lastEmailError: null },
    })
    await audit(input.resend ? 'license_email_resent' : 'license_email_sent', {
      adminId: input.adminId,
      licenseId: input.licenseId,
      metadata: { to: input.customerEmail },
    })
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown email error'
    await prisma.license.update({
      where: { id: input.licenseId },
      data: { emailStatus: 'failed', lastEmailError: message },
    })
    await audit(input.resend ? 'license_email_resend_failed' : 'license_email_failed', {
      adminId: input.adminId,
      licenseId: input.licenseId,
      metadata: { to: input.customerEmail, error: message },
    })
    throw error
  }
}
