/**
 * Pure Helper: Normalisierung der attribute-Werte für Panel-Controls + Preview.
 * i18n-abhängige Strings werden ausschließlich als Funktionen exportiert,
 * damit setLocaleData garantiert vor dem ersten __()-Aufruf gelaufen ist.
 *
 * Add-ons koennen ueber `window.__CE_PD_EDITOR_EXT__.registerPaletteOption(...)`
 * weitere Palette-Optionen einblenden (mit `order`-Feld fuer Sortierung).
 */
import { sortGroupedBarRowsWithIndices } from '../shared/config.js';
import { MAX_H_BREAKPOINTS, STRAIGHT_BAR_LABEL_VALUES, PIE_SLICE_LABEL_VALUES, isPieLayout } from './constants.js';
import { cePdEditorExt } from './editorExt.js';

const { __ } = wp.i18n;

const unset = (v) => v === '' || v === undefined || v === null;
const normSlot = (v) => (STRAIGHT_BAR_LABEL_VALUES.indexOf(v) >= 0 ? v : 'off');

/**
 * Palette-Optionen (i18n) plus Add-on-registrierte Eintraege.
 * Reihenfolge der Palette-Auswahl: Vivid(0), Ocean Sunset(6), Purple Raindrops(11),
 * Spectrum(12), Magenta Dream(13), Twilight(14), Material(15), Corporate(16),
 * Accessible(17), Monochrome(18), Diverging(19). Add-ons setzen `order`, damit zusaetzliche
 * Paletten an ihrer gewuenschten Position eingemischt werden.
 */
export function getColorSchemeOptions() {
  const base = [
    { label: __('Vivid (rainbow)', 'pop3d-charts'), value: 'vivid', order: 0 },
    { label: __('Theme colors', 'pop3d-charts'), value: 'theme', order: 1 },
    { label: __('Ocean Sunset', 'pop3d-charts'), value: 'oceanSunset', order: 6 },
    { label: __('Purple Raindrops', 'pop3d-charts'), value: 'purpleRaindrops', order: 11 },
    { label: __('Spectrum', 'pop3d-charts'), value: 'spectrum', order: 12 },
    { label: __('Magenta Dream', 'pop3d-charts'), value: 'magentaDream', order: 13 },
    { label: __('Twilight', 'pop3d-charts'), value: 'twilight', order: 14 },
    { label: __('Material (Google palette)', 'pop3d-charts'), value: 'material', order: 15 },
    { label: __('Corporate (business tones)', 'pop3d-charts'), value: 'corporate', order: 16 },
    { label: __('Accessible (colorblind-safe)', 'pop3d-charts'), value: 'accessible', order: 17 },
    { label: __('Monochrome (grayscale)', 'pop3d-charts'), value: 'monochrome', order: 18 },
    { label: __('Diverging (red to blue)', 'pop3d-charts'), value: 'diverging', order: 19 },
  ];
  const ext = (cePdEditorExt && typeof cePdEditorExt.getPaletteOptions === 'function')
    ? cePdEditorExt.getPaletteOptions()
    : [];
  const merged = [];
  const seen = new Set();
  base.concat(ext).forEach((opt) => {
    if (!opt || typeof opt.value !== 'string' || seen.has(opt.value)) return;
    seen.add(opt.value);
    merged.push({
      label: opt.label,
      value: opt.value,
      order: typeof opt.order === 'number' ? opt.order : 99,
    });
  });
  merged.sort((a, b) => a.order - b.order);
  return merged.map(({ label, value }) => ({ label, value }));
}

export function getChartDataIntro(layout) {
  if (isPieLayout(layout)) return __('Each row is one slice. These fields appear in tooltips when hovering or tapping a slice.', 'pop3d-charts');
  return __('These fields are shown in the tooltip when hovering or tapping a diagram element.', 'pop3d-charts');
}

