import nodemailer from 'nodemailer'
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'

/*
 * Phone-IVR return-instructions email.
 * Called by the FreePBX IVR middleware (localhost service on the PBX box) AFTER it has
 * created the M_RMA in iDempiere. Email-only: no iDempiere, no cookie/session. Gated by
 * the shared secret (X-IVR-Secret) from runtimeConfig.ivr.sharedSecret. The recipient is
 * resolved by the middleware from the order's own ship-to user (never caller input).
 * Generates + attaches a return-label PDF (return address with the RMA number).
 *
 * Body: { to, cc?, lang?, rmaNos: string[], orderNo?, customerName?, items: [{name,value,qty}] }
 */

interface Item { name?: string; value?: string; qty?: number }

// Static return-address lines, pipe-separated in IVR_RETURN_ADDRESS (runtimeConfig.ivr.returnAddress).
// The RMA number is inserted as line 2 so the warehouse can match the parcel.
const DEFAULT_RETURN_ADDRESS = 'LogYou GmbH|Mühlenweg 4|35110 Butzbach'
const addressLines = (baseRaw: string, rmaNos: string[]) => {
  const base = String(baseRaw || DEFAULT_RETURN_ADDRESS).split('|').map(s => s.trim()).filter(Boolean)
  return [base[0] || 'LogYou GmbH', 'RMA ' + rmaNos.join(' / '), ...base.slice(1)]
}

const esc = (s: any) => String(s == null ? '' : s)
  .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
// keep only chars the PDF standard font (WinAnsi) can encode
const san = (s: any) => String(s == null ? '' : s).replace(/[^\x20-\x7E\xA0-\xFF]/g, ' ')

