// @wuys/map · layers/atmosphere.js
//
// Globe-only premium overlay:
//   • A soft outer glow around the planet (atmosphere scattering)
//   • A subtle inner shadow (terminator + day/night)
//   • Optional sun position (for day/night terminator math)
//
// All three are pure SVG primitives (radialGradient + circle) so they stay
// crisp on retina, scale with zoom, and cost ~3 DOM nodes total.

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

export default function createAtmosphereLayer(opts = {}) {
  let defs = null, group = null;
  let glow = null, shade = null;
  let gradGlow = null, gradShade = null;
  const _id = "wuys-atm-" + Math.random().toString(36).slice(2, 8);

  function build(ctx) {
    const { svg, state, theme } = ctx;
    defs = svg.querySelector("defs");
    if (!defs) {
      defs = document.createElementNS(SVG_NS, "defs");
      svg.insertBefore(defs, svg.firstChild);
    }

    // Atmosphere glow gradient — bright at the rim, transparent outside.
    gradGlow = document.createElementNS(SVG_NS, "radialGradient");
    gradGlow.setAttribute("id", _id + "-glow");
    appendStops(gradGlow, [
      ["80%",  "rgba(0,0,0,0)"],
      ["93%",  theme.globe?.atmosphere?.color || "rgba(110,180,255,0.4)"],
      ["100%", "rgba(0,0,0,0)"],
    ]);
    defs.appendChild(gradGlow);

    // Day/night shading gradient — radial, offset toward "sun".
    gradShade = document.createElementNS(SVG_NS, "radialGradient");
    gradShade.setAttribute("id", _id + "-shade");
    appendStops(gradShade, [
      ["0%",   "rgba(255,255,255,0)"],
      ["55%",  "rgba(0,0,0,0)"],
      ["100%", "rgba(0,0,0,0.55)"],
    ]);
    defs.appendChild(gradShade);

    group = document.createElementNS(SVG_NS, "g");
    group.setAttribute("id", "layer-atmosphere");
    group.setAttribute("pointer-events", "none");
    svg.appendChild(group);

    glow = document.createElementNS(SVG_NS, "circle");
    glow.setAttribute("cx", "1000");
    glow.setAttribute("cy", "500");
    glow.setAttribute("r", "0");
    glow.setAttribute("fill", "url(#" + _id + "-glow)");
    glow.setAttribute("display", "none");
    group.appendChild(glow);

    shade = document.createElementNS(SVG_NS, "circle");
    shade.setAttribute("cx", "1000");
    shade.setAttribute("cy", "500");
    shade.setAttribute("r", "0");
    shade.setAttribute("fill", "url(#" + _id + "-shade)");
    shade.setAttribute("display", "none");
    group.appendChild(shade);
  }

  function patch(ctx) {
    const { state, mode } = ctx;
    if (mode !== "globe") {
      glow.setAttribute("display", "none");
      shade.setAttribute("display", "none");
      return;
    }
    const baseR = 450 * state.nav.zoom;
    // Glow extends ~12% past the planet edge.
    const glowR = baseR * 1.16;
    glow.removeAttribute("display");
    glow.setAttribute("r", glowR.toFixed(2));
    shade.removeAttribute("display");
    shade.setAttribute("r", baseR.toFixed(2));

    // Offset the shade gradient toward "sun" — we use the camera-back orientation
    // (so the day side is what the user looks at) but with a soft top-left bias
    // for cinematic feel. Hook this up to a real solar position later.
    const sunDx = -baseR * 0.35, sunDy = -baseR * 0.35;
    const cx = 1000 + sunDx, cy = 500 + sunDy;
    gradShade.setAttribute("cx", cx);
    gradShade.setAttribute("cy", cy);
    gradShade.setAttribute("fx", cx);
    gradShade.setAttribute("fy", cy);
    gradShade.setAttribute("r", baseR.toFixed(2));
    gradShade.setAttribute("gradientUnits", "userSpaceOnUse");

    gradGlow.setAttribute("cx", "1000");
    gradGlow.setAttribute("cy", "500");
    gradGlow.setAttribute("r", glowR.toFixed(2));
    gradGlow.setAttribute("gradientUnits", "userSpaceOnUse");
  }

  function applyTheme(ctx) {
    if (!gradGlow) return;
    const col = ctx.theme.globe?.atmosphere?.color || "rgba(110,180,255,0.4)";
    while (gradGlow.firstChild) gradGlow.removeChild(gradGlow.firstChild);
    appendStops(gradGlow, [
      ["80%",  "rgba(0,0,0,0)"],
      ["93%",  col],
      ["100%", "rgba(0,0,0,0)"],
    ]);
  }

  function appendStops(grad, stops) {
    for (const [offset, color] of stops) {
      const stop = document.createElementNS(SVG_NS, "stop");
      stop.setAttribute("offset", offset);
      stop.setAttribute("stop-color", color);
      grad.appendChild(stop);
    }
  }

  function destroy() {
    if (group && group.parentNode) group.parentNode.removeChild(group);
    if (gradGlow && gradGlow.parentNode) gradGlow.parentNode.removeChild(gradGlow);
    if (gradShade && gradShade.parentNode) gradShade.parentNode.removeChild(gradShade);
    group = null; glow = null; shade = null;
  }

  return { id: "atmosphere", build, patch, applyTheme, destroy };
}
