function getTiptap() {
  return window.Tiptap || {};
}

function buildTpToolbar(mini, isOption) {
  var btns;
  if (isOption) {
    btns = '<button type="button" class="tp-btn" data-cmd="bold" title="Bold"><i class="fas fa-bold"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="italic" title="Italic"><i class="fas fa-italic"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="link" title="Link"><i class="fas fa-link"></i></button>';
  } else if (mini) {
    btns = '<button type="button" class="tp-btn" data-cmd="bold" title="Bold"><i class="fas fa-bold"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="italic" title="Italic"><i class="fas fa-italic"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="bulletList" title="List"><i class="fas fa-list-ul"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="link" title="Link"><i class="fas fa-link"></i></button>';
  } else {
    btns = '<button type="button" class="tp-btn" data-cmd="bold" title="Bold"><i class="fas fa-bold"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="italic" title="Italic"><i class="fas fa-italic"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="underline" title="Underline"><i class="fas fa-underline"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="strike" title="Strike"><i class="fas fa-strikethrough"></i></button>' +
           '<span class="tp-sep"></span>' +
           '<button type="button" class="tp-btn" data-cmd="h2" title="Heading 2">H2</button>' +
           '<button type="button" class="tp-btn" data-cmd="h3" title="Heading 3">H3</button>' +
           '<span class="tp-sep"></span>' +
           '<button type="button" class="tp-btn" data-cmd="bulletList" title="Bullet List"><i class="fas fa-list-ul"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="orderedList" title="Numbered List"><i class="fas fa-list-ol"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="blockquote" title="Blockquote"><i class="fas fa-quote-left"></i></button>' +
           '<button type="button" class="tp-btn" data-cmd="codeBlock" title="Code"><i class="fas fa-code"></i></button>' +
           '<span class="tp-sep"></span>' +
           '<button type="button" class="tp-btn" data-cmd="link" title="Link"><i class="fas fa-link"></i></button>' +
           '<span class="tp-sep"></span>' +
           '<button type="button" class="tp-btn" data-cmd="clear" title="Clear formatting"><i class="fas fa-remove-format"></i></button>';
  }
  return '<div class="tp-toolbar' + (mini ? ' tp-toolbar-mini' : '') + '">' + btns + '</div>' +
         '<div class="tp-link-bar" style="display:none;">' +
           '<input type="url" class="tp-link-input" placeholder="https://">' +
           '<button type="button" class="tp-link-apply">Apply</button>' +
           '<button type="button" class="tp-link-remove">Remove</button>' +
           '<button type="button" class="tp-link-cancel">&times;</button>' +
         '</div>';
}

