/**
 * Security check template schema editor.
 *
 * Edits the per-product technical checklist as an ordered list of items:
 *   - section: a grouping heading (label only)
 *   - check:   a tracked checkpoint (label + optional hint + optional Markdown guidance)
 *
 * Serializes the items to the hidden #security-schema-json input on every change
 * and on form submit. Item keys are (re)generated server-side on save.
 */
import { resolveHost } from '/js/core/app-dom.js';
import { escapeHtml } from '/js/pages/app-list-utils.js';

const SELECTOR = '#security-schema-editor[data-app-component="security-template-schema-editor"]';
const EMPTY_API = Object.freeze({ destroy: () => {} });

const resolveEditor = (root) => {
  const host = resolveHost(root);
  if (host instanceof HTMLElement && host.matches(SELECTOR)) {
    return host;
  }
  return host.querySelector(SELECTOR);
};

export function initSecurityTemplateSchemaEditor(root = document) {
  const editor = resolveEditor(root);
  if (!editor) {
    return EMPTY_API;
  }

  const form = editor.closest('form');
  const hidden = form?.querySelector('#security-schema-json');
  if (!form || !hidden) {
    return EMPTY_API;
  }

  const labels = {
    section: editor.dataset.labelSection || 'Section',
    check: editor.dataset.labelCheck || 'Check item',
    addSection: editor.dataset.labelAddSection || 'Add section',
    addCheck: editor.dataset.labelAddCheck || 'Add check item',
    remove: editor.dataset.labelRemove || 'Remove',
    moveUp: editor.dataset.labelMoveUp || 'Move up',
    moveDown: editor.dataset.labelMoveDown || 'Move down',
    phSection: editor.dataset.placeholderSection || 'Section title',
    phCheck: editor.dataset.placeholderCheck || 'Check item label',
    phHint: editor.dataset.placeholderHint || 'Hint (optional)',
    phMarkdown: editor.dataset.placeholderMarkdown || 'Markdown (optional)',
    empty: editor.dataset.emptyText || 'No checklist items yet.',
  };

  const listenerController = new AbortController();

  /** @type {{type:string,label:string,hint:string,markdown:string}[]} */
  let items = [];
  try {
    const initial = JSON.parse(document.getElementById('security-schema-initial')?.textContent || '[]');
    if (Array.isArray(initial)) {
      items = initial.map((it) => ({
        type: it && it.type === 'section' ? 'section' : 'check',
        label: String((it && it.label) || ''),
        hint: String((it && it.hint) || ''),
        markdown: String((it && it.markdown) || ''),
      }));
    }
  } catch {
    items = [];
  }

  const serialize = () => {
    hidden.value = JSON.stringify(items.map((it) => (
      it.type === 'section'
        ? { type: 'section', label: it.label }
        : { type: 'check', label: it.label, hint: it.hint, markdown: it.markdown }
    )));
  };

  const render = () => {
    const list = document.createElement('div');
    list.className = 'security-schema-items';

    if (items.length === 0) {
      const empty = document.createElement('p');
      empty.className = 'app-muted';
      empty.textContent = labels.empty;
      list.appendChild(empty);
    }

    items.forEach((item, index) => {
      const row = document.createElement('div');
      row.className = `security-schema-item security-schema-item-${item.type}`;
      row.dataset.index = String(index);

      const topRow = document.createElement('div');
      topRow.className = 'security-schema-item-row';

      const labelInput = document.createElement('input');
      labelInput.type = 'text';
      labelInput.className = 'security-schema-label';
      labelInput.value = item.label;
      labelInput.placeholder = item.type === 'section' ? labels.phSection : labels.phCheck;
      labelInput.addEventListener('input', () => { items[index].label = labelInput.value; serialize(); }, { signal: listenerController.signal });

      const typeBadge = document.createElement('span');
      typeBadge.className = 'security-schema-type badge';
      typeBadge.dataset.variant = item.type === 'section' ? 'neutral' : 'info';
      typeBadge.textContent = item.type === 'section' ? labels.section : labels.check;

      topRow.appendChild(typeBadge);
      topRow.appendChild(labelInput);

      if (item.type === 'check') {
        const hintInput = document.createElement('input');
        hintInput.type = 'text';
        hintInput.className = 'security-schema-hint';
        hintInput.value = item.hint;
        hintInput.placeholder = labels.phHint;
        hintInput.addEventListener('input', () => { items[index].hint = hintInput.value; serialize(); }, { signal: listenerController.signal });
        topRow.appendChild(hintInput);
      }

      const controls = document.createElement('div');
      controls.className = 'security-schema-controls';
      controls.innerHTML = `
        <button type="button" class="app-icon-button" data-action="up" data-tooltip="${escapeHtml(labels.moveUp)}" aria-label="${escapeHtml(labels.moveUp)}"><i class="bi bi-arrow-up"></i></button>
        <button type="button" class="app-icon-button" data-action="down" data-tooltip="${escapeHtml(labels.moveDown)}" aria-label="${escapeHtml(labels.moveDown)}"><i class="bi bi-arrow-down"></i></button>
        <button type="button" class="app-icon-button" data-action="remove" data-tooltip="${escapeHtml(labels.remove)}" aria-label="${escapeHtml(labels.remove)}"><i class="bi bi-x-lg"></i></button>
      `;
      controls.querySelectorAll('button[data-action]').forEach((btn) => {
        btn.addEventListener('click', () => {
          const action = btn.dataset.action;
          if (action === 'remove') {
            items.splice(index, 1);
          } else if (action === 'up' && index > 0) {
            [items[index - 1], items[index]] = [items[index], items[index - 1]];
          } else if (action === 'down' && index < items.length - 1) {
            [items[index + 1], items[index]] = [items[index], items[index + 1]];
          } else {
            return;
          }
          serialize();
          render();
        }, { signal: listenerController.signal });
      });
      topRow.appendChild(controls);
      row.appendChild(topRow);

      if (item.type === 'check') {
        const markdownInput = document.createElement('textarea');
        markdownInput.className = 'security-schema-markdown';
        markdownInput.rows = 2;
        markdownInput.value = item.markdown;
        markdownInput.placeholder = labels.phMarkdown;
        markdownInput.addEventListener('input', () => { items[index].markdown = markdownInput.value; serialize(); }, { signal: listenerController.signal });
        row.appendChild(markdownInput);
      }

      list.appendChild(row);
    });

    const toolbar = document.createElement('div');
    toolbar.className = 'security-schema-toolbar';
    const addSection = document.createElement('button');
    addSection.type = 'button';
    addSection.className = 'secondary outline small';
    addSection.innerHTML = `<i class="bi bi-type-h3"></i> ${escapeHtml(labels.addSection)}`;
    addSection.addEventListener('click', () => { items.push({ type: 'section', label: '', hint: '', markdown: '' }); serialize(); render(); }, { signal: listenerController.signal });
    const addCheck = document.createElement('button');
    addCheck.type = 'button';
    addCheck.className = 'secondary outline small';
    addCheck.innerHTML = `<i class="bi bi-check2-square"></i> ${escapeHtml(labels.addCheck)}`;
    addCheck.addEventListener('click', () => { items.push({ type: 'check', label: '', hint: '', markdown: '' }); serialize(); render(); }, { signal: listenerController.signal });
    toolbar.appendChild(addCheck);
    toolbar.appendChild(addSection);

    editor.replaceChildren(list, toolbar);
  };

  form.addEventListener('submit', serialize, { signal: listenerController.signal });

  serialize();
  render();

  return {
    destroy: () => listenerController.abort(),
  };
}
