document.querySelectorAll('form').forEach((form) => {
  form.addEventListener('submit', () => {
    const btn = form.querySelector('button[type="submit"],button:not([type])');
    if (btn) {
      btn.disabled = true;
      btn.dataset.originalText = btn.textContent;
      btn.textContent = 'Processing...';
    }
  });
});

(function () {
  document.querySelectorAll('.template-picker').forEach((sel) => {
    sel.addEventListener('change', function () {
      const opt = this.options[this.selectedIndex];
      const bodyTarget = this.dataset.targetBody ? document.getElementById(this.dataset.targetBody) : null;
      const subjectTarget = this.dataset.targetSubject ? document.getElementById(this.dataset.targetSubject) : null;
      if (bodyTarget && opt && opt.dataset.body) bodyTarget.value = opt.dataset.body;
      if (subjectTarget && opt && opt.dataset.subject) subjectTarget.value = opt.dataset.subject;
    });
  });
})();

(function () {
  const templates = window.__TEMPLATES__ || [];
  const context = window.__CAMPAIGN_CONTEXT__ || {};
  const select = document.getElementById('campaign-template');
  const channel = document.getElementById('campaign-channel');
  const subjectInput = document.getElementById('campaign-subject');
  const bodyInput = document.getElementById('campaign-body');
  const preview = document.getElementById('campaign-preview');
  const canvas = document.getElementById('builder-canvas');
  const builderJsonInput = document.getElementById('campaign-builder-json');
  const preflightSummary = document.getElementById('campaign-preflight-summary');
  const preflightList = document.getElementById('campaign-preflight-list');
  const listSelect = document.getElementById('campaign-contact-list');
  const segmentSelect = document.querySelector('[name="segment_id"]');
  const filterInput = document.querySelector('[name="recipient_filter"]');
  if (!select || !channel || !preview || !canvas || !builderJsonInput) return;

  const sample = {
    first_name: 'Avery',
    last_name: 'Jordan',
    company: 'Northwind Health',
    email: 'avery@example.com',
    phone: '+15555551212',
    unsubscribe_url: 'https://example.com/unsubscribe'
  };

  const defaults = {
    hero: '<table role="presentation" width="100%"><tr><td style="padding:28px;border-radius:16px;background:#12395b;color:#ffffff;"><div style="font-size:28px;font-weight:700;margin-bottom:8px;">Commercial campaign launch</div><div style="font-size:15px;line-height:1.6;">Hi {{first_name}}, here is the latest update for {{company}}.</div></td></tr></table>',
    heading: '<h2>{{first_name}}, important update</h2>',
    text: '<p>We have a new message for {{company}}. Use this section for body copy, offer details, and next steps.</p>',
    image: '<p><img src="https://via.placeholder.com/640x240" alt="Campaign visual" style="max-width:100%;border-radius:14px;"></p>',
    cta: '<p><a href="https://example.com" style="display:inline-block;padding:12px 18px;border-radius:999px;background:#1f5b92;color:#ffffff;text-decoration:none;">Review details</a></p>',
    divider: '<hr style="border:none;border-top:1px solid #d8e1ec;margin:24px 0;">',
    spacer: '<div style="height:24px;"></div>'
  };

  let blocks = [];
  let draggedIndex = null;

  const pickedTemplate = () => templates.find((t) => Number(t.id) === Number(select.value || 0));

  const interpolate = (text) => String(text || '')
    .replaceAll('{{first_name}}', sample.first_name)
    .replaceAll('{{last_name}}', sample.last_name)
    .replaceAll('{{company}}', sample.company)
    .replaceAll('{{email}}', sample.email)
    .replaceAll('{{phone}}', sample.phone)
    .replaceAll('{{unsubscribe_url}}', sample.unsubscribe_url);

  const bodyFromBlocks = () => blocks.map((block) => block.html || '').filter(Boolean).join('\n\n');

  const summaryAudience = () => {
    const listText = listSelect && listSelect.value ? listSelect.options[listSelect.selectedIndex].text : '';
    if (listText) return listText;
    if (segmentSelect && segmentSelect.value) return 'Saved segment';
    if (filterInput && filterInput.value.trim()) return `Tag filter: ${filterInput.value.trim()}`;
    return `All reachable ${channel.value.toUpperCase()} contacts`;
  };

  const variantCount = () => {
    const hasA = !!(document.querySelector('[name="variant_a_subject"]')?.value.trim() || document.querySelector('[name="variant_a_body"]')?.value.trim());
    const hasB = !!(document.querySelector('[name="variant_b_subject"]')?.value.trim() || document.querySelector('[name="variant_b_body"]')?.value.trim());
    return 1 + (hasA ? 1 : 0) + (hasB ? 1 : 0);
  };

  const syncBuilder = () => {
    builderJsonInput.value = JSON.stringify(blocks);
    if (blocks.length) {
      bodyInput.value = bodyFromBlocks();
    }
    renderPreview();
    renderPreflight();
  };

  const renderBlocks = () => {
    canvas.innerHTML = '';
    if (!blocks.length) {
      canvas.innerHTML = '<div class="builder-empty muted">Drop builder blocks here or start from a template.</div>';
      return;
    }
    blocks.forEach((block, index) => {
      const card = document.createElement('div');
      card.className = 'builder-block';
      card.draggable = true;
      card.dataset.index = String(index);
      card.innerHTML = `
        <div class="builder-block-head">
          <div class="builder-block-title"><span class="drag-handle">↕</span> <strong>${String(block.type || 'text').toUpperCase()}</strong></div>
          <button type="button" class="btn danger small">Remove</button>
        </div>
        <textarea rows="5">${block.html || ''}</textarea>
      `;
      const textarea = card.querySelector('textarea');
      textarea.addEventListener('input', () => {
        blocks[index].html = textarea.value;
        syncBuilder();
      });
      card.querySelector('button').addEventListener('click', () => {
        blocks.splice(index, 1);
        renderBlocks();
        syncBuilder();
      });
      card.addEventListener('dragstart', () => {
        draggedIndex = index;
        card.classList.add('dragging');
      });
      card.addEventListener('dragend', () => {
        draggedIndex = null;
        card.classList.remove('dragging');
      });
      card.addEventListener('dragover', (event) => {
        event.preventDefault();
        card.classList.add('drag-over');
      });
      card.addEventListener('dragleave', () => card.classList.remove('drag-over'));
      card.addEventListener('drop', (event) => {
        event.preventDefault();
        card.classList.remove('drag-over');
        if (draggedIndex === null || draggedIndex === index) return;
        const moved = blocks.splice(draggedIndex, 1)[0];
        blocks.splice(index, 0, moved);
        renderBlocks();
        syncBuilder();
      });
      canvas.appendChild(card);
    });
  };

  const addBlock = (type) => {
    blocks.push({ type, html: defaults[type] || defaults.text });
    renderBlocks();
    syncBuilder();
  };

  const renderPreview = () => {
    const picked = pickedTemplate();
    const rawBody = blocks.length ? bodyFromBlocks() : (bodyInput.value.trim() || picked?.body || 'Choose a template or add builder blocks to preview the campaign body here.');
    const rawSubject = subjectInput.value.trim() || picked?.subject || '';
    preview.innerHTML = '';
    const meta = document.createElement('div');
    meta.className = 'small muted';
    if (picked) {
      meta.textContent = picked.type === channel.value
        ? `Matched ${picked.type.toUpperCase()} template`
        : `Template type mismatch: ${picked.type.toUpperCase()} selected`;
    } else {
      meta.textContent = blocks.length ? 'Builder content preview' : 'No template selected';
    }
    preview.appendChild(meta);
    if (channel.value === 'email' && rawSubject) {
      const s = document.createElement('div');
      s.className = 'preview-subject';
      s.textContent = 'Subject: ' + interpolate(rawSubject);
      preview.appendChild(s);
    }
    const body = document.createElement('div');
    body.className = 'preview-inner';
    body.innerHTML = interpolate(rawBody);
    preview.appendChild(body);
  };

  const renderPreflight = () => {
    if (!preflightList || !preflightSummary) return;
    const picked = pickedTemplate();
    const body = blocks.length ? bodyFromBlocks() : (bodyInput.value.trim() || picked?.body || '');
    const subject = subjectInput.value.trim() || picked?.subject || '';
    const providerStatus = context.providerStatus || {};
    const listChannel = listSelect && listSelect.value ? listSelect.options[listSelect.selectedIndex].dataset.channel || 'both' : 'both';
    const checks = [];

    const pushCheck = (status, label, detail) => checks.push({ status, label, detail });

    if (channel.value === 'email') {
      pushCheck(providerStatus.smtp?.configured ? 'pass' : 'error', 'Provider readiness', providerStatus.smtp?.configured ? 'SMTP ready' : 'SMTP missing');
      pushCheck(subject ? 'pass' : 'error', 'Subject line', subject ? 'Subject ready' : 'Missing subject');
    } else {
      pushCheck(providerStatus.twilio?.configured ? 'pass' : 'error', 'Provider readiness', providerStatus.twilio?.configured ? 'Twilio ready' : 'Twilio missing');
      pushCheck('pass', 'Subject line', 'Not required for SMS');
    }

    pushCheck(body.replace(/<[^>]*>/g, '').trim() ? 'pass' : 'error', 'Content', blocks.length ? `${blocks.length} builder blocks ready` : (body ? 'Raw editor content ready' : 'No content detected'));

    if (picked) {
      pushCheck(picked.type === channel.value ? 'pass' : 'warn', 'Template match', picked.type === channel.value ? 'Template matches channel' : `${picked.type.toUpperCase()} template selected on ${channel.value.toUpperCase()} campaign`);
    }

    if (listSelect && listSelect.value) {
      pushCheck(listChannel === 'both' || listChannel === channel.value ? 'pass' : 'error', 'Audience source', listSelect.options[listSelect.selectedIndex].text);
    } else {
      pushCheck('pass', 'Audience source', summaryAudience());
    }

    if (channel.value === 'email') {
      const hasUnsubscribe = body.includes('{{unsubscribe_url}}') || /unsubscribe/i.test(body);
      pushCheck(hasUnsubscribe ? 'pass' : 'warn', 'Unsubscribe footer', hasUnsubscribe ? 'Detected' : 'Add unsubscribe language or token');
    }

    if (Number(context.systemHealth?.bounceRate || 0) >= 3) {
      pushCheck('warn', 'Recent bounce rate', `${Number(context.systemHealth.bounceRate).toFixed(1)}% system bounce rate`);
    }
    if (Number(context.systemHealth?.queuePressure || 0) >= 20) {
      pushCheck('warn', 'Queue pressure', `${Number(context.systemHealth.queuePressure).toFixed(1)}% queued backlog`);
    }

    preflightSummary.textContent = `${summaryAudience()} · ${blocks.length} builder blocks · ${variantCount()} variants`;
    preflightList.innerHTML = '';
    checks.forEach((check) => {
      const row = document.createElement('div');
      row.className = `preflight-row status-${check.status}`;
      row.innerHTML = `<strong>${check.label}</strong><span>${check.detail}</span>`;
      preflightList.appendChild(row);
    });
  };

  document.querySelectorAll('.builder-add').forEach((button) => {
    button.addEventListener('click', () => addBlock(button.dataset.block || 'text'));
  });

  [select, channel, subjectInput, bodyInput, listSelect, segmentSelect, filterInput].filter(Boolean).forEach((el) => {
    el.addEventListener('input', () => {
      renderPreview();
      renderPreflight();
    });
    el.addEventListener('change', () => {
      const picked = pickedTemplate();
      if (picked && subjectInput && !subjectInput.value.trim() && picked.subject && channel.value === 'email') {
        subjectInput.value = picked.subject;
      }
      if (picked && !blocks.length && bodyInput && !bodyInput.value.trim() && picked.body) {
        bodyInput.value = picked.body;
      }
      renderPreview();
      renderPreflight();
    });
  });

  document.querySelectorAll('[name="variant_a_subject"],[name="variant_a_body"],[name="variant_b_subject"],[name="variant_b_body"],[name="ab_enabled"]').forEach((el) => {
    el.addEventListener('input', renderPreflight);
    el.addEventListener('change', renderPreflight);
  });

  renderBlocks();
  renderPreview();
  renderPreflight();
})();