/** Kurzbeschreibung für role="region" — gleiche Msgids wie ce_pd_diagram_region_aria_label() in PHP. */
export function getDiagramRegionAriaLabel(layout, projection) {
  const is2d = (projection || '3d') === '2d';
  if (layout === 'stacked') return is2d
    ? __('Stacked column chart, flat 2D view. Hover or tap bars for details.', 'pop3d-charts')
    : __('Stacked column chart, 3D view. Hover or tap bars for details.', 'pop3d-charts');
  if (isPieLayout(layout)) return is2d
    ? __('Pie chart, flat 2D view. Hover or tap slices for details.', 'pop3d-charts')
    : __('Pie chart, 3D view. Hover or tap slices for details.', 'pop3d-charts');
  if (layout === 'wave') return is2d
    ? __('Wave chart, flat 2D view. Hover or tap points for details.', 'pop3d-charts')
    : __('Wave chart, 3D view. Hover or tap points for details.', 'pop3d-charts');
  return is2d
    ? __('Column bar chart, flat 2D view. Hover or tap bars for details.', 'pop3d-charts')
    : __('Column bar chart, 3D view. Hover or tap bars for details.', 'pop3d-charts');
}

export function getStraightBarLabelSlots(attributes) {
  let above = attributes.straightBarLabelAbove;
  let below = attributes.straightBarLabelBelow;
  if (unset(above) && unset(below)) {
    if (attributes.labelsUnderBars === true) return { above: 'off', below: 'headline' };
    return { above: 'off', below: 'off' };
  }
  above = normSlot(above);
  below = normSlot(below);
  if (above === below && above !== 'off') below = 'off';
  return { above, below };
}

/** Stacked: sum label on/off. */
export function getStackedBarSumAbove(attributes) {
  if (attributes.stackedBarSumAbove === true) return true;
  return false;
}

export function getPieSliceLabel(attributes) {
  const raw = attributes.pieSliceLabel;
  if (unset(raw)) return 'value';
  return PIE_SLICE_LABEL_VALUES.indexOf(raw) >= 0 ? raw : 'value';
}

export function mergeDiagramMaxHByBp(raw) {
  const d = {
    desktop: { value: '', unit: 'px' },
    tablet: { value: '', unit: 'px' },
    mobile: { value: '', unit: 'px' },
  };
  if (!raw || typeof raw !== 'object') return d;
  MAX_H_BREAKPOINTS.forEach((k) => {
    if (raw[k] && typeof raw[k] === 'object') {
      const u = raw[k].unit;
      d[k] = {
        value: raw[k].value != null && raw[k].value !== '' ? String(raw[k].value).trim() : '',
        unit: u === 'em' || u === '%' ? u : 'px',
      };
    }
  });
  return d;
}

/** Matches ce_pd_axis_y_format_example_value() in PHP and axisYPrefix/Suffix in init.js. */
export function cePdAxisYFormatExample(axisY) {
  const a = axisY || {};
  const hasNew = a.unitPrefix != null || a.unitSuffix != null;
  let prefix; let suffix;
  if (hasNew) {
    prefix = String(a.unitPrefix ?? '');
    suffix = a.unitSuffix != null ? String(a.unitSuffix) : '%';
  } else {
    const unit = String(a.unit ?? '%');
    const before = a.unitPosition === 'before';
    prefix = before ? unit : '';
    suffix = before ? '' : unit;
  }
  return prefix + '42' + suffix;
}

/**
 * Editor-spezifischer Wrapper um die shared-Sort-Helper:
 * Liefert Items `{ bar, originalIndex }`, damit die UI nach Umsortierung
 * weiß, in welcher Reihenfolge sie die Original-bars-Array ansprechen soll.
 */
export function sortBarsWithIndices(bars, sortOrder, layout) {
  if (!bars || bars.length === 0) return [];
  const indexed = bars.map((bar, originalIndex) => ({ bar, originalIndex }));
  if (layout === 'stacked') {
    return sortGroupedBarRowsWithIndices(indexed, sortOrder);
  }
  if (!sortOrder || sortOrder === 'custom') return indexed;
  indexed.sort((A, B) => {
    const a = A.bar; const b = B.bar;
    if (sortOrder === 'value_asc') return (Number(a.value) || 0) - (Number(b.value) || 0);
    if (sortOrder === 'value_desc') return (Number(b.value) || 0) - (Number(a.value) || 0);
    if (sortOrder === 'headline_asc') return String(a.headline || '').localeCompare(String(b.headline || ''), undefined, { sensitivity: 'base' });
    return 0;
  });
  return indexed;
}
