/**
 * Locale-aware number formatting for chart ticks, tooltips, and labels (Intl.NumberFormat).
 * WordPress passes `numberLocale` as BCP 47 (e.g. de-DE); underscore locales are normalized.
 */
import { stripLeadingAxisUnitWhitespace } from './config.js';

/**
 * @param {unknown} raw
 * @returns {string}
 */
export function normalizeLocaleTag(raw) {
  if (raw == null || String(raw).trim() === '') return 'en-US';
  return String(raw).trim().replace(/_/g, '-');
}

let _fallbackFormatter = null;

/**
 * @returns {{ formatTick: (val: unknown) => string, localeTag: string }}
 */
export function getFallbackChartNumberFormatter() {
  if (!_fallbackFormatter) _fallbackFormatter = createChartNumberFormatter('en-US');
  return _fallbackFormatter;
}

/**
 * @param {unknown} localeTag  BCP 47 language tag
 * @returns {{ formatTick: (val: unknown) => string, localeTag: string }}
 */
export function createChartNumberFormatter(localeTag) {
  const tag = normalizeLocaleTag(localeTag);
  let decimalFmt;
  let scientificFmt;
  try {
    decimalFmt = new Intl.NumberFormat(tag, {
      useGrouping: true,
      minimumFractionDigits: 0,
      maximumFractionDigits: 2,
    });
    scientificFmt = new Intl.NumberFormat(tag, {
      notation: 'scientific',
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    });
  } catch (_) {
    decimalFmt = new Intl.NumberFormat('en-US', {
      useGrouping: true,
      minimumFractionDigits: 0,
      maximumFractionDigits: 2,
    });
    scientificFmt = new Intl.NumberFormat('en-US', {
      notation: 'scientific',
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    });
  }
  /**
   * @param {unknown} val
   * @returns {string}
   */
  function formatTick(val) {
    const n = Number(val);
    if (!Number.isFinite(n)) return '';
    if (Math.abs(n) >= 1e6 || (Math.abs(n) < 0.01 && n !== 0)) {
      return scientificFmt.format(n);
    }
    return decimalFmt.format(n);
  }
  return { formatTick, localeTag: tag };
}

/**
 * Row `unit` is only shown as a separate suffix when it differs from axis prefix/suffix
 * (avoids "€" twice or axis prefix + row "€" as suffix).
 *
 * @param {unknown} rowUnit
 * @param {unknown} axisPrefix
 * @param {unknown} axisSuffix
 * @returns {boolean}
 */
export function shouldFormatRowUnitSeparately(rowUnit, axisPrefix, axisSuffix) {
  const u = String(rowUnit ?? '').trim();
  if (u === '') return false;
  const p = String(axisPrefix ?? '').trim();
  const s = stripLeadingAxisUnitWhitespace(String(axisSuffix ?? ''));
  if (p && u === p) return false;
  if (s && u === s) return false;
  return true;
}
