import { sortBars, sortBarsGrouped, toInternalData, i18nStr } from '../../shared/config.js';

/**
 * Mountet das Viewer-Sort-Dropdown in die `.ce-diagram-top-actions`-Leiste und verdrahtet
 * den Change-Handler, der auf Sort-Änderung die Szene mit neu sortierten Daten neu aufbaut.
 *
 * Kein interner State — Caller speichert den Return-Wert selbst (wird in initScene().cleanup()
 * beim Tear-Down referenziert und entfernt).
 *
 * @param {object}       params
 * @param {HTMLElement}  params.wrapper        - .ce-diagram-wrapper
 * @param {Document}     params.ownerDoc       - wrapper.ownerDocument
 * @param {object}       params.opts           - view-options (u. a. viewerSortEnabled, barsSourceTagged, sortOrder, defaultLayout, i18n-Strings)
 * @param {object}       params.state          - scene-state (nur .layout gelesen)
 * @param {object}       params.reinitCtx      - { THREE, OrbitControls, RoundedBoxGeometry, Reflector, wrapper, container, tooltip, iconEl }, wird 1:1 in initScene durchgereicht
 * @param {Function}     params.cleanup        - initScene().cleanup; wird vor Re-Init aufgerufen
 * @param {Function}     params.initScene      - self-reference zum erneuten Szenenaufbau mit neu sortierten Daten
 * @returns {HTMLElement|null} Das Wrapper-Element (oder null, wenn Kontrolle nicht angelegt wurde).
 */
export function createViewerSortControl({ wrapper, ownerDoc, opts, state, reinitCtx, cleanup, initScene }) {
  if (opts.viewerSortEnabled !== true) return null;
  /* Add-on-Plugins koennen via `__CE_PD_SCENE_EXT__.layoutDisablesViewerSort(layout) === true`
   * Layouts ausschliessen (z. B. Surface — XY-Daten ohne sinnvolle Bar-Sortierung). */
  const ext = (typeof window !== 'undefined' && window.__CE_PD_SCENE_EXT__) || null;
  if (ext && typeof ext.layoutDisablesViewerSort === 'function' && ext.layoutDisablesViewerSort(state.layout) === true) return null;
  if (!opts.barsSourceTagged || opts.barsSourceTagged.length === 0) return null;

  const topActions = wrapper.querySelector('.ce-diagram-top-actions');
  if (!topActions) return null;

  const labelText = i18nStr(opts.i18nViewerSortLabel, 'Sort order');
  const ariaSort = i18nStr(opts.i18nViewerSortAria, labelText);
  const selId = (wrapper.id || 'ce-diagram') + '-viewer-sort';

  const viewerSortWrapEl = ownerDoc.createElement('div');
  viewerSortWrapEl.className = 'ce-diagram-expand-btn ce-diagram-viewer-sort';
  viewerSortWrapEl.setAttribute('role', 'group');

  const body = ownerDoc.createElement('div');
  body.className = 'ce-diagram-expand-btn__label ce-diagram-viewer-sort__body';

  const srOnly = ownerDoc.createElement('label');
  srOnly.className = 'ce-diagram-sr-only';
  srOnly.setAttribute('for', selId);
  srOnly.textContent = labelText;

  const sel = ownerDoc.createElement('select');
  sel.id = selId;
  sel.className = 'ce-diagram-viewer-sort__select';
  sel.setAttribute('aria-label', ariaSort);
  const orderVal = opts.sortOrder || 'custom';
  const sortOptions = [
    ['custom', i18nStr(opts.i18nSortCustom, 'Custom (author order)')],
    ['value_asc', i18nStr(opts.i18nSortValueAsc, 'Value ascending')],
    ['value_desc', i18nStr(opts.i18nSortValueDesc, 'Value descending')],
    ['headline_asc', i18nStr(opts.i18nSortHeadlineAsc, 'Label A–Z')],
  ];
  sortOptions.forEach(([val, optLab]) => {
    const o = ownerDoc.createElement('option');
    o.value = val;
    o.textContent = optLab;
    if (val === orderVal) o.selected = true;
    sel.appendChild(o);
  });

  body.appendChild(srOnly);
  body.appendChild(sel);

  const iconWrap = ownerDoc.createElement('div');
  iconWrap.className = 'ce-diagram-expand-btn__icon';
  iconWrap.setAttribute('aria-hidden', 'true');
  if (opts.viewerSortGlyphUrl) {
    const sortImg = ownerDoc.createElement('img');
    sortImg.className = 'ce-diagram-viewer-sort__glyph';
    sortImg.src = opts.viewerSortGlyphUrl;
    sortImg.width = 24;
    sortImg.height = 24;
    sortImg.alt = '';
    sortImg.decoding = 'async';
    sortImg.draggable = false;
    iconWrap.appendChild(sortImg);
  }

  viewerSortWrapEl.appendChild(body);
  viewerSortWrapEl.appendChild(iconWrap);

  const dataTableForOrder = wrapper.querySelector('.ce-diagram-data-table-btn');
  if (dataTableForOrder) {
    topActions.insertBefore(viewerSortWrapEl, dataTableForOrder);
  } else {
    topActions.appendChild(viewerSortWrapEl);
  }

  sel.addEventListener('change', () => {
    const newOrder = sel.value;
    const tagged = opts.barsSourceTagged;
    if (!tagged || tagged.length === 0) return;
    const layoutKey = opts.defaultLayout || 'straight';
    const raw = tagged.map((b) => ({ ...b }));
    /* Free's `stacked` braucht gruppenweise Sortierung (Segmente bleiben pro Bar
     * zusammen). Add-on-Plugins koennen weitere Layouts via
     * `layoutUsesGroupedSort(layout) === true` anmelden (z. B. grouped). */
    const usesGroupedSort = layoutKey === 'stacked'
      || (ext && typeof ext.layoutUsesGroupedSort === 'function' && ext.layoutUsesGroupedSort(layoutKey) === true);
    const sorted = usesGroupedSort
      ? sortBarsGrouped(raw, newOrder)
      : sortBars(raw, newOrder);
    const newDATA = toInternalData(sorted, layoutKey);
    cleanup({ exitFullscreen: false });
    const nextOpts = Object.assign({}, opts, { sortOrder: newOrder });
    initScene({ ...reinitCtx, DATA: newDATA, opts: nextOpts });
  });

  return viewerSortWrapEl;
}
