(function () {
  const init = () => {
    const form = document.querySelector('[data-template-creator-v2]');
    if (!form) return;

    const editorBootstrap = window.__EMAIL_THEME_CREATOR_V2__ || {};
    const bodyField = document.getElementById('theme-body');
    const cssField = document.getElementById('theme-css');
    const smsBodyField = document.getElementById('sms-body');
    const previewField = document.getElementById('template-preview-text');
    const subjectField = document.getElementById('template-subject');
    const sectionsCanvas = document.getElementById('theme-canvas');
    const previewFrame = document.getElementById('theme-preview-frame');
    const presetSelect = document.getElementById('theme-preset-select');
    const presetHidden = document.getElementById('theme-preset-hidden');
    const themeJsonInput = document.getElementById('theme-json');
    const typeInputs = Array.from(form.querySelectorAll('input[name="type"]'));
    const emailPanel = form.querySelector('[data-template-type-panel="email"]');
    const smsPanel = form.querySelector('[data-template-type-panel="sms"]');
    const emailOnlyFields = Array.from(form.querySelectorAll('[data-email-only]'));
    const paletteButtons = Array.from(form.querySelectorAll('[data-theme-palette-item]'));
    const inspector = document.getElementById('theme-section-inspector');
    const copyButton = document.getElementById('theme-copy-html');
    const rebuildButton = document.getElementById('theme-rebuild-html');
    const clearCanvasButton = document.getElementById('theme-clear-canvas');
    const modeBadge = document.getElementById('theme-builder-status');

    if (!bodyField || !cssField || !sectionsCanvas || !previewFrame || !presetSelect || !themeJsonInput || !inspector) {
      return;
    }

    const settingsFields = {
      width: document.getElementById('theme-width'),
      fontFamily: document.getElementById('theme-font-family'),
      bodyBg: document.getElementById('theme-body-bg'),
      cardBg: document.getElementById('theme-card-bg'),
      textColor: document.getElementById('theme-text-color'),
      accentColor: document.getElementById('theme-accent-color'),
      buttonTextColor: document.getElementById('theme-button-text-color'),
      radius: document.getElementById('theme-radius')
    };

    const clone = (value) => JSON.parse(JSON.stringify(value));
    const uid = () => `sec_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
    const selectedType = () => (typeInputs.find((input) => input.checked) || { value: 'email' }).value;
    const escapeHtml = (value) => String(value ?? '').replace(/[&<>\"]/g, (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[char] || char));
    const escapeAttribute = (value) => escapeHtml(String(value ?? '')).replace(/'/g, '&#39;');
    const nl2br = (value) => escapeHtml(value).replace(/\n/g, '<br>');
    const toText = (value) => String(value ?? '').replace(/\s+/g, ' ').trim();
    const deepMerge = (base, override) => {
      const merged = clone(base);
      Object.keys(override || {}).forEach((key) => {
        const overrideValue = override[key];
        const baseValue = merged[key];
        if (Array.isArray(overrideValue)) {
          merged[key] = clone(overrideValue);
          return;
        }
        if (overrideValue && typeof overrideValue === 'object' && baseValue && typeof baseValue === 'object' && !Array.isArray(baseValue)) {
          merged[key] = deepMerge(baseValue, overrideValue);
          return;
        }
        merged[key] = overrideValue;
      });
      return merged;
    };

    const decorateSection = (section) => {
      const next = Object.assign({}, section || {});
      if (!next.id) next.id = uid();
      return next;
    };

    const sectionDefaults = {
      hero: () => ({ type: 'hero', eyebrow: 'Commercial campaign', heading: 'Launch something that looks premium', copy: 'Lead with a strong headline, supportive copy, and a focused CTA that clearly tells the reader what to do next.', buttonText: 'View details', buttonUrl: 'https://example.com', align: 'left' }),
      text: () => ({ type: 'text', heading: 'Explain the value clearly', copy: 'Use a supporting section for details, proof points, timelines, or any helpful context that should sit below the hero area.' }),
      image: () => ({ type: 'image', imageUrl: 'https://via.placeholder.com/640x280?text=Campaign+Image', altText: 'Campaign image', caption: 'Replace this with a branded product shot, banner, or event graphic.' }),
      columns: () => ({ type: 'columns', leftHeading: 'Left column', leftCopy: 'Highlight one key point, audience segment, or supporting detail here.', rightHeading: 'Right column', rightCopy: 'Use the second column for benefits, dates, pricing, or what happens next.' }),
      cta: () => ({ type: 'cta', heading: 'Ready for action?', copy: 'Place a high-contrast CTA block near the bottom when you want to reinforce the next step.', buttonText: 'Take action', buttonUrl: 'https://example.com' }),
      divider: () => ({ type: 'divider' }),
      footer: () => ({ type: 'footer', copy: 'Need help? Reply to this email or contact {{company}} for support. You can also unsubscribe using {{unsubscribe_url}}.' })
    };

    const presetCatalog = {
      newsletter: {
        theme_preset: 'newsletter',
        settings: { width: 640, fontFamily: 'Arial, Helvetica, sans-serif', bodyBg: '#eef2f7', cardBg: '#ffffff', textColor: '#1f2937', accentColor: '#1f5b92', buttonTextColor: '#ffffff', radius: 18 },
        sections: [sectionDefaults.hero(), sectionDefaults.text(), sectionDefaults.columns(), sectionDefaults.cta(), sectionDefaults.footer()]
      },
      announcement: {
        theme_preset: 'announcement',
        settings: { width: 640, fontFamily: "'Helvetica Neue', Arial, sans-serif", bodyBg: '#eff6ff', cardBg: '#ffffff', textColor: '#142235', accentColor: '#0f4c81', buttonTextColor: '#ffffff', radius: 20 },
        sections: [
          { type: 'hero', eyebrow: 'Announcement', heading: 'Major update for your clients', copy: 'Use a stronger hero panel and a clear explanation when you need to communicate a change, launch, or policy update.', buttonText: 'Review update', buttonUrl: 'https://example.com', align: 'left' },
          { type: 'text', heading: 'What changed', copy: 'Summarize what is new, why it matters, and what the recipient should expect next.' },
          sectionDefaults.footer()
        ]
      },
      promotion: {
        theme_preset: 'promotion',
        settings: { width: 640, fontFamily: 'Tahoma, Verdana, sans-serif', bodyBg: '#fff7ed', cardBg: '#ffffff', textColor: '#3a2615', accentColor: '#c46a13', buttonTextColor: '#ffffff', radius: 22 },
        sections: [
          { type: 'hero', eyebrow: 'Promotion', heading: 'Drive action with a clean offer panel', copy: 'Promotional themes work best when the offer is obvious, the terms are simple, and the CTA appears quickly.', buttonText: 'Claim offer', buttonUrl: 'https://example.com', align: 'center' },
          sectionDefaults.image(),
          sectionDefaults.cta(),
          sectionDefaults.footer()
        ]
      },
      event: {
        theme_preset: 'event',
        settings: { width: 620, fontFamily: "'Trebuchet MS', Arial, sans-serif", bodyBg: '#f5f3ff', cardBg: '#ffffff', textColor: '#231942', accentColor: '#6d28d9', buttonTextColor: '#ffffff', radius: 20 },
        sections: [
          { type: 'hero', eyebrow: 'Event invite', heading: 'Invite clients to your next event', copy: 'Use this structure for webinars, appointments, enrollment windows, and workshop invites.', buttonText: 'Reserve my seat', buttonUrl: 'https://example.com', align: 'center' },
          { type: 'columns', leftHeading: 'Date & time', leftCopy: 'Thursday • 11:00 AM CT\nHosted virtually', rightHeading: 'Who should join', rightCopy: 'Prospects, policyholders, partners, and renewal-ready accounts.' },
          sectionDefaults.cta(),
          sectionDefaults.footer()
        ]
      },
      retention: {
        theme_preset: 'retention',
        settings: { width: 640, fontFamily: "Georgia, 'Times New Roman', serif", bodyBg: '#f0fdf4', cardBg: '#ffffff', textColor: '#14321d', accentColor: '#0f766e', buttonTextColor: '#ffffff', radius: 18 },
        sections: [
          { type: 'hero', eyebrow: 'Retention', heading: 'Retention and renewal outreach', copy: 'This preset is designed for trust-building messages, proactive check-ins, and renewal reminders.', buttonText: 'Review options', buttonUrl: 'https://example.com', align: 'left' },
          sectionDefaults.text(),
          sectionDefaults.footer()
        ]
      },
      custom: {
        theme_preset: 'custom',
        settings: { width: 640, fontFamily: 'Arial, Helvetica, sans-serif', bodyBg: '#eef2f7', cardBg: '#ffffff', textColor: '#1f2937', accentColor: '#1f5b92', buttonTextColor: '#ffffff', radius: 18 },
        sections: [sectionDefaults.hero(), sectionDefaults.footer()]
      }
    };

    const defaultPreset = editorBootstrap.theme_preset && presetCatalog[editorBootstrap.theme_preset] ? editorBootstrap.theme_preset : 'newsletter';
    let parsedJson = null;
    try {
      parsedJson = editorBootstrap.theme_json ? JSON.parse(editorBootstrap.theme_json) : null;
    } catch (error) {
      parsedJson = null;
    }

    const presetSeed = clone(presetCatalog[defaultPreset]);
    const state = {
      theme_preset: defaultPreset,
      mode: 'builder',
      settings: clone(presetSeed.settings),
      sections: clone(presetSeed.sections).map(decorateSection),
      selectedId: null,
      dragPayload: null
    };

    if (parsedJson && typeof parsedJson === 'object') {
      state.theme_preset = presetCatalog[parsedJson.theme_preset] ? parsedJson.theme_preset : state.theme_preset;
      state.mode = parsedJson.mode === 'code' ? 'code' : 'builder';
      if (parsedJson.settings && typeof parsedJson.settings === 'object') {
        state.settings = deepMerge(clone(presetCatalog[state.theme_preset].settings), parsedJson.settings);
      }
      if (Array.isArray(parsedJson.sections) && parsedJson.sections.length) {
        state.sections = parsedJson.sections.map(decorateSection);
      }
    }

    if ((!parsedJson || !Array.isArray(parsedJson.sections) || !parsedJson.sections.length) && toText(editorBootstrap.theme_body_html || '') !== '') {
      state.mode = 'code';
    }
    if (!state.sections.length) {
      state.sections = clone(presetCatalog[state.theme_preset].sections).map(decorateSection);
    }
    state.selectedId = state.sections[0] ? state.sections[0].id : null;

    const getSelectedSection = () => state.sections.find((section) => section.id === state.selectedId) || null;
    const ensureSelectedSection = () => {
      if (!state.sections.length) {
        state.selectedId = null;
        return;
      }
      if (!state.selectedId || !getSelectedSection()) {
        state.selectedId = state.sections[0].id;
      }
    };

    const updateModeBadge = () => {
      if (!modeBadge) return;
      modeBadge.textContent = state.mode === 'builder' ? 'Builder synced' : 'Custom HTML mode';
      modeBadge.classList.toggle('color-blue', state.mode === 'builder');
      modeBadge.classList.toggle('color-violet', state.mode !== 'builder');
    };

    const syncThemeJson = () => {
      themeJsonInput.value = JSON.stringify({ version: '16.6', theme_preset: state.theme_preset, mode: state.mode, settings: state.settings, sections: state.sections });
      presetHidden.value = state.theme_preset;
      updateModeBadge();
    };

    const applySettingsToFields = () => {
      Object.keys(settingsFields).forEach((key) => {
        if (!settingsFields[key]) return;
        const value = state.settings[key];
        settingsFields[key].value = value != null ? value : '';
      });
      presetSelect.value = state.theme_preset;
    };

    const summaryForSection = (section) => {
      switch (section.type) {
        case 'hero': return toText(section.heading || section.copy || 'Hero section');
        case 'text': return toText(section.heading || section.copy || 'Text section');
        case 'image': return toText(section.caption || section.altText || section.imageUrl || 'Image section');
        case 'columns': return `${toText(section.leftHeading || 'Left column')} • ${toText(section.rightHeading || 'Right column')}`;
        case 'cta': return `${toText(section.heading || 'CTA block')} • ${toText(section.buttonText || 'Button')}`;
        case 'footer': return toText(section.copy || 'Footer section');
        default: return 'Spacing divider';
      }
    };

    const fieldMarkup = (label, key, value, type) => {
      if (type === 'textarea') {
        return `<label><span class="small muted">${label}</span><textarea data-field="${key}" rows="4">${escapeHtml(value)}</textarea></label>`;
      }
      if (type === 'select-align') {
        return `<label><span class="small muted">${label}</span><select data-field="${key}"><option value="left" ${value === 'left' ? 'selected' : ''}>Left</option><option value="center" ${value === 'center' ? 'selected' : ''}>Center</option></select></label>`;
      }
      return `<label><span class="small muted">${label}</span><input data-field="${key}" value="${escapeAttribute(value)}"></label>`;
    };

    const duplicateSection = (sectionId) => {
      const index = state.sections.findIndex((section) => section.id === sectionId);
      if (index < 0) return;
      const copy = decorateSection(clone(state.sections[index]));
      state.sections.splice(index + 1, 0, copy);
      state.selectedId = copy.id;
      applyBuilderChange();
    };

    const removeSection = (sectionId) => {
      const index = state.sections.findIndex((section) => section.id === sectionId);
      if (index < 0) return;
      state.sections.splice(index, 1);
      if (state.selectedId === sectionId) {
        state.selectedId = state.sections[index] ? state.sections[index].id : (state.sections[index - 1] ? state.sections[index - 1].id : null);
      }
      applyBuilderChange();
    };

    const duplicateSelectedSection = () => {
      const selected = getSelectedSection();
      if (selected) duplicateSection(selected.id);
    };

    const removeSelectedSection = () => {
      const selected = getSelectedSection();
      if (selected) removeSection(selected.id);
    };

    const renderInspector = () => {
      ensureSelectedSection();
      const section = getSelectedSection();
      if (!section) {
        inspector.innerHTML = '<div class="theme-v2-empty muted">Select a block to edit its content and settings.</div>';
        return;
      }
      let fields = '';
      switch (section.type) {
        case 'hero':
          fields = [fieldMarkup('Eyebrow', 'eyebrow', section.eyebrow || '', 'text'), fieldMarkup('Heading', 'heading', section.heading || '', 'text'), fieldMarkup('Body copy', 'copy', section.copy || '', 'textarea'), fieldMarkup('Button text', 'buttonText', section.buttonText || '', 'text'), fieldMarkup('Button URL', 'buttonUrl', section.buttonUrl || '', 'text'), fieldMarkup('Alignment', 'align', section.align || 'left', 'select-align')].join('');
          break;
        case 'text':
          fields = [fieldMarkup('Heading', 'heading', section.heading || '', 'text'), fieldMarkup('Body copy', 'copy', section.copy || '', 'textarea')].join('');
          break;
        case 'image':
          fields = [fieldMarkup('Image URL', 'imageUrl', section.imageUrl || '', 'text'), fieldMarkup('Alt text', 'altText', section.altText || '', 'text'), fieldMarkup('Caption', 'caption', section.caption || '', 'textarea')].join('');
          break;
        case 'columns':
          fields = [fieldMarkup('Left heading', 'leftHeading', section.leftHeading || '', 'text'), fieldMarkup('Left copy', 'leftCopy', section.leftCopy || '', 'textarea'), fieldMarkup('Right heading', 'rightHeading', section.rightHeading || '', 'text'), fieldMarkup('Right copy', 'rightCopy', section.rightCopy || '', 'textarea')].join('');
          break;
        case 'cta':
          fields = [fieldMarkup('Heading', 'heading', section.heading || '', 'text'), fieldMarkup('Body copy', 'copy', section.copy || '', 'textarea'), fieldMarkup('Button text', 'buttonText', section.buttonText || '', 'text'), fieldMarkup('Button URL', 'buttonUrl', section.buttonUrl || '', 'text')].join('');
          break;
        case 'footer':
          fields = fieldMarkup('Footer copy', 'copy', section.copy || '', 'textarea');
          break;
        default:
          fields = '<div class="small muted">Divider sections create spacing between content blocks.</div>';
      }

      inspector.innerHTML = `<div class="theme-v2-inspector-head"><div><strong>${escapeHtml(section.type.charAt(0).toUpperCase() + section.type.slice(1))} block</strong><div class="small muted">Edit content for the selected block.</div></div><div class="theme-v2-inline-actions"><button type="button" class="btn secondary small" data-inspector-action="duplicate">Duplicate</button><button type="button" class="btn danger small" data-inspector-action="remove">Remove</button></div></div><div class="theme-v2-inspector-fields">${fields}</div>`;
      inspector.querySelectorAll('[data-field]').forEach((field) => {
        const handler = () => {
          section[field.dataset.field] = field.value;
          applyBuilderChange();
        };
        field.addEventListener('input', handler);
        field.addEventListener('change', handler);
      });
      const duplicateButton = inspector.querySelector('[data-inspector-action="duplicate"]');
      const removeButton = inspector.querySelector('[data-inspector-action="remove"]');
      if (duplicateButton) duplicateButton.addEventListener('click', duplicateSelectedSection);
      if (removeButton) removeButton.addEventListener('click', removeSelectedSection);
    };

    const clearActiveDropSlots = () => {
      form.querySelectorAll('.theme-v2-drop-slot.is-active').forEach((slot) => slot.classList.remove('is-active'));
    };

    const handleDrop = (slotIndex) => {
      const payload = state.dragPayload;
      if (!payload) return;
      if (payload.source === 'palette') {
        const factory = sectionDefaults[payload.sectionType];
        if (!factory) return;
        const created = decorateSection(factory());
        state.sections.splice(slotIndex, 0, created);
        state.selectedId = created.id;
        applyBuilderChange();
        return;
      }
      if (payload.source === 'canvas') {
        const fromIndex = state.sections.findIndex((section) => section.id === payload.sectionId);
        if (fromIndex < 0) return;
        const moved = state.sections.splice(fromIndex, 1)[0];
        let targetIndex = slotIndex;
        if (fromIndex < slotIndex) targetIndex -= 1;
        state.sections.splice(targetIndex, 0, moved);
        state.selectedId = moved.id;
        applyBuilderChange();
      }
    };

    const createDropSlot = (index) => {
      const slot = document.createElement('button');
      slot.type = 'button';
      slot.className = 'theme-v2-drop-slot';
      slot.dataset.slotIndex = String(index);
      slot.innerHTML = '<span class="theme-v2-drop-line"></span><span class="theme-v2-drop-copy">Drop block here</span>';
      const activate = () => slot.classList.add('is-active');
      const deactivate = () => slot.classList.remove('is-active');
      slot.addEventListener('dragover', (event) => { event.preventDefault(); activate(); });
      slot.addEventListener('dragenter', (event) => { event.preventDefault(); activate(); });
      slot.addEventListener('dragleave', deactivate);
      slot.addEventListener('drop', (event) => { event.preventDefault(); deactivate(); handleDrop(index); });
      return slot;
    };

    const renderCanvas = () => {
      ensureSelectedSection();
      sectionsCanvas.innerHTML = '';
      sectionsCanvas.appendChild(createDropSlot(0));
      if (!state.sections.length) {
        const empty = document.createElement('div');
        empty.className = 'theme-v2-empty-canvas';
        empty.innerHTML = '<strong>Start building your template</strong><div class="small muted">Drag a block here from the left rail or click a block to add it to the canvas.</div>';
        sectionsCanvas.appendChild(empty);
        return;
      }
      state.sections.forEach((section, index) => {
        const card = document.createElement('article');
        card.className = `theme-v2-canvas-card${section.id === state.selectedId ? ' is-selected' : ''}`;
        card.draggable = true;
        card.dataset.sectionId = section.id;
        card.innerHTML = `<div class="theme-v2-card-head"><div class="theme-v2-card-title"><span class="theme-v2-drag-handle" aria-hidden="true">⋮⋮</span><div><strong>${escapeHtml(section.type.charAt(0).toUpperCase() + section.type.slice(1))}</strong><div class="small muted">${escapeHtml(summaryForSection(section))}</div></div></div><div class="theme-v2-inline-actions"><button type="button" class="btn secondary small" data-card-action="up">↑</button><button type="button" class="btn secondary small" data-card-action="down">↓</button><button type="button" class="btn secondary small" data-card-action="duplicate">Duplicate</button><button type="button" class="btn danger small" data-card-action="remove">Remove</button></div></div><div class="theme-v2-card-preview">${escapeHtml(summaryForSection(section))}</div>`;
        card.addEventListener('click', (event) => {
          if (event.target.closest('button')) return;
          state.selectedId = section.id;
          renderCanvas();
          renderInspector();
        });
        card.addEventListener('dragstart', () => {
          state.dragPayload = { source: 'canvas', sectionId: section.id };
          form.classList.add('theme-v2-dragging');
        });
        card.addEventListener('dragend', () => {
          state.dragPayload = null;
          form.classList.remove('theme-v2-dragging');
          clearActiveDropSlots();
        });
        const moveSection = (direction) => {
          const fromIndex = state.sections.findIndex((candidate) => candidate.id === section.id);
          if (fromIndex < 0) return;
          const toIndex = direction === 'up' ? fromIndex - 1 : fromIndex + 1;
          if (toIndex < 0 || toIndex >= state.sections.length) return;
          const moved = state.sections.splice(fromIndex, 1)[0];
          state.sections.splice(toIndex, 0, moved);
          state.selectedId = moved.id;
          applyBuilderChange();
        };
        card.querySelector('[data-card-action="up"]').addEventListener('click', (event) => { event.stopPropagation(); moveSection('up'); });
        card.querySelector('[data-card-action="down"]').addEventListener('click', (event) => { event.stopPropagation(); moveSection('down'); });
        card.querySelector('[data-card-action="duplicate"]').addEventListener('click', (event) => { event.stopPropagation(); duplicateSection(section.id); });
        card.querySelector('[data-card-action="remove"]').addEventListener('click', (event) => { event.stopPropagation(); removeSection(section.id); });
        sectionsCanvas.appendChild(card);
        sectionsCanvas.appendChild(createDropSlot(index + 1));
      });
    };

    const renderSectionHtml = (section) => {
      const settings = state.settings;
      const font = settings.fontFamily;
      const baseText = `font-family:${font};color:${settings.textColor};font-size:15px;line-height:1.7;`;
      const heading = `font-family:${font};color:${settings.textColor};margin:0 0 10px;font-weight:700;`;
      const radius = Number(settings.radius) || 18;
      const buttonMarkup = () => {
        if (!section.buttonText || !section.buttonUrl) return '';
        return `<div style="margin-top:18px;"><a href="${escapeAttribute(section.buttonUrl)}" style="display:inline-block;background:${settings.accentColor};color:${settings.buttonTextColor};text-decoration:none;font-weight:700;padding:12px 20px;border-radius:999px;">${escapeHtml(section.buttonText)}</a></div>`;
      };
      switch (section.type) {
        case 'hero': {
          const align = section.align === 'center' ? 'center' : 'left';
          return `<tr><td style="padding:0;"><table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td style="padding:36px 32px;background:${settings.accentColor};border-radius:${radius}px ${radius}px 0 0;text-align:${align};color:${settings.buttonTextColor};"><div style="font-family:${font};font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;opacity:.9;margin-bottom:12px;">${escapeHtml(section.eyebrow || '')}</div><h1 style="font-family:${font};margin:0 0 14px;font-size:30px;line-height:1.2;color:${settings.buttonTextColor};">${escapeHtml(section.heading || '')}</h1><div style="font-family:${font};font-size:16px;line-height:1.7;color:${settings.buttonTextColor};opacity:.96;">${nl2br(section.copy || '')}</div>${section.buttonText && section.buttonUrl ? `<div style="margin-top:20px;"><a href="${escapeAttribute(section.buttonUrl)}" style="display:inline-block;background:${settings.cardBg};color:${settings.accentColor};text-decoration:none;font-weight:700;padding:12px 20px;border-radius:999px;">${escapeHtml(section.buttonText)}</a></div>` : ''}</td></tr></table></td></tr>`;
        }
        case 'text': return `<tr><td style="padding:28px 32px 12px;"><h2 style="${heading}font-size:22px;">${escapeHtml(section.heading || '')}</h2><div style="${baseText}">${nl2br(section.copy || '')}</div></td></tr>`;
        case 'image': return `<tr><td style="padding:10px 32px 18px;"><img src="${escapeAttribute(section.imageUrl || '')}" alt="${escapeAttribute(section.altText || '')}" style="display:block;width:100%;max-width:100%;border-radius:${Math.max(10, radius - 4)}px;border:0;">${section.caption ? `<div style="${baseText}font-size:13px;color:#5b6675;margin-top:10px;">${nl2br(section.caption)}</div>` : ''}</td></tr>`;
        case 'columns': return `<tr><td style="padding:12px 32px 18px;"><table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td width="50%" valign="top" style="padding:16px 16px 16px 0;border-top:1px solid #e4ebf2;"><h3 style="${heading}font-size:18px;">${escapeHtml(section.leftHeading || '')}</h3><div style="${baseText}">${nl2br(section.leftCopy || '')}</div></td><td width="50%" valign="top" style="padding:16px 0 16px 16px;border-top:1px solid #e4ebf2;"><h3 style="${heading}font-size:18px;">${escapeHtml(section.rightHeading || '')}</h3><div style="${baseText}">${nl2br(section.rightCopy || '')}</div></td></tr></table></td></tr>`;
        case 'cta': return `<tr><td style="padding:8px 32px 26px;"><table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td style="padding:24px;border-radius:${Math.max(12, radius - 2)}px;background:${settings.bodyBg};"><h3 style="${heading}font-size:20px;">${escapeHtml(section.heading || '')}</h3><div style="${baseText}">${nl2br(section.copy || '')}</div>${buttonMarkup()}</td></tr></table></td></tr>`;
        case 'footer': return `<tr><td style="padding:18px 32px 28px;border-top:1px solid #e4ebf2;"><div style="${baseText}font-size:13px;color:#64748b;">${nl2br(section.copy || '')}</div></td></tr>`;
        default: return '<tr><td style="padding:8px 32px;"><div style="height:1px;background:#e4ebf2;"></div></td></tr>';
      }
    };

    const buildGeneratedHtml = () => {
      const width = Math.max(480, Math.min(760, Number(state.settings.width) || 640));
      const rows = state.sections.map(renderSectionHtml).join('') || '<tr><td style="padding:24px 32px;font-family:Arial, sans-serif;color:#1f2937;">Add sections to build your layout.</td></tr>';
      return `<div style="margin:0;padding:0;background:${state.settings.bodyBg};"><table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="width:100%;background:${state.settings.bodyBg};"><tr><td align="center" style="padding:32px 12px;"><table role="presentation" width="${width}" cellspacing="0" cellpadding="0" style="width:100%;max-width:${width}px;background:${state.settings.cardBg};border-radius:${Number(state.settings.radius) || 18}px;overflow:hidden;margin:0 auto;">${rows}</table></td></tr></table></div>`;
    };

    const buildCombinedHtml = () => {
      const previewText = previewField ? previewField.value.trim() : '';
      const css = cssField.value.trim();
      const body = bodyField.value.trim();
      let combined = '';
      if (previewText) combined += `<div style="display:none;max-height:0;overflow:hidden;opacity:0;color:transparent;visibility:hidden;mso-hide:all;">${escapeHtml(previewText)}</div>`;
      if (css) combined += `<style>${css}</style>`;
      combined += body;
      return combined;
    };

    const renderPreview = () => {
      if (selectedType() !== 'email') {
        previewFrame.srcdoc = '<html><body style="font-family:Arial,sans-serif;padding:24px;color:#475569;">SMS/MMS templates do not use the email theme preview.</body></html>';
        return;
      }
      previewFrame.srcdoc = `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head><body style="margin:0;padding:0;background:#e5edf6;">${buildCombinedHtml()}</body></html>`;
    };

    function applyBuilderChange() {
      state.mode = 'builder';
      ensureSelectedSection();
      bodyField.value = buildGeneratedHtml();
      syncThemeJson();
      renderCanvas();
      renderInspector();
      renderPreview();
    }

    const addSection = (sectionType, index) => {
      const factory = sectionDefaults[sectionType];
      if (!factory) return;
      const created = decorateSection(factory());
      const insertAt = Number.isInteger(index) ? index : (() => {
        const selectedIndex = state.sections.findIndex((section) => section.id === state.selectedId);
        return selectedIndex >= 0 ? selectedIndex + 1 : state.sections.length;
      })();
      state.sections.splice(insertAt, 0, created);
      state.selectedId = created.id;
      applyBuilderChange();
    };

    const applyPreset = (presetKey) => {
      const preset = clone(presetCatalog[presetKey] || presetCatalog.newsletter);
      state.theme_preset = preset.theme_preset || presetKey;
      state.settings = clone(preset.settings);
      state.sections = clone(preset.sections).map(decorateSection);
      state.selectedId = state.sections[0] ? state.sections[0].id : null;
      applySettingsToFields();
      applyBuilderChange();
    };

    const updateModeVisibility = () => {
      const emailMode = selectedType() === 'email';
      if (emailPanel) emailPanel.hidden = !emailMode;
      if (smsPanel) smsPanel.hidden = emailMode;
      emailOnlyFields.forEach((field) => { field.hidden = !emailMode; });
      renderPreview();
    };

    paletteButtons.forEach((button) => {
      button.addEventListener('click', () => addSection(button.dataset.section));
      button.addEventListener('dragstart', () => {
        state.dragPayload = { source: 'palette', sectionType: button.dataset.section };
        form.classList.add('theme-v2-dragging');
      });
      button.addEventListener('dragend', () => {
        state.dragPayload = null;
        form.classList.remove('theme-v2-dragging');
        clearActiveDropSlots();
      });
    });
    typeInputs.forEach((input) => input.addEventListener('change', updateModeVisibility));
    presetSelect.addEventListener('change', () => applyPreset(presetSelect.value));
    Object.keys(settingsFields).forEach((key) => {
      const input = settingsFields[key];
      if (!input) return;
      const handler = () => {
        state.settings[key] = key === 'width' || key === 'radius' ? Number(input.value || 0) : input.value;
        applyBuilderChange();
      };
      input.addEventListener('input', handler);
      input.addEventListener('change', handler);
    });
    bodyField.addEventListener('input', () => {
      state.mode = 'code';
      syncThemeJson();
      renderPreview();
    });
    cssField.addEventListener('input', () => {
      syncThemeJson();
      renderPreview();
    });
    if (previewField) previewField.addEventListener('input', renderPreview);
    if (subjectField) subjectField.addEventListener('input', syncThemeJson);
    if (copyButton) {
      copyButton.addEventListener('click', async () => {
        try {
          await navigator.clipboard.writeText(buildCombinedHtml());
          copyButton.textContent = 'Copied';
          window.setTimeout(() => { copyButton.textContent = 'Copy HTML'; }, 1200);
        } catch (error) {
          copyButton.textContent = 'Copy failed';
          window.setTimeout(() => { copyButton.textContent = 'Copy HTML'; }, 1200);
        }
      });
    }
    if (rebuildButton) {
      rebuildButton.addEventListener('click', () => {
        state.mode = 'builder';
        bodyField.value = buildGeneratedHtml();
        syncThemeJson();
        renderPreview();
      });
    }
    if (clearCanvasButton) {
      clearCanvasButton.addEventListener('click', () => {
        state.sections = [];
        state.selectedId = null;
        applyBuilderChange();
      });
    }
    form.addEventListener('submit', () => {
      if (selectedType() === 'email') {
        syncThemeJson();
      } else {
        themeJsonInput.value = '';
        presetHidden.value = '';
      }
    });
    if (editorBootstrap.theme_body_html && bodyField.value.trim() === '') bodyField.value = editorBootstrap.theme_body_html;
    if (editorBootstrap.theme_css && cssField.value.trim() === '') cssField.value = editorBootstrap.theme_css;
    if (previewField && editorBootstrap.preview_text && previewField.value.trim() === '') previewField.value = editorBootstrap.preview_text;
    if (smsBodyField && editorBootstrap.sms_body_text && smsBodyField.value.trim() === '') smsBodyField.value = editorBootstrap.sms_body_text;

    applySettingsToFields();
    syncThemeJson();
    renderCanvas();
    renderInspector();
    if (state.mode === 'builder' && bodyField.value.trim() === '') bodyField.value = buildGeneratedHtml();
    updateModeVisibility();
    renderPreview();
  };

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
