#!/usr/bin/env node
'use strict'
/**
 * build-native-template.js — generate a template using NATIVE Unlayer blocks
 * (text / image / button / divider / html) instead of one giant Custom HTML
 * block. Produces matched .json (for the Unlayer editor canvas) and .html
 * (what the worker sends to recipients) in lockstep so what the operator
 * edits is exactly what the recipient receives.
 *
 * Usage:
 *   node build-native-template.js gift-email-native-reminder-fr
 *
 * Each template is defined as a JS module under templates-spec/<name>.js
 * exporting { body: { rows: [...] }, preheader, ariaLabel }.
 *
 * Native block coverage (granular editability in Unlayer):
 *   - text     : rich-text paragraphs, supports {{vars}}
 *   - image    : standalone logos, with alt + optional href
 *   - button   : single CTA, supports {{vars}} in href and label
 *   - divider  : horizontal rule
 *   - html     : escape-hatch for custom markup (chips, multi-logo strips)
 */

const fs = require('fs')
const path = require('path')

// ── ID counter so each block gets a unique htmlID Unlayer can reference ──
const counter = { u_row: 0, u_column: 0, u_content_text: 0, u_content_image: 0,
                  u_content_button: 0, u_content_divider: 0, u_content_html: 0 }
function nextId (kind) { counter[kind]++; return `${kind}_${counter[kind]}` }

// ── Default values shared across all blocks (Unlayer fills these on save) ──
const COMMON = {
  selectable: true, draggable: true, duplicatable: true, deletable: true,
  hideable: true, hideDesktop: false, displayCondition: null,
}

// ── Block factories — each returns { json: <Unlayer block>, html: <compiled> } ──
function textBlock ({ html, padding = '10px 36px', fontSize = '16px', fontWeight = 400,
                       color = '#374151', textAlign = 'left', lineHeight = '150%' }) {
  const id = nextId('u_content_text')
  return {
    json: {
      id, type: 'text',
      values: {
        ...COMMON, containerPadding: padding, anchor: '',
        fontWeight, fontSize, color, textAlign, lineHeight,
        linkStyle: { inherit: true },
        _meta: { htmlID: id, htmlClassNames: 'u_content_text' },
        text: html,
      },
    },
    html: `      <table style="font-family:'Plus Jakarta Sans', sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
        <tbody><tr><td style="overflow-wrap:break-word;word-break:break-word;padding:${padding};font-family:'Plus Jakarta Sans', sans-serif;" align="${textAlign}">
          <div class="u_content_text" style="font-size:${fontSize};font-weight:${fontWeight};color:${color};text-align:${textAlign};line-height:${lineHeight};">${html}</div>
        </td></tr></tbody>
      </table>`,
  }
}

function imageBlock ({ src, alt = '', width = 140, padding = '10px',
                       textAlign = 'center', href = '' }) {
  const id = nextId('u_content_image')
  const imgTag = `<img alt="${alt}" src="${src}" width="${width}" style="display:block;border:0;height:auto;outline:none;text-decoration:none;width:${width}px;max-width:100%;" />`
  const wrapped = href ? `<a href="${href}" target="_blank" style="text-decoration:none;">${imgTag}</a>` : imgTag
  // Centering an img with display:block via text-align doesn't work — the
  // text-align prop only affects inline content. The robust email-client
  // pattern (used by MJML, Litmus, Mailchimp) is to wrap the img in a
  // nested table with align="<textAlign>", which Outlook 2007-2019 respects
  // alongside modern clients.
  return {
    json: {
      id, type: 'image',
      values: {
        ...COMMON, containerPadding: padding, anchor: '',
        src: { url: src, width, height: 'auto', autoWidth: false, maxWidth: `${width}px` },
        textAlign, altText: alt,
        action: href ? { name: 'web', values: { href, target: '_blank' } } : { name: 'web', values: { href: '', target: '_blank' } },
        _meta: { htmlID: id, htmlClassNames: 'u_content_image' },
      },
    },
    html: `      <table role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
        <tbody><tr><td style="padding:${padding};text-align:${textAlign};" align="${textAlign}">
          <table role="presentation" cellpadding="0" cellspacing="0" border="0" align="${textAlign}" style="border-collapse:collapse;border-spacing:0;${textAlign === 'center' ? 'margin:0 auto;' : ''}">
            <tbody><tr><td style="width:${width}px;">
              ${wrapped}
            </td></tr></tbody>
          </table>
        </td></tr></tbody>
      </table>`,
  }
}