function wireTpToolbar(wrap, editor) {
  var linkBar   = wrap.querySelector('.tp-link-bar');
  var linkInput = wrap.querySelector('.tp-link-input');

  wrap.querySelector('.tp-toolbar').addEventListener('mousedown', function(e) {
    var btn = e.target.closest('.tp-btn[data-cmd]');
    if (!btn) return;
    e.preventDefault();
    var cmd = btn.dataset.cmd;
    switch (cmd) {
      case 'bold':         editor.chain().focus().toggleBold().run(); break;
      case 'italic':       editor.chain().focus().toggleItalic().run(); break;
      case 'underline':    editor.chain().focus().toggleUnderline().run(); break;
      case 'strike':       editor.chain().focus().toggleStrike().run(); break;
      case 'h2':           editor.chain().focus().toggleHeading({ level: 2 }).run(); break;
      case 'h3':           editor.chain().focus().toggleHeading({ level: 3 }).run(); break;
      case 'bulletList':   editor.chain().focus().toggleBulletList().run(); break;
      case 'orderedList':  editor.chain().focus().toggleOrderedList().run(); break;
      case 'blockquote':   editor.chain().focus().toggleBlockquote().run(); break;
      case 'codeBlock':    editor.chain().focus().toggleCodeBlock().run(); break;
      case 'clear':        editor.chain().focus().unsetAllMarks().clearNodes().run(); break;
      case 'link':
        if (linkBar.style.display === 'none') {
          linkInput.value = editor.getAttributes('link').href || '';
          linkBar.style.display = 'flex';
          setTimeout(function() { linkInput.focus(); }, 0);
        } else {
          linkBar.style.display = 'none';
        }
        break;
    }
    updateTpState(wrap, editor);
  });

  wrap.querySelector('.tp-link-apply').addEventListener('mousedown', function(e) {
    e.preventDefault();
    var url = linkInput.value.trim();
    if (url) editor.chain().focus().setLink({ href: url }).run();
    linkBar.style.display = 'none';
  });
  wrap.querySelector('.tp-link-remove').addEventListener('mousedown', function(e) {
    e.preventDefault();
    editor.chain().focus().unsetLink().run();
    linkBar.style.display = 'none';
  });
  wrap.querySelector('.tp-link-cancel').addEventListener('mousedown', function(e) {
    e.preventDefault();
    linkBar.style.display = 'none';
  });
  linkInput.addEventListener('keydown', function(e) {
    if (e.key === 'Enter') { e.preventDefault(); wrap.querySelector('.tp-link-apply').dispatchEvent(new MouseEvent('mousedown')); }
    if (e.key === 'Escape') linkBar.style.display = 'none';
  });
}

function updateTpState(wrap, editor) {
  wrap.querySelectorAll('.tp-btn[data-cmd]').forEach(function(btn) {
    var a = false;
    switch (btn.dataset.cmd) {
      case 'bold':        a = editor.isActive('bold'); break;
      case 'italic':      a = editor.isActive('italic'); break;
      case 'underline':   a = editor.isActive('underline'); break;
      case 'strike':      a = editor.isActive('strike'); break;
      case 'h2':          a = editor.isActive('heading', { level: 2 }); break;
      case 'h3':          a = editor.isActive('heading', { level: 3 }); break;
      case 'bulletList':  a = editor.isActive('bulletList'); break;
      case 'orderedList': a = editor.isActive('orderedList'); break;
      case 'blockquote':  a = editor.isActive('blockquote'); break;
      case 'codeBlock':   a = editor.isActive('codeBlock'); break;
      case 'link':        a = editor.isActive('link'); break;
    }
    btn.classList.toggle('active', a);
  });
}

export function makeTpEditor(wrap, existingHtml, mini, isOption) {
  var T = getTiptap();
  wrap.innerHTML = buildTpToolbar(mini, isOption) + '<div class="tp-content"></div>';
  var ed = new T.Editor({
    element: wrap.querySelector('.tp-content'),
    extensions: [
      T.StarterKit,
      T.Link.configure({ openOnClick: false, autolink: true }),
      T.Underline
    ],
    content: existingHtml || '',
    onUpdate:          function() { updateTpState(wrap, ed); },
    onSelectionUpdate: function() { updateTpState(wrap, ed); }
  });
  wireTpToolbar(wrap, ed);
  return ed;
}

export function getTpHTML(editor) {
  if (!editor) return '';
  var html = editor.getHTML();
  return (html === '<p></p>' || html === '') ? '' : html;
}

export function destroyTpEditor(editor) {
  if (editor && typeof editor.destroy === 'function') editor.destroy();
}

export function destroyOptionEditor(row) {
  if (!row || !row._optEditor) return;
  destroyTpEditor(row._optEditor);
  row._optEditor = null;
}

export function destroyQuestionBlockEditors(block) {
  if (!block) return;
  destroyTpEditor(block._questionEditor);
  block._questionEditor = null;
  block.querySelectorAll('.lh-option-row').forEach(destroyOptionEditor);
}

export function clearQuestionBlocks(container) {
  if (!container) return;
  container.querySelectorAll('.lh-question-block').forEach(destroyQuestionBlockEditors);
  container.innerHTML = '';
}
