/* Markdown editor (edit-control A5) — progressive enhancement over a <textarea>.
   Adds a formatting toolbar + Write/Preview tabs. The preview mirrors the SERVER
   subset (escape-all-HTML first, then a fixed set of safe tags), so what you see
   is close to the sanitised output; the server is still the source of truth. */
(function () {
  'use strict';
  if (window.__ppMdInit) return;           // one-time global init
  window.__ppMdInit = true;

  var esc = function (s) {
    return String(s).replace(/[&<>"']/g, function (c) {
      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
    });
  };

  // Client preview — same escape-first subset as core/Html/Markdown.php.
  function render(src) {
    src = String(src).replace(/\r\n?/g, '\n');
    var lines = src.split('\n'), out = [], i = 0;
    function inline(t) {
      t = esc(t);
      var codes = [], S0 = String.fromCharCode(2), S1 = String.fromCharCode(3);
      // Protect inline code with sentinels so nothing else touches it.
      t = t.replace(/`([^`\n]+)`/g, function (_, c) { codes.push('<code>' + c + '</code>'); return S0 + (codes.length - 1) + S1; });
      t = t.replace(/!\[([^\]]*)\]\(([^)\s]+)\)/g, '<img src="$2" alt="$1">');
      t = t.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, '<a href="$2" rel="nofollow ugc noopener" target="_blank">$1</a>');
      t = t.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>').replace(/__([^_]+)__/g, '<strong>$1</strong>');
      t = t.replace(/(^|[^*])\*([^*\n]+)\*/g, '$1<em>$2</em>');
      t = t.replace(new RegExp(S0 + '(\\d+)' + S1, 'g'), function (_, n) { return codes[+n]; });
      return t;
    }
    while (i < lines.length) {
      var ln = lines[i];
      if (ln.trim() === '') { i++; continue; }
      var m;
      if (/^```/.test(ln)) {
        i++; var buf = [];
        while (i < lines.length && !/^```\s*$/.test(lines[i])) { buf.push(lines[i]); i++; }
        i++; out.push('<pre><code>' + esc(buf.join('\n')) + '</code></pre>'); continue;
      }
      if ((m = ln.match(/^(#{1,6})\s+(.*)$/))) { var l = Math.max(2, Math.min(4, m[1].length + 1)); out.push('<h' + l + '>' + inline(m[2]) + '</h' + l + '>'); i++; continue; }
      if (/^\s*([-*_])(\s*\1){2,}\s*$/.test(ln)) { out.push('<hr>'); i++; continue; }
      if (/^\s*>\s?/.test(ln)) { var q = []; while (i < lines.length && /^\s*>\s?(.*)$/.test(lines[i])) { q.push(lines[i].replace(/^\s*>\s?/, '')); i++; } out.push('<blockquote>' + render(q.join('\n')) + '</blockquote>'); continue; }
      if (/^\s*[-*+]\s+/.test(ln)) { var u = []; while (i < lines.length && (m = lines[i].match(/^\s*[-*+]\s+(.*)$/))) { u.push('<li>' + inline(m[1]) + '</li>'); i++; } out.push('<ul>' + u.join('') + '</ul>'); continue; }
      if (/^\s*\d+\.\s+/.test(ln)) { var o = []; while (i < lines.length && (m = lines[i].match(/^\s*\d+\.\s+(.*)$/))) { o.push('<li>' + inline(m[1]) + '</li>'); i++; } out.push('<ol>' + o.join('') + '</ol>'); continue; }
      var p = [];
      while (i < lines.length && lines[i].trim() !== '' && !/^(#{1,6})\s|^```|^\s*>\s?|^\s*[-*+]\s+|^\s*\d+\.\s+/.test(lines[i])) { p.push(inline(lines[i])); i++; }
      out.push('<p>' + p.join('<br>') + '</p>');
    }
    return out.join('\n');
  }

  var TOOLS = [
    { t: 'B', title: 'Bold', wrap: ['**', '**'] },
    { t: 'i', title: 'Italic', wrap: ['*', '*'] },
    { t: '</>', title: 'Inline code', wrap: ['`', '`'] },
    { t: '{ }', title: 'Code block', block: '```\n', blockEnd: '\n```' },
    { t: '“', title: 'Quote', line: '> ' },
    { t: '•', title: 'Bullet list', line: '- ' },
    { t: '1.', title: 'Numbered list', line: '1. ' },
    { t: '🔗', title: 'Link', link: true },
    { t: 'H', title: 'Heading', line: '## ' }
  ];

  function surround(ta, before, after) {
    var s = ta.selectionStart, e = ta.selectionEnd, v = ta.value;
    var sel = v.slice(s, e) || '';
    ta.value = v.slice(0, s) + before + sel + after + v.slice(e);
    ta.focus();
    ta.selectionStart = s + before.length;
    ta.selectionEnd = s + before.length + sel.length;
    ta.dispatchEvent(new Event('input', { bubbles: true }));
  }
  function prefixLines(ta, prefix) {
    var s = ta.selectionStart, e = ta.selectionEnd, v = ta.value;
    var a = v.lastIndexOf('\n', s - 1) + 1;
    var chunk = v.slice(a, e).split('\n').map(function (l) { return prefix + l; }).join('\n');
    ta.value = v.slice(0, a) + chunk + v.slice(e);
    ta.focus();
    ta.dispatchEvent(new Event('input', { bubbles: true }));
  }

  function enhance(wrap) {
    if (wrap.__done) return; wrap.__done = true;
    var ta = wrap.querySelector('.pp-md-src');
    if (!ta) return;
    var noTb = wrap.hasAttribute('data-no-toolbar');
    var noPv = wrap.hasAttribute('data-no-preview');

    var bar = document.createElement('div');
    bar.className = 'pp-md-bar';

    if (!noTb) {
      TOOLS.forEach(function (tool) {
        var b = document.createElement('button');
        b.type = 'button'; b.className = 'pp-md-btn'; b.textContent = tool.t; b.title = tool.title;
        b.addEventListener('click', function () {
          if (tool.wrap) surround(ta, tool.wrap[0], tool.wrap[1]);
          else if (tool.block) surround(ta, tool.block, tool.blockEnd);
          else if (tool.line) prefixLines(ta, tool.line);
          else if (tool.link) {
            var url = window.prompt('Link URL (https://…)', 'https://');
            if (url) surround(ta, '[', '](' + url + ')');
          }
        });
        bar.appendChild(b);
      });
    }

    var tabs = document.createElement('div'); tabs.className = 'pp-md-tabs';
    var write = document.createElement('button'); write.type = 'button'; write.className = 'pp-md-tab on'; write.textContent = 'Write';
    var prev = document.createElement('button'); prev.type = 'button'; prev.className = 'pp-md-tab'; prev.textContent = 'Preview';
    var pane = document.createElement('div'); pane.className = 'pp-md-preview'; pane.style.display = 'none';

    if (!noPv) {
      tabs.appendChild(write); tabs.appendChild(prev);
      write.addEventListener('click', function () { write.classList.add('on'); prev.classList.remove('on'); ta.style.display = ''; pane.style.display = 'none'; });
      prev.addEventListener('click', function () { prev.classList.add('on'); write.classList.remove('on'); pane.innerHTML = render(ta.value) || '<p class="pp-md-empty">Nothing to preview yet.</p>'; ta.style.display = 'none'; pane.style.display = ''; });
    }

    var head = document.createElement('div'); head.className = 'pp-md-head';
    if (!noPv) head.appendChild(tabs);
    if (!noTb) head.appendChild(bar);
    wrap.insertBefore(head, ta);
    wrap.appendChild(pane);
    var hint = document.createElement('div'); hint.className = 'pp-md-hint'; hint.textContent = 'Markdown supported. Content is sanitised on save.';
    wrap.appendChild(hint);
  }

  function boot() {
    var nodes = document.querySelectorAll('[data-pp-md]');
    for (var i = 0; i < nodes.length; i++) enhance(nodes[i]);
  }
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
  else boot();
})();