function buttonBlock ({ text, href, padding = '10px 25px',
                         buttonPadding = '30px 24px', bgColor = '#00C853',
                         color = '#FFFFFF', borderRadius = '12px',
                         fontSize = '32px', fontWeight = 700 }) {
  const id = nextId('u_content_button')
  return {
    json: {
      id, type: 'button',
      values: {
        ...COMMON, containerPadding: padding, anchor: '',
        href: { name: 'web', values: { href, target: '_blank' } },
        buttonColors: { color, backgroundColor: bgColor, hoverColor: color, hoverBackgroundColor: '#005026' },
        size: { autoWidth: false, width: '100%' },
        fontSize, fontWeight, textAlign: 'center', lineHeight: '120%',
        padding: buttonPadding, border: {}, borderRadius,
        _meta: { htmlID: id, htmlClassNames: 'u_content_button' },
        text: `<span style="font-size: ${fontSize}; line-height: 120%; font-weight: ${fontWeight};">${text}</span>`,
      },
    },
    html: `      <table role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0" style="border-collapse:separate;line-height:100%;">
        <tbody><tr><td style="padding:${padding};text-align:center;" align="center">
          <a href="${href}" target="_blank" class="u_content_button" style="display:inline-block;background:${bgColor};color:${color};font-family:'Space Grotesk', Helvetica, Arial, sans-serif;font-size:${fontSize};font-weight:${fontWeight};line-height:120%;text-decoration:none;padding:${buttonPadding};border-radius:${borderRadius};">${text}</a>
        </td></tr></tbody>
      </table>`,
  }
}

function htmlBlock ({ html, padding = '0' }) {
  const id = nextId('u_content_html')
  return {
    json: {
      id, type: 'html',
      values: {
        ...COMMON, containerPadding: padding, anchor: '',
        _meta: { htmlID: id, htmlClassNames: 'u_content_html' },
        html,
      },
    },
    html: `      <table role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
        <tbody><tr><td style="padding:${padding};">
          ${html}
        </td></tr></tbody>
      </table>`,
  }
}

function dividerBlock ({ padding = '10px', borderColor = '#e5e7eb' }) {
  const id = nextId('u_content_divider')
  return {
    json: {
      id, type: 'divider',
      values: {
        ...COMMON, containerPadding: padding, anchor: '',
        width: '100%', border: { borderTopWidth: '1px', borderTopStyle: 'solid', borderTopColor: borderColor },
        textAlign: 'center', _meta: { htmlID: id, htmlClassNames: 'u_content_divider' },
      },
    },
    html: `      <table role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
        <tbody><tr><td style="padding:${padding};">
          <hr style="border:none;border-top:1px solid ${borderColor};margin:0;width:100%;" />
        </td></tr></tbody>
      </table>`,
  }
}

// Bundle a list of blocks into a single Unlayer row+column with shared row styles.
function row (blocks, opts = {}) {
  const rowId = nextId('u_row'); const colId = nextId('u_column')
  const { backgroundColor = '', columnsBackgroundColor = '', padding = '0px',
           border = '', borderRadius = '', columnPadding = '0px' } = opts
  const rowBg = backgroundColor || 'transparent'
  const innerStyle = [
    border ? `border:${border}` : '',
    borderRadius ? `border-radius:${borderRadius}` : '',
    padding !== '0px' ? `padding:${padding}` : '',
    backgroundColor ? `background:${backgroundColor};background-color:${backgroundColor}` : '',
    'margin:0 auto', 'max-width:600px',
  ].filter(Boolean).join(';')
  return {
    json: {
      id: rowId, cells: [1],
      columns: [{
        id: colId,
        contents: blocks.map(b => b.json),
        values: { ...COMMON, _meta: { htmlID: colId, htmlClassNames: 'u_column' },
                  padding: columnPadding, border: {}, borderRadius: '0px', backgroundColor: columnsBackgroundColor },
      }],
      values: {
        ...COMMON, displayCondition: null, columns: false,
        backgroundColor, columnsBackgroundColor,
        backgroundImage: { url: '', fullWidth: true, repeat: 'no-repeat', size: 'custom', position: 'center' },
        padding, anchor: '', borderRadius,
        _meta: { htmlID: rowId, htmlClassNames: 'u_row' },
      },
    },
    html: `<div class="u-row-container" style="padding:${padding};background-color:${rowBg};">
  <div class="u-row" style="${innerStyle}">
    <div style="border-collapse:collapse;display:table;width:100%;height:100%;">
      <!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding:${padding};background-color:${rowBg};"><table role="presentation" cellpadding="0" cellspacing="0" border="0" width="600" align="center" style="border-collapse:collapse;background:${rowBg};"><tr><td style="${innerStyle.replace(/background[^;]+;?/, '')}"><![endif]-->
      <div class="u-col u-col-100" style="max-width:320px;min-width:600px;display:table-cell;vertical-align:top;">
        <div style="height:100%;width:100% !important;">
          <!--[if (!mso)&(!IE)]><!--><div style="box-sizing:border-box;height:100%;padding:${columnPadding};"><!--<![endif]-->
${blocks.map(b => b.html).join('\n')}
          <!--[if (!mso)&(!IE)]><!--></div><!--<![endif]-->
        </div>
      </div>
      <!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
    </div>
  </div>
</div>`,
  }
}