(function () {
  document.querySelectorAll('.mini-chart').forEach((node) => {
    let series = [];
    try {
      series = JSON.parse(node.dataset.series || '[]');
    } catch (e) {
      series = [];
    }
    if (!Array.isArray(series) || !series.length) {
      node.innerHTML = '<div class="muted">No recent data.</div>';
      return;
    }
    const keys = (node.dataset.keys || 'delivered_count,unique_open_count,unique_click_count,bounced_count')
      .split(',')
      .map((key) => key.trim())
      .filter(Boolean);
    const names = (node.dataset.names || '')
      .split('|')
      .map((name) => name.trim())
      .filter(Boolean);
    const labelKey = node.dataset.labelKey || 'day';
    const max = Math.max(1, ...series.map((item) => Math.max(...keys.map((key) => Number(item[key] || 0)))));
    const wrap = document.createElement('div');
    wrap.className = 'chart-bars';

    const formatLabel = (value) => {
      const text = String(value || '');
      if (/^\d{4}-\d{2}-\d{2}/.test(text)) return text.slice(5);
      return text.length > 12 ? `${text.slice(0, 10)}…` : text;
    };

    series.forEach((item) => {
      const group = document.createElement('div');
      group.className = `chart-group chart-group-${Math.max(1, keys.length)}`;
      keys.forEach((key) => {
        const bar = document.createElement('div');
        bar.className = `bar ${key}`;
        bar.style.height = `${Math.max(8, (Number(item[key] || 0) / max) * 120)}px`;
        bar.title = `${key}: ${item[key] || 0}`;
        group.appendChild(bar);
      });
      const label = document.createElement('div');
      label.className = 'chart-label';
      label.textContent = formatLabel(item[labelKey]);
      group.appendChild(label);
      wrap.appendChild(group);
    });

    const legend = document.createElement('div');
    legend.className = 'chart-legend';
    legend.innerHTML = keys.map((key, index) => `<span><i class="legend-chip ${key}"></i>${names[index] || key.replaceAll('_', ' ')}</span>`).join('');
    node.innerHTML = '';
    node.appendChild(wrap);
    node.appendChild(legend);
  });
})();


