/*
 * Datentabellen-Modal (Accessibility): Dialog mit kompletter Datenliste,
 * Suchfeld und klickbare Spaltensortierung. ESC schließt, Focus-Trap zurück zum Trigger.
 * Wird je nach Fullscreen-Zustand unter body oder wrapper gemountet.
 */

import { i18nStr, escapeHtml, escapeAttr } from '../../shared/config.js';

export function createDataTableModal({
  wrapper,
  ownerDoc,
  DATA,
  state,
  opts,
  dataTableBtn,
  backgroundTransparent,
  intToCssHex,
  barColorAtIndex,
  barGradientStopsAtIndex,
  formatDataPointDisplayValue,
  isDiagramFullscreen,
}) {
  const i18nDataTableShow = i18nStr(opts.i18nDataTableShow, 'Show data table');
  const i18nDataTableClose = i18nStr(opts.i18nDataTableClose, 'Close');
  const i18nDataTableCaption = i18nStr(opts.i18nDataTableCaption, 'Diagram data');
  const i18nDataTableColValue = i18nStr(opts.i18nDataTableColValue, 'Value');
  const i18nDataTableColTitle = i18nStr(opts.i18nDataTableColTitle, 'Title');
  const i18nDataTableColDescription = i18nStr(opts.i18nDataTableColDescription, 'Description');
  const i18nDataTableColSmallPrint = i18nStr(opts.i18nDataTableColSmallPrint, 'Note');
  const i18nDataTableColColor = i18nStr(opts.i18nDataTableColColor, 'Color');
  const i18nDataTableColGroup = i18nStr(opts.i18nDataTableColGroup, 'X group');

  function formatDataTableValueCell(item) {
    return formatDataPointDisplayValue(item);
  }

  /* Verlaufs-Swatch (Gradient-Balken): echter linear-gradient + Mittelfarbe als
   * background-color (PNG-Export liest getComputedStyle().backgroundColor). */
  function swatchCellHtml(i) {
    const stops = typeof barGradientStopsAtIndex === 'function' ? barGradientStopsAtIndex(i) : null;
    let style;
    if (stops) {
      const mid = intToCssHex(stops[1]);
      style = 'background-color:' + mid + ';background-image:linear-gradient(to right, ' + intToCssHex(stops[0]) + ', ' + mid + ', ' + intToCssHex(stops[2]) + ')';
    } else {
      style = 'background-color:' + intToCssHex(barColorAtIndex(i));
    }
    return '<td><span class="ce-diagram-data-table-swatch" style="' + style + '" title="' + escapeAttr(i18nDataTableColColor) + '"></span></td>';
  }

  /* Add-on-Plugins koennen via `__CE_PD_SCENE_EXT__.dataTable.showsGroupColumn(layout)` weitere
   * Layouts (z. B. grouped) eintragen; Free's eigenes Layout 'stacked' hat per Default eine Gruppen-Spalte. */
  const __dtExt = (typeof window !== 'undefined' && window.__CE_PD_SCENE_EXT__ && window.__CE_PD_SCENE_EXT__.dataTable) || null;
  const __proShowsGroup = __dtExt && typeof __dtExt.showsGroupColumn === 'function'
    ? __dtExt.showsGroupColumn(state.layout) === true
    : false;
  const dataTableShowGroupCol = state.layout === 'stacked' || __proShowsGroup;

  function buildDataTableBodyHtml() {
    /* Add-on-Plugins koennen via `__CE_PD_SCENE_EXT__.dataTable.maxRows(layout)` einen Row-Cap
     * setzen (z. B. Surface 96). Free liefert kein Cap (Infinity). */
    const __maxRowsFn = __dtExt && typeof __dtExt.maxRows === 'function' ? __dtExt.maxRows : null;
    const __maxRows = __maxRowsFn ? __maxRowsFn(state.layout) : Infinity;
    if (Number.isFinite(__maxRows) && DATA.length > __maxRows) {
      const surfaceTableCap = __maxRows;
      const head = DATA.slice(0, surfaceTableCap).map((item, i) => {
        const val = escapeHtml(formatDataTableValueCell(item));
        const title = escapeHtml(item.label || '');
        const desc = escapeHtml(item.desc || '');
        const small = escapeHtml(item.source || '');
        return (
          '<tr>' +
          swatchCellHtml(i) +
          '<td class="ce-diagram-data-table-value">' + val + '</td>' +
          '<td class="ce-diagram-data-table-title">' + title + '</td>' +
          '<td class="ce-diagram-data-table-desc">' + desc + '</td>' +
          '<td class="ce-diagram-data-table-small">' + small + '</td>' +
          '</tr>'
        );
      }).join('');
      const rest = DATA.length - surfaceTableCap;
      return head + '<tr><td colspan="5" class="ce-diagram-data-table-desc">… ' + rest + ' more grid cells (export raw data for full list).</td></tr>';
    }
    const rows = DATA.map((item, i) => {
      const val = escapeHtml(formatDataTableValueCell(item));
      const gk = item.groupKey != null && String(item.groupKey).trim() !== '' ? escapeHtml(String(item.groupKey).trim()) : '';
      const title = escapeHtml(item.label || '');
      const desc = escapeHtml(item.desc || '');
      const small = escapeHtml(item.source || '');
      const groupTd = dataTableShowGroupCol
        ? '<td class="ce-diagram-data-table-group">' + gk + '</td>'
        : '';
      return (
        '<tr>' +
        swatchCellHtml(i) +
        '<td class="ce-diagram-data-table-value">' + val + '</td>' +
        groupTd +
        '<td class="ce-diagram-data-table-title">' + title + '</td>' +
        '<td class="ce-diagram-data-table-desc">' + desc + '</td>' +
        '<td class="ce-diagram-data-table-small">' + small + '</td>' +
        '</tr>'
      );
    }).join('');
    return rows;
  }

  let dataTableModal = null;

  function mountDataTableModal() {
    const mount = isDiagramFullscreen() ? wrapper : ownerDoc.body;
    if (dataTableModal && dataTableModal.parentNode !== mount) mount.appendChild(dataTableModal);
  }

  let dataTableOpen = false;
  let dataTableFocusBefore = null;

  function onDataTableKeydown(e) {
    if (e.key === 'Escape' && dataTableOpen) {
      e.preventDefault();
      closeDataTableModal();
    }
  }

  function openDataTableModal() {
    if (!dataTableModal || !dataTableBtn) return;
    dataTableFocusBefore = ownerDoc.activeElement;
    dataTableModal.removeAttribute('hidden');
    dataTableModal.setAttribute('aria-hidden', 'false');
    dataTableBtn.setAttribute('aria-expanded', 'true');
    dataTableOpen = true;
    mountDataTableModal();
    ownerDoc.addEventListener('keydown', onDataTableKeydown, true);
    requestAnimationFrame(() => {
      dataTableModal.classList.add('ce-diagram-data-modal--open');
      const closeBtn = dataTableModal.querySelector('.ce-diagram-data-modal-close');
      if (closeBtn && typeof closeBtn.focus === 'function') closeBtn.focus();
    });
  }

  function closeDataTableModal() {
    if (!dataTableModal || !dataTableBtn) return;
    dataTableModal.classList.remove('ce-diagram-data-modal--open');
    dataTableModal.setAttribute('hidden', '');
    dataTableModal.setAttribute('aria-hidden', 'true');
    dataTableBtn.setAttribute('aria-expanded', 'false');
    dataTableOpen = false;
    ownerDoc.removeEventListener('keydown', onDataTableKeydown, true);
    if (dataTableFocusBefore && typeof dataTableFocusBefore.focus === 'function') {
      try { dataTableFocusBefore.focus(); } catch (_) { /* ignore */ }
    }
    dataTableFocusBefore = null;
  }

  let onDataTableBtnClick = null;
  let onDataTableCloseClick = null;
  let onDataTableBackdropClick = null;

  if (dataTableBtn && DATA.length > 0) {
    const dialogId = 'ce-diagram-data-dialog-' + (wrapper.id || String(Math.random()).slice(2, 10));
    const captionId = dialogId + '-cap';
    dataTableModal = ownerDoc.createElement('div');
    dataTableModal.id = dialogId;
    dataTableModal.className = 'ce-diagram-data-modal' + (backgroundTransparent ? ' ce-diagram-data-modal--transparent-bg' : '');
    dataTableModal.setAttribute('role', 'dialog');
    dataTableModal.setAttribute('aria-modal', 'true');
    dataTableModal.setAttribute('aria-labelledby', captionId);
    dataTableModal.setAttribute('hidden', '');
    dataTableModal.setAttribute('aria-hidden', 'true');
    dataTableBtn.setAttribute('aria-expanded', 'false');
    dataTableBtn.setAttribute('aria-controls', dialogId);
    dataTableBtn.setAttribute('aria-haspopup', 'dialog');
    dataTableBtn.setAttribute('aria-label', i18nDataTableShow);
    dataTableModal.innerHTML =
      '<div class="ce-diagram-data-modal-panel">' +
      '<button type="button" class="ce-diagram-data-modal-close" aria-label="' + escapeAttr(i18nDataTableClose) + '">&times;</button>' +
      '<div class="ce-diagram-data-modal-inner">' +
      '<div class="ce-diagram-data-table-wrap">' +
      '<table class="ce-diagram-data-table">' +
      '<caption id="' + escapeAttr(captionId) + '">' + escapeHtml(i18nDataTableCaption) + '</caption>' +
      '<thead><tr>' +
      '<th scope="col"><span class="ce-diagram-sr-only">' + escapeHtml(i18nDataTableColColor) + '</span></th>' +
      '<th scope="col">' + escapeHtml(i18nDataTableColValue) + '</th>' +
      (dataTableShowGroupCol ? '<th scope="col">' + escapeHtml(i18nDataTableColGroup) + '</th>' : '') +
      '<th scope="col">' + escapeHtml(i18nDataTableColTitle) + '</th>' +
      '<th scope="col">' + escapeHtml(i18nDataTableColDescription) + '</th>' +
      '<th scope="col">' + escapeHtml(i18nDataTableColSmallPrint) + '</th>' +
      '</tr></thead>' +
      '<tbody>' + buildDataTableBodyHtml() + '</tbody>' +
      '</table></div></div></div>';
    mountDataTableModal();
    onDataTableBtnClick = (e) => {
      e.stopPropagation();
      openDataTableModal();
    };
    dataTableBtn.addEventListener('click', onDataTableBtnClick);
    const closeEl = dataTableModal.querySelector('.ce-diagram-data-modal-close');
    onDataTableCloseClick = () => closeDataTableModal();
    if (closeEl) closeEl.addEventListener('click', onDataTableCloseClick);
    onDataTableBackdropClick = (e) => {
      if (e.target === dataTableModal) closeDataTableModal();
    };
    dataTableModal.addEventListener('click', onDataTableBackdropClick);

    /* ── Data table: search + column sort ── */
    const dtInner = dataTableModal.querySelector('.ce-diagram-data-modal-inner');
    const dtTable = dataTableModal.querySelector('.ce-diagram-data-table');
    if (dtInner && dtTable) {
      const searchInput = ownerDoc.createElement('input');
      searchInput.type = 'search';
      searchInput.className = 'ce-diagram-data-table-search';
      searchInput.placeholder = i18nStr(opts.i18nDataTableSearch, 'Search\u2026');
      searchInput.setAttribute('aria-label', i18nStr(opts.i18nDataTableSearch, 'Search\u2026'));
      dtInner.insertBefore(searchInput, dtInner.firstChild);

      const tbody = dtTable.querySelector('tbody');
      searchInput.addEventListener('input', () => {
        const q = searchInput.value.toLowerCase().trim();
        if (!tbody) return;
        const rows = tbody.querySelectorAll('tr');
        for (let r = 0; r < rows.length; r++) {
          rows[r].style.display = (!q || rows[r].textContent.toLowerCase().indexOf(q) >= 0) ? '' : 'none';
        }
      });

      const ths = dtTable.querySelectorAll('thead th');
      let sortCol = -1;
      let sortAsc = true;
      ths.forEach((th, colIdx) => {
        if (colIdx === 0) return;
        th.style.cursor = 'pointer';
        th.setAttribute('aria-sort', 'none');
        th.addEventListener('click', () => {
          if (!tbody) return;
          if (sortCol === colIdx) { sortAsc = !sortAsc; } else { sortCol = colIdx; sortAsc = true; }
          ths.forEach((h, hi) => { if (hi > 0) h.setAttribute('aria-sort', hi === colIdx ? (sortAsc ? 'ascending' : 'descending') : 'none'); });
          const rows = Array.from(tbody.querySelectorAll('tr'));
          const isValueCol = colIdx === 1;
          rows.sort((a, b) => {
            const ca = (a.children[colIdx] || {}).textContent || '';
            const cb = (b.children[colIdx] || {}).textContent || '';
            if (isValueCol) {
              const na = parseFloat(ca.replace(/[^\d.\-]/g, '')) || 0;
              const nb = parseFloat(cb.replace(/[^\d.\-]/g, '')) || 0;
              return sortAsc ? na - nb : nb - na;
            }
            return sortAsc ? ca.localeCompare(cb, undefined, { sensitivity: 'base' }) : cb.localeCompare(ca, undefined, { sensitivity: 'base' });
          });
          rows.forEach((r) => tbody.appendChild(r));
        });
      });
    }
  }

  return {
    get dataTableModal() { return dataTableModal; },
    mountDataTableModal,
    unbind() {
      ownerDoc.removeEventListener('keydown', onDataTableKeydown, true);
      if (dataTableBtn && onDataTableBtnClick) dataTableBtn.removeEventListener('click', onDataTableBtnClick);
      const closeBtnCleanup = dataTableModal && dataTableModal.querySelector('.ce-diagram-data-modal-close');
      if (closeBtnCleanup && onDataTableCloseClick) closeBtnCleanup.removeEventListener('click', onDataTableCloseClick);
      if (dataTableModal && onDataTableBackdropClick) dataTableModal.removeEventListener('click', onDataTableBackdropClick);
      if (dataTableModal && dataTableModal.parentNode) dataTableModal.parentNode.removeChild(dataTableModal);
    },
  };
}
