'use strict'
const cfg = require('./config')
const { log } = require('./helpers')

let _transporter = null
// Side-channel for the most recent send failure. Callers that need the
// specific reason (e.g. campaign worker that wants to display it in the
// UI) read this after a falsy return from sendEmail. Cleared at the
// start of every send call. NOT thread-safe — fine for the worker's
// sequential loop, but if we ever parallelise sends we'd need a proper
// returned result tuple instead.
let _lastError = null
function getLastError () { return _lastError }

function getTransporter () {
  if (_transporter) return _transporter
  try {
    const nodemailer = require('nodemailer')

    if (cfg.SMTP_USER && cfg.SMTP_PASS) {
      _transporter = nodemailer.createTransport({
        host: cfg.SMTP_HOST,
        port: cfg.SMTP_PORT,
        secure: cfg.SMTP_SECURE,
        auth: { user: cfg.SMTP_USER, pass: cfg.SMTP_PASS },
      })
      log(`Email transport configured: ${cfg.SMTP_HOST}:${cfg.SMTP_PORT} as ${cfg.SMTP_USER}`)
    } else {
      // Direct delivery (no SMTP relay) — sends directly to recipient MX
      _transporter = nodemailer.createTransport({ direct: true, name: 'msg.gigafibre.ca' })
      log('Email transport: direct MX delivery (no SMTP relay configured)')
    }
  } catch (e) {
    log('Email transport init failed:', e.message)
    return null
  }
  return _transporter
}

/**
 * Send an HTML email with optional PDF attachment
 * @param {object} opts
 * @param {string} opts.to - Recipient email
 * @param {string} opts.subject - Subject line
 * @param {string} opts.html - HTML body
 * @param {Buffer} [opts.pdfBuffer] - Optional PDF attachment
 * @param {string} [opts.pdfFilename] - PDF filename
 * @returns {Promise<boolean>} true if sent
 */
async function sendEmail (opts) {
  _lastError = null
  const transport = getTransporter()
  if (!transport) {
    _lastError = new Error('No transport available (SMTP not configured)')
    log('Cannot send email — no transport available')
    return false
  }

  const mailOpts = {
    from: opts.from || cfg.MAIL_FROM,
    to: opts.to,
    subject: opts.subject,
    html: opts.html,
    attachments: [],
    // Custom headers (e.g. X-MJ-CustomID for Mailjet Event API webhook
    // correlation — Mailjet echoes the CustomID back in every event so
    // we can match webhook events to the originating recipient).
    headers: opts.headers || {},
  }

  if (opts.pdfBuffer && opts.pdfFilename) {
    mailOpts.attachments.push({
      filename: opts.pdfFilename,
      content: opts.pdfBuffer,
      contentType: 'application/pdf',
    })
  }

  // Generic attachments (e.g. event invitation images) : [{ filename, content(Buffer), contentType|mime }]
  if (Array.isArray(opts.attachments)) {
    for (const a of opts.attachments) {
      if (a && a.filename && a.content) {
        mailOpts.attachments.push({
          filename: a.filename,
          content: a.content,
          contentType: a.contentType || a.mime || 'application/octet-stream',
        })
      }
    }
  }

  try {
    const info = await transport.sendMail(mailOpts)
    log(`Email sent to ${opts.to}: ${info.messageId || 'OK'}`)
    // Return the info object (always truthy) so callers can capture
    // info.messageId for tracking. Legacy `if (await sendEmail(...))`
    // callers continue to work because the object is truthy.
    return info || { messageId: null }
  } catch (e) {
    _lastError = e
    log(`Email send failed to ${opts.to}: ${e.message}`)
    // Legacy contract: return false on failure. New callers that need the
    // error string should call email.getLastError() right after a falsy
    // return — set above, cleared at the start of every send call.
    return false
  }
}

/**
 * Send a quotation acceptance email with PDF attached
 */
async function sendQuotationEmail (opts) {
  const { to, quotationName, acceptLink, pdfBuffer } = opts

  const html = `<!DOCTYPE html>
<html><head><meta charset="utf-8"></head><body style="font-family:'Inter',system-ui,sans-serif;margin:0;padding:0;background:#f1f5f9">
<div style="max-width:580px;margin:0 auto;padding:24px">
  <div style="background:white;border-radius:16px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.06)">
    <div style="background:linear-gradient(135deg,#6366f1,#8b5cf6);color:white;padding:24px 28px">
      <h1 style="margin:0;font-size:20px;font-weight:700">Votre devis est pr&ecirc;t</h1>
      <p style="margin:6px 0 0;opacity:0.85;font-size:13px">Devis ${quotationName}</p>
    </div>
    <div style="padding:24px 28px">
      <p style="color:#334155;font-size:15px;line-height:1.6;margin:0 0 20px">
        Bonjour,<br><br>
        Votre devis <b>${quotationName}</b> est pr&ecirc;t pour votre examen.
        Cliquez sur le bouton ci-dessous pour le consulter et l'accepter.
      </p>
      <div style="text-align:center;margin:24px 0">
        <a href="${acceptLink}" style="display:inline-block;background:#6366f1;color:white;padding:14px 32px;border-radius:10px;text-decoration:none;font-weight:700;font-size:15px">
          Voir et accepter le devis
        </a>
      </div>
      <p style="color:#64748b;font-size:13px;text-align:center;margin:16px 0 0">
        ${pdfBuffer ? 'Le PDF du devis est &eacute;galement joint &agrave; ce courriel.' : ''}
        Ce lien est valide pour 7 jours.
      </p>
    </div>
    <div style="border-top:1px solid #e2e8f0;padding:16px 28px;text-align:center">
      <p style="color:#94a3b8;font-size:11px;margin:0">Gigafibre &mdash; Targo T&eacute;l&eacute;communications</p>
    </div>
  </div>
</div>
</body></html>`

  return sendEmail({
    to,
    subject: `Devis ${quotationName} — Acceptation requise`,
    html,
    pdfBuffer: pdfBuffer || null,
    pdfFilename: pdfBuffer ? `${quotationName}.pdf` : null,
  })
}

module.exports = { sendEmail, sendQuotationEmail, getLastError }