const buildHtmlDE = (rmaNos: string[], orderNo: string, customerName: string, items: Item[], addr: string[]) => {
  const rmaList = rmaNos.map(esc).join(', ')
  const rows = items.map(i => `
    <tr>
      <td style="padding:10px 12px;border-bottom:1px solid #e0e0e0;">${esc(i.value)}</td>
      <td style="padding:10px 12px;border-bottom:1px solid #e0e0e0;">${esc(i.name)}</td>
      <td style="padding:10px 12px;border-bottom:1px solid #e0e0e0;text-align:center;">${esc(i.qty)}</td>
    </tr>`).join('')
  const addrHtml = addr.map((l, idx) => idx === 0 ? `<strong>${esc(l)}</strong>` : esc(l)).join('<br>')
  return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"></head>
<body style="margin:0;padding:0;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:1.6;color:#333;background:#f4f4f4;">
  <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background:#f4f4f4;"><tr><td style="padding:20px 0;">
    <table role="presentation" width="600" cellspacing="0" cellpadding="0" style="margin:0 auto;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 4px rgba(0,0,0,.1);">
      <tr><td style="background:#2563eb;padding:30px 40px;text-align:center;">
        <h1 style="margin:0;color:#fff;font-size:24px;font-weight:600;">Rücksendeanweisungen</h1>
        <p style="margin:10px 0 0;color:#fff;font-size:16px;">RMA ${rmaList}</p>
      </td></tr>
      <tr><td style="padding:40px;">
        <p style="margin:0 0 20px;">Guten Tag${customerName ? ' ' + esc(customerName) : ''},</p>
        <p style="margin:0 0 20px;">vielen Dank für Ihren Anruf. Ihre Rückgabe wurde unter der/den folgenden RMA-Nummer(n) registriert:
           <strong>${rmaList}</strong>${orderNo ? ' (Bestellung ' + esc(orderNo) + ')' : ''}.</p>
        <h3 style="margin:24px 0 12px;font-size:16px;">Folgende Artikel werden zurückgesendet:</h3>
        <table role="presentation" cellspacing="0" cellpadding="0" style="width:100%;border-collapse:collapse;border:1px solid #e0e0e0;border-radius:6px;">
          <thead><tr style="background:#f8f9fa;">
            <th style="padding:12px;border-bottom:2px solid #e0e0e0;text-align:left;">Artikelnr.</th>
            <th style="padding:12px;border-bottom:2px solid #e0e0e0;text-align:left;">Bezeichnung</th>
            <th style="padding:12px;border-bottom:2px solid #e0e0e0;text-align:center;">Menge</th>
          </tr></thead><tbody>${rows}</tbody>
        </table>
        <h3 style="margin:28px 0 12px;font-size:16px;">So senden Sie zurück:</h3>
        <ol style="margin:0 0 20px;padding-left:20px;">
          <li>Verpacken Sie die Artikel sicher.</li>
          <li>Drucken Sie das beigefügte <strong>Rücksendeetikett (PDF)</strong> und kleben Sie es gut sichtbar auf das Paket.</li>
          <li>Senden Sie das Paket an die unten stehende Adresse. Die RMA-Nummer <strong>${rmaList}</strong> ist bereits Teil der Adresse.</li>
        </ol>
        <table role="presentation" cellspacing="0" cellpadding="0" style="width:100%;border-collapse:collapse;margin:0 0 10px;border:1px solid #e0e0e0;border-radius:6px;background:#f8f9fa;">
          <tr><td style="padding:16px;"><strong>Rücksendeadresse:</strong><br>${addrHtml}</td></tr>
        </table>
      </td></tr>
      <tr><td style="background:#f8f9fa;padding:20px 40px;text-align:center;border-top:1px solid #eee;">
        <p style="margin:0;font-size:12px;color:#888;">Diese E-Mail wurde automatisch versendet. Bitte antworten Sie nicht direkt auf diese E-Mail.</p>
      </td></tr>
    </table>
  </td></tr></table>
</body></html>`
}

const buildText = (rmaNos: string[], orderNo: string, items: Item[], addr: string[]) =>
  `Ihre Rückgabe wurde registriert.\n\nRMA-Nummer(n): ${rmaNos.join(', ')}${orderNo ? '\nBestellung: ' + orderNo : ''}\n\n` +
  `Artikel:\n${items.map(i => `- ${i.qty}x ${i.name || ''} (${i.value || ''})`).join('\n')}\n\n` +
  `So senden Sie zurück:\n1. Artikel sicher verpacken.\n2. Beigefügtes Rücksendeetikett (PDF) ausdrucken und auf das Paket kleben.\n3. Paket senden an:\n\n${addr.join('\n')}\n`

// Return-label PDF: a printable A4 sheet showing the return address (incl. RMA no), to be
// stuck on the parcel. Uses the standard Helvetica font (WinAnsi) — dynamic text sanitized.
async function buildLabelPdf (rmaNos: string[], orderNo: string, items: Item[], addr: string[]): Promise<Buffer> {
  const doc = await PDFDocument.create()
  const page = doc.addPage([595.28, 841.89]) // A4
  const font = await doc.embedFont(StandardFonts.Helvetica)
  const bold = await doc.embedFont(StandardFonts.HelveticaBold)
  const { width, height } = page.getSize()
  const navy = rgb(0.12, 0.22, 0.5)
  const black = rgb(0, 0, 0)
  const gray = rgb(0.42, 0.42, 0.42)
  const lightBlue = rgb(0.92, 0.95, 1)

  let y = height - 60
  page.drawText(san('Rücksendeetikett'), { x: 60, y, size: 24, font: bold, color: navy })
  y -= 16
  page.drawText('Return label', { x: 60, y, size: 11, font, color: gray })

  // RMA highlight box
  y -= 44
  page.drawRectangle({ x: 60, y: y - 6, width: width - 120, height: 42, color: lightBlue, borderColor: navy, borderWidth: 1 })
  page.drawText(san('RMA ' + rmaNos.join(' / ')), { x: 76, y: y + 8, size: 20, font: bold, color: navy })

  y -= 44
  page.drawText(san('Bitte dieses Etikett gut sichtbar außen auf das Paket kleben.'), { x: 60, y, size: 11, font, color: black })

  // Address box (shipping-label style)
  y -= 28
  const boxH = 150
  const boxTop = y
  page.drawRectangle({ x: 60, y: boxTop - boxH, width: 330, height: boxH, borderColor: black, borderWidth: 1.2 })
  let ay = boxTop - 26
  page.drawText(san('Empfänger / An:'), { x: 78, y: ay, size: 10, font, color: gray })
  ay -= 28
  addr.forEach((ln, idx) => {
    page.drawText(san(ln), { x: 78, y: ay, size: 15, font: idx === 0 ? bold : font, color: black })
    ay -= 24
  })

  // Order + items
  y = boxTop - boxH - 36
  if (orderNo) { page.drawText(san('Bestellung: ' + orderNo), { x: 60, y, size: 11, font, color: black }); y -= 22 }
  if (items && items.length) {
    page.drawText(san('Artikel:'), { x: 60, y, size: 11, font: bold, color: black }); y -= 18
    for (const it of items) {
      const line = '- ' + (it.qty != null ? it.qty + 'x  ' : '') + (it.name || '') + (it.value ? '  (' + it.value + ')' : '')
      page.drawText(san(line).substring(0, 90), { x: 70, y, size: 10, font, color: black })
      y -= 16
      if (y < 70) break
    }
  }
  page.drawText(san((addr[0] || 'LogYou GmbH') + ' · automatisch erstellt'), { x: 60, y: 40, size: 8, font, color: gray })

  const bytes = await doc.save()
  return Buffer.from(bytes)
}

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig()
  const secret = config.ivr?.sharedSecret
  const provided = getHeader(event, 'x-ivr-secret')
  if (!secret || !provided || provided !== secret) {
    setResponseStatus(event, 401)
    return { status: 401, message: 'Unauthorized' }
  }

  const body = await readBody(event)
  const rmaNos: string[] = Array.isArray(body?.rmaNos) ? body.rmaNos.map((x: any) => String(x)) : []
  const items: Item[] = Array.isArray(body?.items) ? body.items : []
  const orderNo = String(body?.orderNo || '')
  const customerName = String(body?.customerName || '')
  let to = String(body?.to || '').trim()
  const cc = String(body?.cc || '').trim()

  if (!rmaNos.length) {
    setResponseStatus(event, 400)
    return { status: 400, message: 'Missing rmaNos' }
  }

  const addr = addressLines(config.ivr?.returnAddress, rmaNos)

  // No customer email → send to staff (cc) only so the return is still actioned.
  const ccList: string[] = []
  if (!to) { to = cc || 'info@logyou.de' } else if (cc) { ccList.push(cc) }

  const html = buildHtmlDE(rmaNos, orderNo, customerName, items, addr)
  const text = buildText(rmaNos, orderNo, items, addr)
  const subject = `Rücksendeanweisungen – RMA ${rmaNos.join(', ')}`

  let pdf: Buffer | null = null
  try { pdf = await buildLabelPdf(rmaNos, orderNo, items, addr) } catch (e: any) { console.error('[ivr return email] PDF build failed:', e?.message || e) }

  const transporter = nodemailer.createTransport({
    host: 'localhost', port: 25, secure: false, tls: { rejectUnauthorized: false }
  })

  const mail: any = { from: 'no-reply@logyou.de', to, subject, text, html }
  if (ccList.length) mail.cc = ccList.join(', ')
  if (pdf) mail.attachments = [{ filename: `Ruecksendeetikett-RMA-${rmaNos.join('_')}.pdf`, content: pdf, contentType: 'application/pdf' }]

  try {
    await transporter.sendMail(mail)
  } catch (err: any) {
    console.error('[ivr return email] send error:', err?.message || err)
    setResponseStatus(event, 500)
    return { status: 500, message: 'Failed to send return instructions email' }
  }

  return { status: 200, message: 'Return instructions email sent', to, attachedPdf: !!pdf }
})
