// Text widget dialog: a small rich-text editor (bold/italic/underline,
// text/highlight color), font size/alignment/background settings, and
// the rendered preview. Not a page-load script -- frame_layout.js
// fetches this widget's dialog HTML fragment, injects it into the
// shared <dialog>, points window.FRAME_API at this specific widget
// (/api/frames/{id}/widgets/{widget_id}), then calls initTextDialog().
//
// The editor is never seeded via innerHTML string interpolation --
// #text-editor's data-content attribute (server-rendered from
// app/text_content.py's already-sanitized run structure, not raw HTML)
// is JSON-parsed and rebuilt with createElement/textContent below. The
// same <div><span style="..."> shape this produces is exactly what
// app/text_content.py's parser expects back on save, so round-tripping
// (load -> edit -> save -> reload) is stable.

function loadTextPreview() {
  document.getElementById('text-preview').src = `${window.FRAME_API}/preview/text?_=${Date.now()}`;
}

function buildTextEditorContent(editor, paragraphs) {
  editor.textContent = '';
  if (!paragraphs || !paragraphs.length) return;
  paragraphs.forEach((para) => {
    const div = document.createElement('div');
    if (!para.length) {
      div.appendChild(document.createElement('br'));
    } else {
      para.forEach((run) => {
        const span = document.createElement('span');
        span.textContent = run.text;
        if (run.bold) span.style.fontWeight = 'bold';
        if (run.italic) span.style.fontStyle = 'italic';
        if (run.underline) span.style.textDecoration = 'underline';
        if (run.color) span.style.color = run.color;
        if (run.bg) span.style.backgroundColor = run.bg;
        div.appendChild(span);
      });
    }
    editor.appendChild(div);
  });
}

let _textSavedRange = null;
let _textSelectionHandler = null;

function initTextDialog() {
  const editor = document.getElementById('text-editor');
  let initialContent = null;
  try {
    initialContent = JSON.parse(editor.dataset.content || 'null');
  } catch (e) { /* leave empty */ }
  buildTextEditorContent(editor, initialContent);

  // Native <input type="color"> steals focus (and with it, the
  // editor's text selection) the moment it's interacted with -- track
  // the most recent in-editor selection continuously so a color pick
  // can be reapplied to the text the user actually had selected,
  // instead of applying to nothing.
  _textSelectionHandler = () => {
    const sel = window.getSelection();
    if (sel.rangeCount > 0 && editor.contains(sel.anchorNode)) {
      _textSavedRange = sel.getRangeAt(0).cloneRange();
    }
  };
  document.addEventListener('selectionchange', _textSelectionHandler);

  function restoreSelection() {
    if (!_textSavedRange) return;
    const sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(_textSavedRange);
  }

  ['text-bold', 'text-italic', 'text-underline'].forEach((id) => {
    const btn = document.getElementById(id);
    // preventDefault on mousedown keeps focus (and the selection) in
    // the editor, so the click's execCommand has something to act on.
    btn.addEventListener('mousedown', (e) => e.preventDefault());
    btn.addEventListener('click', () => {
      editor.focus();
      document.execCommand(btn.dataset.cmd, false, null);
    });
  });

  document.getElementById('text-color').addEventListener('input', (e) => {
    editor.focus();
    restoreSelection();
    document.execCommand('foreColor', false, e.target.value);
  });

  document.getElementById('text-highlight').addEventListener('input', (e) => {
    editor.focus();
    restoreSelection();
    document.execCommand('hiliteColor', false, e.target.value);
  });

  document.getElementById('text-highlight-clear').addEventListener('mousedown', (e) => e.preventDefault());
  document.getElementById('text-highlight-clear').addEventListener('click', () => {
    editor.focus();
    restoreSelection();
    document.execCommand('hiliteColor', false, 'transparent');
  });

  document.getElementById('text_font_size').addEventListener('input', (e) => {
    document.getElementById('text_font_size_value').textContent = `${e.target.value}px`;
  });

  document.getElementById('text-config-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const body = new URLSearchParams({
      text_html: editor.innerHTML,
      text_font_family: document.getElementById('text_font_family').value,
      text_font_size: document.getElementById('text_font_size').value,
      text_align: document.getElementById('text_align').value,
      text_background_color: document.getElementById('text_background_color').value,
    });
    try {
      const resp = await fetch(`${window.FRAME_API}/config`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body,
      });
      if (!resp.ok) throw new Error(await apiError(resp));
      showStatus(true, 'Saved.');
      loadTextPreview();
    } catch (e2) {
      showStatus(false, e2.message);
    }
  });

  document.getElementById('text-preview-refresh').addEventListener('click', loadTextPreview);
  loadTextPreview();
}

function closeTextDialog() {
  if (_textSelectionHandler) {
    document.removeEventListener('selectionchange', _textSelectionHandler);
    _textSelectionHandler = null;
  }
  _textSavedRange = null;
}
