// @wuys/map · layers/countries.js
//
// Renders one <path data-iso="xx"> per country. The path's `d` attribute is
// computed by the renderer's `pathForCountry(iso)` (which handles projection,
// antimeridian split, horizon clipping). Country fill is the theme fallback —
// the flag layer renders flag images on top, clipped to these same paths.

const SVG_NS = "http://www.w3.org/2000/svg";

export default function createCountriesLayer(opts = {}) {
  const id = opts.id || "countries";
  /** Map<iso, SVGPathElement> */
  const els = new Map();
  let group = null;
  let api = null;

  function build(ctx) {
    const { svg, state } = ctx;
    group = document.createElementNS(SVG_NS, "g");
    group.setAttribute("id", "layer-" + id);
    svg.appendChild(group);
    for (const iso of state.data.countries.keys()) {
      const p = document.createElementNS(SVG_NS, "path");
      p.setAttribute("data-iso", iso);
      p.setAttribute("data-name", state.data.countries.get(iso).name || iso);
      p.setAttribute("d", "M0,0");
      p.setAttribute("display", "none");
      group.appendChild(p);
      els.set(iso, p);
    }
    applyTheme(ctx);
  }

  function patch(ctx) {
    const { state, pathForCountry, isVisibleAt } = ctx;
    for (const [iso, el] of els) {
      if (!isVisibleAt(iso)) { el.setAttribute("display", "none"); continue; }
      const d = pathForCountry(iso);
      if (!d) { el.setAttribute("display", "none"); continue; }
      el.removeAttribute("display");
      el.setAttribute("d", d);
    }
  }

  function applyTheme(ctx) {
    if (!group) return;
    const theme = ctx.theme;
    const c = theme.countries;
    group.style.setProperty("--country-stroke", c.stroke);
    group.style.setProperty("--country-stroke-width", c.strokeWidth);
    for (const [iso, el] of els) {
      el.setAttribute("fill", c.fillFallback || "#1f1430");
      el.setAttribute("stroke", c.stroke);
      el.setAttribute("stroke-width", c.strokeWidth);
      el.setAttribute("vector-effect", "non-scaling-stroke");
    }
  }

  function setFill(iso, fill) {
    const el = els.get(iso);
    if (el) el.setAttribute("fill", fill);
  }

  function destroy() {
    if (group && group.parentNode) group.parentNode.removeChild(group);
    els.clear();
    group = null;
  }

  api = { id, build, patch, applyTheme, setFill, destroy, getElement: (iso) => els.get(iso) };
  return api;
}