(function () {
  document.querySelectorAll('.js-page-slider').forEach((slider) => {
    const root = slider.closest('.page-slider');
    const valueNode = root ? root.querySelector('[data-slider-value]') : null;

    const update = () => {
      if (valueNode) valueNode.textContent = slider.value;
    };

    slider.addEventListener('input', update);
    slider.addEventListener('change', () => {
      const base = slider.dataset.pageBase || '';
      if (!base) return;
      window.location.href = `${base}${slider.value}`;
    });

    update();
  });
})();

(function () {
  document.querySelectorAll('.js-page-slider').forEach((slider) => {
    const root = slider.closest('.page-slider');
    const valueNode = root ? root.querySelector('[data-slider-value]') : null;
    const pageTemplate = slider.dataset.pageTemplate || '';
    const pageBase = slider.dataset.pageBase || '';

    const update = () => {
      if (valueNode) valueNode.textContent = slider.value;
    };

    slider.addEventListener('input', update);
    slider.addEventListener('change', () => {
      if (pageTemplate) {
        window.location.href = pageTemplate.replace('__PAGE__', slider.value);
        return;
      }
      if (pageBase) {
        window.location.href = `${pageBase}${slider.value}`;
      }
    });

    update();
  });
})();

(function () {
  const drawer = document.getElementById('mail-compose-drawer');
  if (!drawer) return;
  const open = () => {
    drawer.classList.add('is-open');
    drawer.setAttribute('aria-hidden', 'false');
  };
  const close = () => {
    drawer.classList.remove('is-open');
    drawer.setAttribute('aria-hidden', 'true');
  };
  document.querySelectorAll('[data-compose-toggle="true"]').forEach((button) => button.addEventListener('click', open));
  document.querySelectorAll('[data-compose-close="true"]').forEach((button) => button.addEventListener('click', close));
  drawer.addEventListener('click', (event) => {
    if (event.target === drawer) close();
  });
})();