// Compose the full <html> shell — Unlayer-standard markup + our brand defaults.
function compileHtml (preheader, ariaLabel, rows) {
  return `<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="x-apple-disable-message-reformatting">
<!--[if !mso]><!--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]-->
<style type="text/css">
  @media only screen and (min-width: 620px) { .u-row { width: 600px !important; } .u-row .u-col { vertical-align: top; } .u-row .u-col-100 { width: 600px !important; } }
  @media only screen and (max-width: 620px) {
    .u-row-container { max-width: 100% !important; padding-left: 0 !important; padding-right: 0 !important; }
    .u-row { width: 100% !important; }
    .u-row .u-col { display: block !important; width: 100% !important; min-width: 320px !important; max-width: 100% !important; }
    .u-row .u-col > div { margin: 0 auto; }
  }
  body{margin:0;padding:0}table,td,tr{border-collapse:collapse;vertical-align:top}*{line-height:inherit}a[x-apple-data-detectors=true]{color:inherit!important;text-decoration:none!important}
  table, td { color: #1B2E24; } #u_body a { color: #00C853; text-decoration: underline; }
</style>
<!--[if !mso]><!--><link href="https://fonts.googleapis.com/css?family=Plus+Jakarta+Sans:400,500,600,700" rel="stylesheet" type="text/css"><!--<![endif]-->
</head>
<body class="clean-body u_body" style="margin:0;padding:0;-webkit-text-size-adjust:100%;background-color:#F5FAF7;color:#1B2E24">
<!--[if IE]><div class="ie-container"><![endif]--><!--[if mso]><div class="mso-container"><![endif]-->
<table role="presentation" id="u_body" style="border-collapse:collapse;table-layout:fixed;border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;vertical-align:top;min-width:320px;Margin:0 auto;background-color:#F5FAF7;width:100%" cellpadding="0" cellspacing="0">
<tbody>
<tr><td style="display:none !important;visibility:hidden;mso-hide:all;font-size:1px;color:#fff;line-height:1px;max-height:0;max-width:0;opacity:0;overflow:hidden;">${preheader}</td></tr>
<tr style="vertical-align:top"><td style="word-break:break-word;border-collapse:collapse !important;vertical-align:top">
<!--[if (mso)|(IE)]><table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color:#F5FAF7;" bgcolor="#F5FAF7"><table role="presentation" cellpadding="0" cellspacing="0" border="0" width="600" align="center"><tr><td><![endif]-->
<div aria-label="${ariaLabel}" aria-roledescription="email" role="article" lang="und" dir="auto" style="word-spacing:normal;background-color:#F5FAF7;">

${rows.map(r => r.html).join('\n\n')}

</div>
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</td></tr>
</tbody>
</table>
<!--[if mso]></div><![endif]--><!--[if IE]></div><![endif]-->
</body></html>`
}

function compileJson (preheader, ariaLabel, rows) {
  return {
    counters: { ...counter },
    body: {
      id: 'u_body',
      rows: rows.map(r => r.json),
      values: {
        popupPosition: 'center', popupWidth: '600px', popupHeight: 'auto',
        borderRadius: '10px', contentAlign: 'center', contentVerticalAlign: 'center',
        contentWidth: '600px',
        fontFamily: { label: 'Plus Jakarta Sans', value: "'Plus Jakarta Sans', sans-serif",
                       url: 'https://fonts.googleapis.com/css?family=Plus+Jakarta+Sans:400,500,600,700' },
        textColor: '#1B2E24', popupBackgroundColor: '#FFFFFF', backgroundColor: '#F5FAF7',
        preheaderText: preheader,
        linkStyle: { body: true, linkColor: '#00C853', linkHoverColor: '#005026',
                      linkUnderline: true, linkHoverUnderline: true },
        _meta: { htmlID: 'u_body', htmlClassNames: 'u_body' },
      },
    },
    schemaVersion: 16,
  }
}

// ── Export the factories so template-spec files can use them ──────────────
module.exports = { textBlock, imageBlock, buttonBlock, htmlBlock, dividerBlock, row, compileHtml, compileJson }

// ── CLI ───────────────────────────────────────────────────────────────────
if (require.main === module) {
  const name = process.argv[2]
  if (!name) { console.error('Usage: build-native-template.js <template-name>'); process.exit(1) }
  const spec = require(path.resolve(__dirname, 'templates-spec', name))
  const tplDir = path.resolve(__dirname, '..', 'templates')
  const rows = spec.rows(module.exports)
  fs.writeFileSync(path.join(tplDir, name + '.html'), compileHtml(spec.preheader, spec.ariaLabel, rows), 'utf8')
  fs.writeFileSync(path.join(tplDir, name + '.json'), JSON.stringify(compileJson(spec.preheader, spec.ariaLabel, rows), null, 2), 'utf8')
  console.log(`✓ Built ${name}.html (${fs.statSync(path.join(tplDir, name + '.html')).size}b) + ${name}.json (${fs.statSync(path.join(tplDir, name + '.json')).size}b)`)
}
