/* Compact GOA / CUR:amount display using SI-style alt units (kGOA, MGOA, …).
 * Large values → "1.23 MGOA" (title = full GOA:n) so landing tiles fit.
 */
(function (global) {
  "use strict";

  var DEFAULT_ALT = {
    "24": "YGOA",
    "21": "ZGOA",
    "18": "EGOA",
    "15": "PGOA",
    "12": "TGOA",
    "9": "GGOA",
    "6": "MGOA",
    "3": "kGOA",
    "0": "GOA",
    "-1": "dGOA",
    "-2": "cGOA",
    "-3": "mGOA",
    "-6": "µGOA",
    "-7": "dµGOA",
    "-8": "aGOA"
  };

  var LONG_TO_COMPACT = {
    "yotta-goa": "YGOA",
    "zetta-goa": "ZGOA",
    "exa-goa": "EGOA",
    "peta-goa": "PGOA",
    "tera-goa": "TGOA",
    "giga-goa": "GGOA",
    "mega-goa": "MGOA",
    "kilo-goa": "kGOA",
    "goa": "GOA",
    "deci-goa": "dGOA",
    "centi-goa": "cGOA",
    "milli-goa": "mGOA",
    "micro-goa": "µGOA",
    "deci-micro-goa": "dµGOA",
    "atomic-goa": "aGOA"
  };

  var THRESHOLD = 1000;

  function compactAlt(altMap) {
    var out = {};
    var src = altMap || DEFAULT_ALT;
    Object.keys(DEFAULT_ALT).forEach(function (k) {
      out[k] = DEFAULT_ALT[k];
    });
    Object.keys(src).forEach(function (k) {
      var name = String(src[k] || "").trim();
      var low = name.toLowerCase().replace(/\s+/g, "");
      if (LONG_TO_COMPACT[low]) out[k] = LONG_TO_COMPACT[low];
      else if (DEFAULT_ALT[k] && /goa/i.test(name)) out[k] = DEFAULT_ALT[k];
      else out[k] = name || DEFAULT_ALT[k] || name;
    });
    return out;
  }

  function parseAmount(s) {
    if (s == null || s === "") return { cur: "GOA", val: 0 };
    if (typeof s === "number") return { cur: "GOA", val: s };
    var t = String(s).trim();
    var i = t.indexOf(":");
    if (i < 0) return { cur: "GOA", val: parseFloat(t) || 0 };
    return {
      cur: t.slice(0, i) || "GOA",
      val: parseFloat(t.slice(i + 1)) || 0
    };
  }

  function fmtCoeff(v) {
    if (!isFinite(v)) return "?";
    var a = Math.abs(v);
    if (Math.abs(a - Math.round(a)) < 1e-9) return String(Math.round(v));
    var s = v.toFixed(4).replace(/\.?0+$/, "");
    return s;
  }

  function baseStr(cur, val) {
    if (!isFinite(val)) return String(cur) + ":?";
    if (Math.abs(val - Math.round(val)) < 1e-9) return cur + ":" + Math.round(val);
    return cur + ":" + String(val).replace(/(\.\d*?[1-9])0+$/, "$1").replace(/\.0+$/, "");
  }

  /**
   * @param {string|number|object} amount
   * @param {object} [altMap]
   * @returns {{ display: string, title: string, raw: string, usedAlt: boolean }}
   */
  function format(amount, altMap) {
    if (amount == null || amount === "") {
      return { display: "—", title: "", raw: "", usedAlt: false };
    }
    // Prefer re-format from canonical amount (keeps kGOA even if server sent Kilo-GOA)
    if (typeof amount === "object" && amount) {
      if (amount.amount) {
        return format(amount.amount, altMap);
      }
      amount = amount.amount_full || amount.amount_alt || "";
    }

    var alt = compactAlt(altMap || global.__GOA_ALT_UNITS || DEFAULT_ALT);
    var p = parseAmount(amount);
    var raw = baseStr(p.cur, p.val);
    var baseName = (alt && alt["0"]) || p.cur;
    var curU = String(p.cur || "").toUpperCase();
    var baseU = String(baseName || "").toUpperCase();
    if (curU && curU !== "GOA" && (baseU === "GOA" || baseU.indexOf("GOA") !== -1)) {
      return { display: raw, title: raw, raw: raw, usedAlt: false };
    }
    if (p.val === 0) {
      return { display: raw, title: raw, raw: raw, usedAlt: false };
    }
    if (Math.abs(p.val) < THRESHOLD) {
      return { display: raw, title: raw, raw: raw, usedAlt: false };
    }

    var scales = [];
    Object.keys(alt || {}).forEach(function (k) {
      var n = parseInt(k, 10);
      if (!isNaN(n)) scales.push({ sc: n, name: String(alt[k]) });
    });
    scales.sort(function (a, b) {
      return b.sc - a.sc;
    });

    var abs = Math.abs(p.val);
    var chosen = null;
    for (var i = 0; i < scales.length; i++) {
      var unit = Math.pow(10, scales[i].sc);
      if (!(unit > 0)) continue;
      var coeff = abs / unit;
      if (coeff >= 1) {
        chosen = {
          sc: scales[i].sc,
          name: scales[i].name,
          coeff: p.val >= 0 ? coeff : -coeff
        };
        break;
      }
    }
    if (!chosen || chosen.sc === 0) {
      return { display: raw, title: raw, raw: raw, usedAlt: false };
    }
    var short = fmtCoeff(chosen.coeff) + " " + chosen.name;
    return {
      display: short,
      title: short + " (" + raw + ")",
      raw: raw,
      usedAlt: true
    };
  }

  function setText(el, amount, altMap) {
    if (!el) return;
    var f = format(amount, altMap);
    el.textContent = f.display;
    if (f.title && f.title !== f.display) el.setAttribute("title", f.title);
    else el.removeAttribute("title");
  }

  function setById(id, amount, altMap) {
    setText(document.getElementById(id), amount, altMap);
  }

  /** Prefer formatting from amount field; fall back to amount_alt string. */
  function pick(rowOrAmount, altMap) {
    if (rowOrAmount && typeof rowOrAmount === "object") {
      var a =
        rowOrAmount.amount ||
        rowOrAmount.total_amount ||
        rowOrAmount.amount_paid_sum ||
        rowOrAmount.amount_sum;
      if (a) return format(a, altMap);
      if (rowOrAmount.amount_alt) {
        return {
          display: String(rowOrAmount.amount_alt),
          title: String(rowOrAmount.amount_full || rowOrAmount.amount_alt),
          raw: String(rowOrAmount.amount_full || rowOrAmount.amount_alt),
          usedAlt: true
        };
      }
      return format("", altMap);
    }
    return format(rowOrAmount, altMap);
  }

  function rememberAlt(stats) {
    if (stats && stats.alt_unit_names && typeof stats.alt_unit_names === "object") {
      global.__GOA_ALT_UNITS = compactAlt(stats.alt_unit_names);
    }
  }

  /** Small legend HTML (positive scales). */
  function legendHtml(stats) {
    var alt = compactAlt((stats && stats.alt_unit_names) || global.__GOA_ALT_UNITS || DEFAULT_ALT);
    var rows = [];
    Object.keys(alt)
      .map(function (k) {
        return parseInt(k, 10);
      })
      .filter(function (n) {
        return !isNaN(n) && n > 0;
      })
      .sort(function (a, b) {
        return a - b;
      })
      .forEach(function (sc) {
        rows.push(
          "<tr><td>10<sup>" +
            sc +
            "</sup></td><td><strong>" +
            alt[String(sc)] +
            "</strong></td></tr>"
        );
      });
    if (!rows.length) return "";
    return (
      '<table class="unit-legend" aria-label="GOA unit names"><thead><tr><th>×base</th><th>name</th></tr></thead><tbody>' +
      rows.join("") +
      "</tbody></table>"
    );
  }

  function fillLegend(elOrId, stats) {
    var el = typeof elOrId === "string" ? document.getElementById(elOrId) : elOrId;
    if (!el) return;
    el.innerHTML = legendHtml(stats);
  }

  global.GoaAmount = {
    format: format,
    setText: setText,
    setById: setById,
    pick: pick,
    rememberAlt: rememberAlt,
    compactAlt: compactAlt,
    legendHtml: legendHtml,
    fillLegend: fillLegend,
    DEFAULT_ALT: DEFAULT_ALT,
    THRESHOLD: THRESHOLD
  };
})(typeof window !== "undefined" ? window : globalThis);