(function () {
  document.querySelectorAll('.js-apply-reply').forEach((button) => {
    button.addEventListener('click', () => {
      const bodyTarget = document.getElementById(button.dataset.target || '');
      const subjectTarget = document.getElementById(button.dataset.subjectTarget || '');
      if (subjectTarget && button.dataset.subject) {
        subjectTarget.value = button.dataset.subject;
        subjectTarget.dispatchEvent(new Event('input', { bubbles: true }));
      }
      if (bodyTarget) {
        bodyTarget.value = button.dataset.body || '';
        bodyTarget.dispatchEvent(new Event('input', { bubbles: true }));
      }
    });
  });
})();

(function () {
  document.querySelectorAll('.mail-autosave-form').forEach((form) => {
    const autosaveUrl = form.dataset.autosaveUrl || '';
    if (!autosaveUrl) return;
    const statusNode = form.querySelector('.mail-draft-status');
    let timer = null;
    let lastSnapshot = '';

    const setState = (state, message) => {
      form.classList.remove('is-saving', 'is-saved', 'is-error');
      if (state) form.classList.add(state);
      if (statusNode && message) statusNode.textContent = message;
    };

    const buildSnapshot = () => JSON.stringify({
      contact_id: form.querySelector('[name="contact_id"]')?.value || '',
      to_address: form.querySelector('[name="to_address"]')?.value || '',
      subject: form.querySelector('[name="subject"]')?.value || '',
      body: form.querySelector('[name="body"]')?.value || '',
      conversation_key: form.querySelector('[name="conversation_key"]')?.value || '',
      draft_type: form.querySelector('[name="draft_type"]')?.value || 'compose'
    });

    const autosave = async () => {
      const snapshot = buildSnapshot();
      if (!snapshot || snapshot === lastSnapshot) return;
      const bodyField = form.querySelector('[name="body"]');
      const subjectField = form.querySelector('[name="subject"]');
      if (!bodyField && !subjectField) return;
      setState('is-saving', 'Saving draft...');
      const payload = new FormData();
      payload.append('_csrf', form.querySelector('[name="_csrf"]')?.value || '');
      payload.append('draft_type', form.querySelector('[name="draft_type"]')?.value || 'compose');
      payload.append('conversation_key', form.querySelector('[name="conversation_key"]')?.value || '');
      payload.append('contact_id', form.querySelector('[name="contact_id"]')?.value || '');
      payload.append('to_address', form.querySelector('[name="to_address"]')?.value || '');
      payload.append('subject', form.querySelector('[name="subject"]')?.value || '');
      payload.append('body', form.querySelector('[name="body"]')?.value || '');
      try {
        const response = await fetch(autosaveUrl, {
          method: 'POST',
          body: payload,
          credentials: 'same-origin',
          headers: { 'X-Requested-With': 'XMLHttpRequest' }
        });
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const data = await response.json();
        if (data?.draft_id) {
          let hidden = form.querySelector('[name="draft_id"]');
          if (!hidden) {
            hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.name = 'draft_id';
            form.appendChild(hidden);
          }
          hidden.value = data.draft_id;
        }
        lastSnapshot = snapshot;
        setState('is-saved', data?.saved_at ? `Draft saved at ${data.saved_at}` : 'Draft saved.');
      } catch (error) {
        setState('is-error', 'Draft autosave failed.');
      }
    };

    form.querySelectorAll('input[type="text"],input[type="email"],input[type="search"],input:not([type]),textarea,select').forEach((field) => {
      field.addEventListener('input', () => {
        clearTimeout(timer);
        timer = setTimeout(autosave, 900);
      });
      field.addEventListener('change', () => {
        clearTimeout(timer);
        timer = setTimeout(autosave, 200);
      });
    });
  });
})();

