/*
 * Live-Update für Ruler/Label-Farben über data-*-Attribute am Wrapper
 * (Editor schreibt `data-ruler-color`, `data-bar-label-color`, `data-group-label-color`).
 * Frontend greift auf die Werte via `opts` zurück.
 */

import {
  updateRulerColor,
} from './ruler.js';
import {
  updateStackedBarSumLabelColors,
  updateStraightBarTopLabelColors,
} from './groupedBarLabels.js';

function _extLabels() {
  return (typeof window !== 'undefined' && window.__CE_PD_SCENE_EXT__ && window.__CE_PD_SCENE_EXT__.labels) || null;
}

export function createRulerColorObserver({
  wrapper,
  opts,
  baseRulerColor,
  effectiveBarLabelColor,
  effectiveGroupLabelColor,
  rulerEnabled,
  rulerGroup,
  waveGroup,
  THREE,
  DATA,
  axisYPrefix,
  axisYSuffix,
  dataLabelFontScale,
  formatChartNumber,
  buildRulerColorCtx,
  invalidateFrameCache,
  syncGroupedBarHeadlineLabelsFromBars,
  syncStackedBarSumLabelsFromBars,
  syncStraightBarTopLabelsFromBars,
  syncArcBarTopLabelsFromBars,
  syncWaveNodeLabelsFromSpheres,
}) {
  let lastRulerColor = baseRulerColor;
  let lastBarLabelColor = effectiveBarLabelColor;
  let lastGroupLabelColor = effectiveGroupLabelColor;

  const observer = new MutationObserver(() => {
    const nextRuler = wrapper.getAttribute('data-ruler-color') || baseRulerColor;
    const nextBar = wrapper.getAttribute('data-bar-label-color') || (typeof opts.barLabelColor === 'string' && opts.barLabelColor.trim() !== '' ? opts.barLabelColor.trim() : nextRuler);
    const nextGroup = wrapper.getAttribute('data-group-label-color') || (typeof opts.groupLabelColor === 'string' && opts.groupLabelColor.trim() !== '' ? opts.groupLabelColor.trim() : nextRuler);
    const rulerChanged = nextRuler !== lastRulerColor;
    const barChanged = nextBar !== lastBarLabelColor;
    const groupChanged = nextGroup !== lastGroupLabelColor;
    if (!rulerChanged && !barChanged && !groupChanged) return;
    if (rulerChanged || groupChanged) {
      lastRulerColor = nextRuler;
      lastGroupLabelColor = nextGroup;
      wrapper.style.setProperty('--ce-diagram-ruler-color', nextRuler);
      if (rulerEnabled && rulerGroup) {
        const ctx = buildRulerColorCtx();
        ctx.groupLabelColor = nextGroup;
        updateRulerColor(rulerGroup, nextRuler, ctx);
        invalidateFrameCache();
      }
    }
    if (barChanged) {
      lastBarLabelColor = nextBar;
      if (rulerGroup?.userData._groupedBarHeadlineMeshes?.length) {
        _extLabels()?.updateGroupedBarHeadlineLabelColors?.(rulerGroup.userData._groupedBarHeadlineMeshes, nextBar, THREE, DATA, axisYPrefix, axisYSuffix, dataLabelFontScale, formatChartNumber);
        syncGroupedBarHeadlineLabelsFromBars();
      }
      if (rulerGroup?.userData._stackedBarSumMeshes?.length) {
        updateStackedBarSumLabelColors(rulerGroup.userData._stackedBarSumMeshes, nextBar, THREE, DATA, axisYPrefix, axisYSuffix, dataLabelFontScale, formatChartNumber);
        syncStackedBarSumLabelsFromBars();
      }
      if (rulerGroup?.userData._straightBarTopLabelMeshes?.length) {
        updateStraightBarTopLabelColors(rulerGroup.userData._straightBarTopLabelMeshes, nextBar, THREE, DATA, axisYPrefix, axisYSuffix, dataLabelFontScale, formatChartNumber);
        syncStraightBarTopLabelsFromBars();
      }
      if (rulerGroup?.userData._arcBarTopLabelMeshes?.length) {
        _extLabels()?.updateArcBarTopLabelColors?.(rulerGroup.userData._arcBarTopLabelMeshes, nextBar, THREE, DATA, axisYPrefix, axisYSuffix, dataLabelFontScale, formatChartNumber);
        syncArcBarTopLabelsFromBars();
      }
      if (rulerGroup?.userData._radialBarStartLabelMeshes?.length) {
        _extLabels()?.updateRadialBarStartLabelColors?.(rulerGroup.userData._radialBarStartLabelMeshes, nextBar, THREE, DATA, axisYPrefix, axisYSuffix, dataLabelFontScale, formatChartNumber);
      }
      if (waveGroup?.userData._waveNodeLabelMeshes?.length) {
        _extLabels()?.updateWaveNodeLabelColors?.(waveGroup.userData._waveNodeLabelMeshes, nextBar, THREE, DATA, axisYPrefix, axisYSuffix, dataLabelFontScale, formatChartNumber);
        syncWaveNodeLabelsFromSpheres();
      }
    }
  });
  observer.observe(wrapper, { attributes: true, attributeFilter: ['data-ruler-color', 'data-bar-label-color', 'data-group-label-color'] });

  return {
    disconnect() { observer.disconnect(); },
  };
}
