// @wuys/map · data/labels-convert.js
//
// Convert legacy-format label nudges (relative lon/lat + viewBox fontSize) into
// the canonical schema the renderer consumes:
//
//   canonical = { lon: ABSOLUTE, lat: ABSOLUTE, sizeRatio: number, rotate?: number }
//
// `sizeRatio` is the label height as a fraction of the country's PROJECTED
// height — view-agnostic. We derive it from legacy fontSize using the
// flat-projection ratio (`latRange × 5.555` viewBox units per degree at equator).
// That keeps hand-tuned legacy labels at the same visual size after migration.
//
// The function also accepts canonical entries (entries with `sizeRatio` set)
// and passes them through unchanged.

const VBOX_UNITS_PER_DEG = 5.555;       // EE flat projection: latRange × this = projected height

/**
 * @param {Record<string, {lon?:number, lat?:number, fontSize?:number, sizeRatio?:number, rotate?:number}>} offsets
 * @param {Map<string, {lon:number, lat:number, latRange:number}>} countriesMeta
 * @returns {Map<string, {lon:number, lat:number, sizeRatio?:number, rotate?:number}>}
 */
export function applyLabelOffsets(offsets, countriesMeta) {
  const out = new Map();
  if (!offsets) return out;
  for (const iso of Object.keys(offsets)) {
    const o = offsets[iso] || {};
    const cm = countriesMeta.get(iso);
    // Centroid: from country meta if available, otherwise (0,0) — caller can
    // also provide a fallback by setting the offset to absolute coords.
    const baseLon = cm ? cm.lon : (o.lon ?? 0);
    const baseLat = cm ? cm.lat : (o.lat ?? 0);
    const lon = cm ? baseLon + (o.lon || 0) : (o.lon ?? baseLon);
    const lat = cm ? baseLat + (o.lat || 0) : (o.lat ?? baseLat);

    let sizeRatio = o.sizeRatio;
    if (!sizeRatio && o.fontSize && cm) {
      // Precise inverse: sizeRatio × projectedHeight = fontSize, projectedHeight = latRange × 5.555.
      const projH = (cm.latRange || 30) * VBOX_UNITS_PER_DEG;
      sizeRatio = projH > 0 ? Math.max(0.04, Math.min(0.5, o.fontSize / projH)) : undefined;
    } else if (!sizeRatio && o.fontSize) {
      // No country meta — fall back to legacy 1/25 ratio used in geo.js migration.
      sizeRatio = Math.max(0.05, Math.min(0.5, o.fontSize / 25));
    }

    out.set(iso, {
      lon, lat,
      sizeRatio,
      rotate: o.rotate || 0,
    });
  }
  return out;
}