(function () {
  const shell = document.getElementById('mail-outlook-shell');
  if (!shell) return;

  const safeStorage = {
    get(key) {
      try {
        return window.localStorage.getItem(key);
      } catch (error) {
        return null;
      }
    },
    set(key, value) {
      try {
        window.localStorage.setItem(key, value);
      } catch (error) {
        // ignore storage failures
      }
    }
  };

  const densityButtons = Array.from(shell.querySelectorAll('[data-mail-density]'));
  const layoutButtons = Array.from(shell.querySelectorAll('[data-mail-layout]'));
  const applyMode = (kind, value) => {
    if (!value) return;
    if (kind === 'density') {
      shell.dataset.mailDensity = value;
      safeStorage.set('aio.mailCenterDensity', value);
      densityButtons.forEach((button) => button.classList.toggle('is-active', button.dataset.mailDensity === value));
    }
    if (kind === 'layout') {
      shell.dataset.mailLayout = value;
      safeStorage.set('aio.mailCenterLayout', value);
      layoutButtons.forEach((button) => button.classList.toggle('is-active', button.dataset.mailLayout === value));
    }
  };

  densityButtons.forEach((button) => {
    button.addEventListener('click', () => applyMode('density', button.dataset.mailDensity));
  });
  layoutButtons.forEach((button) => {
    button.addEventListener('click', () => applyMode('layout', button.dataset.mailLayout));
  });

  applyMode('density', safeStorage.get('aio.mailCenterDensity') || shell.dataset.mailDensity || 'roomy');
  applyMode('layout', safeStorage.get('aio.mailCenterLayout') || shell.dataset.mailLayout || 'right');
})();

(function () {
  const tabs = Array.from(document.querySelectorAll('[data-mail-insight-tab]'));
  const panels = Array.from(document.querySelectorAll('[data-mail-insight-panel]'));
  if (!tabs.length || !panels.length) return;

  const activate = (name) => {
    tabs.forEach((tab) => tab.classList.toggle('is-active', tab.dataset.mailInsightTab === name));
    panels.forEach((panel) => panel.classList.toggle('is-active', panel.dataset.mailInsightPanel === name));
  };

  tabs.forEach((tab) => {
    tab.addEventListener('click', () => activate(tab.dataset.mailInsightTab));
  });

  activate(tabs[0].dataset.mailInsightTab);
})();

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

  const editorBootstrap = window.__EMAIL_THEME_EDITOR__ || {};
  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 sectionsContainer = document.getElementById('theme-sections');
  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 addSectionButtons = Array.from(form.querySelectorAll('.js-add-theme-section'));
  const copyButton = document.getElementById('theme-copy-html');

  if (!bodyField || !cssField || !sectionsContainer || !previewFrame || !presetSelect || !themeJsonInput) return;

  const clone = (value) => JSON.parse(JSON.stringify(value));
  const deepMerge = (base, override) => {
    const merged = clone(base);
    Object.keys(override || {}).forEach((key) => {
      const baseValue = merged[key];
      const overrideValue = override[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 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 selectedType = () => (typeInputs.find((input) => input.checked) || { value: 'email' }).value;

  const sectionDefaults = {
    hero: () => ({ type: 'hero', heading: 'Launch something that looks premium', copy: 'Use the Email Theme Creator to build branded, reusable layouts with strong hierarchy and clean calls to action.', buttonText: 'View details', buttonUrl: 'https://example.com', eyebrow: 'Commercial campaign', align: 'left' }),
    text: () => ({ type: 'text', heading: 'Why this theme works', copy: 'Pair a strong subject line with a clear headline, concise supporting copy, and a single focused CTA for stronger campaign performance.' }),
    image: () => ({ type: 'image', imageUrl: 'https://via.placeholder.com/640x280?text=Theme+Preview', altText: 'Theme preview image', caption: 'Swap in a brand image, banner, or campaign visual.' }),
    columns: () => ({ type: 'columns', leftHeading: 'Segment fit', leftCopy: 'Explain who should receive this message and why it matters.', rightHeading: 'Offer details', rightCopy: 'Summarize the value, pricing, timeline, or response CTA.' }),
    cta: () => ({ type: 'cta', heading: 'Ready to launch?', copy: 'Use this CTA section for confirmations, proposal approvals, webinar RSVPs, or renewal nudges.', buttonText: 'Schedule launch', 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', heading: 'Major update for your clients', copy: 'Use an announcement layout when you need a stronger opening panel and a very clear next action.', buttonText: 'Review update', buttonUrl: 'https://example.com', eyebrow: 'Announcement', align: 'left' },
        { type: 'text', heading: 'What changed', copy: 'Summarize the headline change, the practical impact, and the timeline so the reader understands the message quickly.' },
        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', heading: 'Drive action with a clean offer panel', copy: 'Promotional themes work best when the value is obvious, the terms are simple, and the CTA appears early.', buttonText: 'Claim offer', buttonUrl: 'https://example.com', eyebrow: 'Promotion', 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', 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', eyebrow: 'Event invite', 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', 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', eyebrow: 'Retention', 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 state = (() => {
    const presetState = clone(presetCatalog[defaultPreset]);
    let parsedJson = null;
    try {
      parsedJson = editorBootstrap.theme_json ? JSON.parse(editorBootstrap.theme_json) : null;
    } catch (error) {
      parsedJson = null;
    }
    const merged = parsedJson ? deepMerge(presetState, parsedJson) : presetState;
    merged.settings = merged.settings || clone(presetCatalog[defaultPreset].settings);
    merged.sections = Array.isArray(merged.sections) ? merged.sections : clone(presetCatalog[defaultPreset].sections);
    merged.theme_preset = editorBootstrap.theme_preset || merged.theme_preset || defaultPreset;
    merged.builderActive = Boolean(editorBootstrap.theme_json || !String(editorBootstrap.theme_body_html || '').trim());
    return merged;
  })();

  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 applyStateToFields = () => {
    Object.entries(settingsFields).forEach(([key, input]) => {
      if (input) input.value = state.settings[key];
    });
    presetSelect.value = state.theme_preset || 'newsletter';
    presetHidden.value = state.theme_preset || 'newsletter';
  };

  const syncThemeJson = () => {
    themeJsonInput.value = JSON.stringify({
      theme_preset: state.theme_preset || 'custom',
      settings: state.settings,
      sections: state.sections,
      builderActive: state.builderActive,
    });
  };

  const renderSectionFields = (section, index) => {
    const card = document.createElement('article');
    card.className = 'theme-section-card';
    const actions = `
      <div class="theme-section-card-actions">
        <button type="button" class="btn secondary small" data-move="up">↑</button>
        <button type="button" class="btn secondary small" data-move="down">↓</button>
        <button type="button" class="btn danger small" data-remove="1">Remove</button>
      </div>`;
    const title = section.type === 'columns' ? 'Two Column' : section.type.charAt(0).toUpperCase() + section.type.slice(1);
    const field = (label, key, value, type = 'text') => {
      if (type === 'textarea') {
        return `<label><span class="small muted">${label}</span><textarea data-field="${key}" rows="4">${escapeHtml(value)}</textarea></label>`;
      }
      if (type === 'select') {
        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}" type="${type}" value="${escapeAttribute(value)}"></label>`;
    };

    let fields = '';
    switch (section.type) {
      case 'hero':
        fields = [
          field('Eyebrow', 'eyebrow', section.eyebrow || ''),
          field('Heading', 'heading', section.heading || ''),
          field('Body copy', 'copy', section.copy || '', 'textarea'),
          field('Button text', 'buttonText', section.buttonText || ''),
          field('Button URL', 'buttonUrl', section.buttonUrl || ''),
          field('Alignment', 'align', section.align || 'left', 'select'),
        ].join('');
        break;
      case 'text':
        fields = [
          field('Heading', 'heading', section.heading || ''),
          field('Body copy', 'copy', section.copy || '', 'textarea'),
        ].join('');
        break;
      case 'image':
        fields = [
          field('Image URL', 'imageUrl', section.imageUrl || ''),
          field('Alt text', 'altText', section.altText || ''),
          field('Caption', 'caption', section.caption || '', 'textarea'),
        ].join('');
        break;
      case 'columns':
        fields = [
          field('Left heading', 'leftHeading', section.leftHeading || ''),
          field('Left copy', 'leftCopy', section.leftCopy || '', 'textarea'),
          field('Right heading', 'rightHeading', section.rightHeading || ''),
          field('Right copy', 'rightCopy', section.rightCopy || '', 'textarea'),
        ].join('');
        break;
      case 'cta':
        fields = [
          field('Heading', 'heading', section.heading || ''),
          field('Body copy', 'copy', section.copy || '', 'textarea'),
          field('Button text', 'buttonText', section.buttonText || ''),
          field('Button URL', 'buttonUrl', section.buttonUrl || ''),
        ].join('');
        break;
      case 'footer':
        fields = field('Footer copy', 'copy', section.copy || '', 'textarea');
        break;
      default:
        fields = '<div class="small muted">Divider adds breathing room between sections.</div>';
        break;
    }

    card.innerHTML = `
      <div class="theme-section-card-head">
        <div>
          <strong>${title}</strong>
          <div class="small muted">Section ${index + 1}</div>
        </div>
        ${actions}
      </div>
      <div class="theme-section-fields">${fields}</div>`;

    card.querySelectorAll('[data-field]').forEach((input) => {
      input.addEventListener('input', () => {
        section[input.dataset.field] = input.value;
        state.builderActive = true;
        syncFromBuilder();
      });
      input.addEventListener('change', () => {
        section[input.dataset.field] = input.value;
        state.builderActive = true;
        syncFromBuilder();
      });
    });

    const move = (direction) => {
      const target = direction === 'up' ? index - 1 : index + 1;
      if (target < 0 || target >= state.sections.length) return;
      const [current] = state.sections.splice(index, 1);
      state.sections.splice(target, 0, current);
      state.builderActive = true;
      renderSections();
      syncFromBuilder();
    };

    const upButton = card.querySelector('[data-move="up"]');
    const downButton = card.querySelector('[data-move="down"]');
    const removeButton = card.querySelector('[data-remove]');
    if (upButton) upButton.addEventListener('click', () => move('up'));
    if (downButton) downButton.addEventListener('click', () => move('down'));
    if (removeButton) removeButton.addEventListener('click', () => {
      state.sections.splice(index, 1);
      state.builderActive = true;
      renderSections();
      syncFromBuilder();
    });
    sectionsContainer.appendChild(card);
  };

  const renderSections = () => {
    sectionsContainer.innerHTML = '';
    if (!state.sections.length) {
      sectionsContainer.innerHTML = '<div class="theme-section-empty muted">No sections added yet. Start with a preset or add a hero, text, image, CTA, or footer block.</div>';
      return;
    }
    state.sections.forEach((section, index) => renderSectionFields(section, index));
  };

  const buttonMarkup = (section, settings) => {
    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>`;
  };

  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;

    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(section, settings)}</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>`;
  };

  const syncFromBuilder = () => {
    if (selectedType() !== 'email') return;
    syncThemeJson();
    if (state.builderActive) {
      bodyField.value = buildGeneratedHtml();
    }
    renderPreview();
  };

  const applyPreset = (presetKey, preserveContent = false) => {
    const preset = clone(presetCatalog[presetKey] || presetCatalog.newsletter);
    state.theme_preset = preset.theme_preset || presetKey;
    state.settings = clone(preset.settings);
    if (!preserveContent) {
      state.sections = clone(preset.sections);
      state.builderActive = true;
    }
    applyStateToFields();
    renderSections();
    syncFromBuilder();
  };

  const syncSettingsFromInputs = () => {
    state.settings.width = Number(settingsFields.width.value || 640);
    state.settings.fontFamily = settingsFields.fontFamily.value;
    state.settings.bodyBg = settingsFields.bodyBg.value;
    state.settings.cardBg = settingsFields.cardBg.value;
    state.settings.textColor = settingsFields.textColor.value;
    state.settings.accentColor = settingsFields.accentColor.value;
    state.settings.buttonTextColor = settingsFields.buttonTextColor.value;
    state.settings.radius = Number(settingsFields.radius.value || 18);
    state.builderActive = true;
    syncFromBuilder();
  };

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

  typeInputs.forEach((input) => input.addEventListener('change', updateModeVisibility));
  addSectionButtons.forEach((button) => button.addEventListener('click', () => {
    const factory = sectionDefaults[button.dataset.section];
    if (!factory) return;
    state.sections.push(factory());
    state.builderActive = true;
    renderSections();
    syncFromBuilder();
  }));
  presetSelect.addEventListener('change', () => applyPreset(presetSelect.value));
  Object.values(settingsFields).forEach((input) => {
    input.addEventListener('input', syncSettingsFromInputs);
    input.addEventListener('change', syncSettingsFromInputs);
  });
  bodyField.addEventListener('input', () => {
    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);
      }
    });
  }

  form.addEventListener('submit', () => {
    if (selectedType() === 'email') {
      syncThemeJson();
    } else {
      themeJsonInput.value = '';
      presetHidden.value = '';
    }
  });

  const bootstrapType = editorBootstrap.type || 'email';
  typeInputs.forEach((input) => {
    input.checked = input.value === bootstrapType;
  });
  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;
  }

  applyStateToFields();
  renderSections();
  if (state.builderActive) {
    bodyField.value = buildGeneratedHtml();
  }
  syncThemeJson();
  updateModeVisibility();
})();
