/* ATLAS — homepage map view. A Google-Earth-style interactive map of UltraTech's
   49 cement plants across India, rendered in the LatSpace design language.

   Ported from the Claude Design prototype (Atlas.dc.html). Pan/zoom India map with
   square teal markers (IU = integrated, GU = grinding), hover tooltips, click-to-fly,
   a basemap-style toggle (Graticule / Outline / Dot grid — Outline is the default).

   Country geometry (d3 + world-atlas) loads from a CDN at runtime, so first load needs
   a connection. d3 + topojson-client are loaded as globals in index.html. */
(function () {
  "use strict";
  const { useState, useRef, useEffect } = React;
  const h = React.createElement;
  const FONT_MONO = "var(--font-mono)";

  const COLORS = { IU: "#074D47", GU: "#22867C" };
  const colorOf = (d) => COLORS[d.type] || "#22867C";

  // Map markers that correspond to the three plants modelled in the workspace.
  // The atlas `unit` field carries the same plant identity as the workspace fullName,
  // so clicking one of these markers opens that plant's full interactive site view.
  function workspacePlantIdFor(d) {
    if (!window.ATLAS_PLANTS) return null;
    const unit = String(d.unit || "").trim().toLowerCase();
    const hit = ATLAS_PLANTS.list.find(
      (p) => String(p.fullName || "").trim().toLowerCase() === unit
    );
    return hit ? hit.id : null;
  }

  // ---- Map / Network view toggle ------------------------------------------
  // A shared segmented control used both in the Atlas map header and the
  // workspace app bar, so the two top-level views are switchable from either side.
  function ViewToggle({ active, onMap, onNetwork }) {
    const seg = (label, isOn, onClick) => h("button", {
      type: "button",
      onClick: isOn ? undefined : onClick,
      style: {
        padding: "11px 20px", fontFamily: FONT_MONO, fontSize: 12, fontWeight: 600,
        letterSpacing: "0.1em", textTransform: "uppercase",
        cursor: isOn ? "default" : "pointer", border: "none",
        background: isOn ? "#074D47" : "#fff",
        color: isOn ? "#fff" : "#4B5563",
        transition: "background 200ms, color 200ms",
      },
    }, label);
    return h("div", {
      role: "tablist", "aria-label": "Switch view",
      style: { display: "inline-flex", border: "1px solid #E5E7EB", background: "#fff" },
    },
      seg("Map", active === "map", onMap),
      h("span", { style: { width: 1, background: "#E5E7EB", alignSelf: "stretch" } }),
      seg("Grid", active === "network", onNetwork),
    );
  }

  // ---- Zoom / reset controls (bottom-right) -------------------------------
  function ZoomControls({ onZoomIn, onZoomOut, onReset }) {
    const btn = {
      width: 44, height: 44, border: "none", background: "#fff", cursor: "pointer",
      display: "flex", alignItems: "center", justifyContent: "center",
      transition: "background 200ms",
    };
    const glyph = Object.assign({}, btn, {
      borderBottom: "1px solid #E5E7EB",
      fontFamily: FONT_MONO, fontSize: 22, color: "#074D47",
    });
    return h("div", {
      style: {
        position: "absolute", bottom: 24, right: 24, zIndex: 20,
        display: "flex", flexDirection: "column",
        border: "1px solid #E5E7EB", background: "#fff",
      },
    },
      h("button", { className: "atlas-ctl", type: "button", title: "Zoom in", onClick: onZoomIn, style: glyph }, "+"),
      h("button", { className: "atlas-ctl", type: "button", title: "Zoom out", onClick: onZoomOut, style: glyph }, "−"),
      h("button", { className: "atlas-ctl", type: "button", title: "Reset view", onClick: onReset, style: btn },
        h("svg", { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: "#074D47", strokeWidth: 1.6 },
          h("path", { d: "M3 8V3h5M21 8V3h-5M3 16v5h5M21 16v5h-5", strokeLinecap: "square" }),
        ),
      ),
    );
  }

  // ---- Title / legend overlay (top-left) ----------------------------------
  function Overlay() {
    const legendRow = (color, label) => h("div", {
      style: { display: "flex", alignItems: "center", gap: 11 },
    },
      h("span", { style: { width: 11, height: 11, background: color, boxShadow: `0 0 0 1.5px #fff, 0 0 0 2.5px ${color}` } }),
      h("span", { style: { fontSize: 13, color: "#111" } }, label),
    );
    return h("div", {
      style: {
        position: "absolute", top: 24, left: 24, zIndex: 20,
        display: "flex", flexDirection: "column", gap: 16, maxWidth: 330, pointerEvents: "none",
      },
    },
      h("div", {
        style: {
          display: "inline-flex", flexDirection: "column", gap: 11, background: "#fff",
          border: "1px solid #E5E7EB", padding: "14px 16px", alignSelf: "flex-start",
        },
      },
        h("div", { style: { fontFamily: FONT_MONO, fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase", color: "#6B7280" } }, "Unit Type"),
        legendRow("#074D47", "Integrated Unit (IU)"),
        legendRow("#22867C", "Grinding Unit (GU)"),
      ),
    );
  }

  function AtlasMap({
    onEnterApp, onShowNetwork, onOpenPlant,
    plants, model, agentCollapsed, onAgentCollapsedChange, agentWide, onAgentWideChange,
  }) {
    const [loading, setLoading] = useState(true);

    const mapRef = useRef(null);
    const svgRef = useRef(null);
    const tooltipRef = useRef(null);

    // mutable engine state kept on a ref so D3 callbacks read live values without re-render
    const eng = useRef({}).current;
    // keep the live open-plant callback on the ref so D3 click handlers never go stale
    eng.onOpenPlant = onOpenPlant;

    const waitFor = (cond) => new Promise((res) => {
      const tick = () => { if (cond()) return res(); setTimeout(tick, 30); };
      tick();
    });

    // ---- tooltip --------------------------------------------------------
    const showTip = (e, d) => {
      const tip = tooltipRef.current;
      if (!tip) return;
      const typeLabel = d.type === "IU" ? "Integrated Unit" : "Grinding Unit";
      const linked = !!workspacePlantIdFor(d);
      tip.innerHTML =
        `<div style="font-family:'IBM Plex Mono',monospace;font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:#89E4DA;margin-bottom:6px;">${d.type} &middot; ${typeLabel}</div>` +
        `<div style="font-size:14px;font-weight:600;line-height:1.3;margin-bottom:6px;">${d.name}</div>` +
        `<div style="font-size:12px;color:#D1D5DB;margin-bottom:9px;">${d.location}</div>` +
        `<div style="font-family:'IBM Plex Mono',monospace;font-size:11px;color:#89E4DA;letter-spacing:0.02em;">${d.lat.toFixed(4)}, ${d.lng.toFixed(4)}</div>` +
        (linked
          ? `<div style="margin-top:9px;padding-top:8px;border-top:1px solid rgba(137,228,218,0.3);font-family:'IBM Plex Mono',monospace;font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:#fff;">Click to open plant &#9656;</div>`
          : "");
      tip.style.opacity = "1";
      moveTip(e);
    };
    const moveTip = (e) => {
      const container = mapRef.current;
      const tip = tooltipRef.current;
      if (!container || !tip) return;
      const [x, y] = eng.d3.pointer(e, container);
      const tw = tip.offsetWidth, th = tip.offsetHeight;
      let left = x + 18, top = y + 18;
      if (left + tw > container.clientWidth - 12) left = x - tw - 18;
      if (top + th > container.clientHeight - 12) top = y - th - 18;
      tip.style.left = left + "px";
      tip.style.top = top + "px";
    };
    const hideTip = () => { const tip = tooltipRef.current; if (tip) tip.style.opacity = "0"; };

    // ---- basemap styling (Outline is the only treatment) ----------------
    const applyBasemap = () => {
      if (!eng.g) return;
      eng.g.select(".grat").attr("stroke", "#F3F4F6").attr("opacity", 1);
      eng.g.select(".neighbors").attr("opacity", 1).attr("stroke", "#D1D5DB");
      eng.g.select(".india").attr("opacity", 1).attr("stroke", "#074D47").attr("stroke-width", 2);
    };

    // ---- fly / zoom controls -------------------------------------------
    const flyTo = (d) => {
      const d3 = eng.d3, k = 12;
      const p = eng.projection([d.lng, d.lat]);
      const t = d3.zoomIdentity.translate(eng.w / 2 - k * p[0], eng.h / 2 - k * p[1]).scale(k);
      eng.svgSel.transition().duration(800).call(eng.zoom.transform, t);
    };
    const zoomIn = () => { if (eng.svgSel) eng.svgSel.transition().duration(300).call(eng.zoom.scaleBy, 1.6); };
    const zoomOut = () => { if (eng.svgSel) eng.svgSel.transition().duration(300).call(eng.zoom.scaleBy, 1 / 1.6); };
    const resetView = () => { if (eng.svgSel) eng.svgSel.transition().duration(650).call(eng.zoom.transform, eng.d3.zoomIdentity); };

    // ---- main map render -------------------------------------------------
    const renderMap = () => {
      const d3 = eng.d3;
      const container = mapRef.current;
      if (!container) return;
      const w = container.clientWidth || 1200;
      const h2 = container.clientHeight || 700;
      eng.w = w; eng.h = h2;

      const proj = d3.geoMercator().fitExtent([[64, 64], [w - 64, h2 - 64]], eng.india);
      eng.projection = proj;
      const path = d3.geoPath(proj);

      const svg = d3.select(svgRef.current).attr("viewBox", `0 0 ${w} ${h2}`);
      svg.selectAll("*").remove();

      const g = svg.append("g");
      eng.g = g;

      g.append("path").attr("class", "grat")
        .datum(d3.geoGraticule().step([5, 5])())
        .attr("d", path).attr("fill", "none").attr("stroke", "#E5E7EB")
        .attr("stroke-width", 0.8).attr("vector-effect", "non-scaling-stroke");

      g.append("g").attr("class", "neighbors").attr("opacity", 0)
        .selectAll("path").data(eng.countries.features).join("path")
        .attr("d", path).attr("fill", "none").attr("stroke", "#D1D5DB")
        .attr("stroke-width", 0.8).attr("vector-effect", "non-scaling-stroke");

      g.append("path").attr("class", "india").datum(eng.india)
        .attr("d", path).attr("fill", "none").attr("stroke", "#074D47")
        .attr("stroke-width", 1.5).attr("vector-effect", "non-scaling-stroke");

      const m = g.append("g").attr("class", "pins")
        .selectAll("g").data(eng.plants).join("g")
        .attr("transform", (d) => `translate(${proj([d.lng, d.lat])})`)
        .style("cursor", "pointer");
      m.append("rect").attr("class", "halo")
        .attr("x", -8).attr("y", -8).attr("width", 16).attr("height", 16)
        .attr("fill", "none").attr("stroke", (d) => colorOf(d))
        .attr("stroke-width", 1).attr("opacity", 0);
      // Markers linked to a modelled workspace plant get a persistent ring so the user
      // can tell which sites open into the full interactive explorer.
      m.filter((d) => !!workspacePlantIdFor(d)).append("rect").attr("class", "link-ring")
        .attr("x", -8.5).attr("y", -8.5).attr("width", 17).attr("height", 17)
        .attr("fill", "none").attr("stroke", (d) => colorOf(d))
        .attr("stroke-width", 1).attr("stroke-dasharray", "2.5 2").attr("opacity", 0.7);
      m.append("rect").attr("class", "core")
        .attr("x", -4.5).attr("y", -4.5).attr("width", 9).attr("height", 9)
        .attr("fill", (d) => colorOf(d)).attr("stroke", "#fff").attr("stroke-width", 1.5);

      m.on("mouseenter", function (e, d) {
        d3.select(this).raise().select(".halo").transition().duration(150)
          .attr("opacity", 0.9).attr("x", -11).attr("y", -11).attr("width", 22).attr("height", 22);
        showTip(e, d);
      }).on("mousemove", function (e) {
        moveTip(e);
      }).on("mouseleave", function () {
        d3.select(this).select(".halo").transition().duration(200)
          .attr("opacity", 0).attr("x", -8).attr("y", -8).attr("width", 16).attr("height", 16);
        hideTip();
      }).on("click", function (e, d) {
        const pid = workspacePlantIdFor(d);
        if (pid && eng.onOpenPlant) { hideTip(); eng.onOpenPlant(pid); return; }
        flyTo(d);
      });

      const zoom = d3.zoom().scaleExtent([1, 48]).on("zoom", (e) => {
        const t = e.transform;
        g.attr("transform", t);
        m.attr("transform", (d) => `translate(${proj([d.lng, d.lat])}) scale(${1 / t.k})`);
      });
      eng.zoom = zoom;
      eng.svgSel = svg;
      svg.call(zoom).on("dblclick.zoom", null);
      svg.call(zoom.transform, d3.zoomIdentity);

      applyBasemap();
    };

    // ---- lifecycle ------------------------------------------------------
    useEffect(() => {
      let cancelled = false;
      const onResize = () => {
        clearTimeout(eng._rt);
        eng._rt = setTimeout(() => { if (eng.india) renderMap(); }, 200);
      };
      (async () => {
        await waitFor(() => window.d3 && window.topojson);
        if (cancelled) return;
        eng.d3 = window.d3;
        try {
          const [plants, world] = await Promise.all([
            fetch("assets/atlas-plants.json").then((r) => r.json()),
            fetch("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-50m.json").then((r) => r.json()),
          ]);
          if (cancelled) return;
          const topojson = window.topojson;
          eng.countries = topojson.feature(world, world.objects.countries);
          eng.india = eng.countries.features.find((f) => String(f.id) === "356")
            || eng.countries.features.find((f) => f.properties && f.properties.name === "India");
          eng.plants = plants;
          renderMap();
          setLoading(false);
          window.addEventListener("resize", onResize);
        } catch (err) {
          console.error("Atlas init failed", err);
          setLoading(false);
        }
      })();
      return () => { cancelled = true; window.removeEventListener("resize", onResize); clearTimeout(eng._rt); };
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return h("div", {
      style: {
        height: "100vh", display: "flex", flexDirection: "column", background: "#fff",
        fontFamily: "'IBM Plex Sans', system-ui, sans-serif", overflow: "hidden", color: "#000",
      },
    },
      // ---- top bar: identical chrome to the grid view ----
      window.AtlasAppBar && h(window.AtlasAppBar, {
        active: "map",
        onMap: () => {},
        onNetwork: onShowNetwork || onEnterApp,
        onBrandClick: () => {},
      }),

      // ---- body: map stage + network analyst rail ----
      h("div", { style: { flex: 1, minHeight: 0, display: "flex", flexDirection: "row" } },
        // map stage
        h("div", { ref: mapRef, style: { position: "relative", flex: 1, minWidth: 0, overflow: "hidden", background: "#fff" } },
          h("svg", {
            ref: svgRef, className: "atlas-svg",
            style: { position: "absolute", inset: 0, width: "100%", height: "100%", display: "block", cursor: "grab", touchAction: "none" },
          }),
          h(Overlay),

          h(ZoomControls, { onZoomIn: zoomIn, onZoomOut: zoomOut, onReset: resetView }),

          // tooltip
          h("div", {
            ref: tooltipRef,
            style: {
              position: "absolute", top: 0, left: 0, zIndex: 40, pointerEvents: "none", opacity: 0,
              transition: "opacity 120ms ease", background: "#074D47", color: "#fff",
              padding: "11px 13px", maxWidth: 250, border: "1px solid #074D47",
              boxShadow: "0 12px 28px rgba(7,77,71,0.18)",
            },
          }),

          // loading veil
          loading && h("div", {
            style: {
              position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
              background: "#fff", zIndex: 50,
            },
          },
            h("span", { style: { fontFamily: FONT_MONO, fontSize: 12, letterSpacing: "0.16em", textTransform: "uppercase", color: "#22867C" } }, "Loading map…"),
          ),
        ),

        // cross-plant Network Analyst — same component the Grid view uses, docked here too
        window.NetworkAgentPanel && h("div", {
          className: "atlas-agent-host" + (agentCollapsed ? " collapsed" : agentWide ? " wide" : ""),
        },
          h(window.NetworkAgentPanel, {
            plants: plants || [],
            model,
            collapsed: !!agentCollapsed,
            onCollapsedChange: onAgentCollapsedChange || (() => {}),
            wide: !!agentWide,
            onWideChange: onAgentWideChange || (() => {}),
          }),
        ),
      ),
    );
  }

  const LOGO = '<svg viewBox="0 0 460 460" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0,460) scale(0.1,-0.1)" fill="#000"><path d="M1830 4159 c-769 -99 -1413 -650 -1619 -1384 -38 -137 -59 -254 -72 -415 -10 -119 -4 -300 10 -300 7 1 101 153 114 185 5 11 17 85 28 165 38 287 80 432 181 632 201 396 530 698 935 859 212 84 462 124 723 116 265 -9 490 -66 722 -182 291 -145 558 -391 727 -670 128 -211 228 -511 248 -741 5 -62 3 -74 -9 -74 -26 0 -180 103 -355 236 -233 178 -368 266 -508 334 -245 118 -337 140 -589 140 -162 0 -201 -3 -265 -21 -144 -40 -312 -132 -436 -237 -58 -50 -185 -188 -185 -202 0 -4 30 -10 68 -14 194 -20 360 -66 767 -216 304 -111 436 -152 601 -184 157 -30 190 -41 175 -60 -18 -22 -92 -39 -164 -38 -122 2 -279 49 -615 183 -383 153 -529 197 -724 218 -54 6 -104 11 -113 11 -11 0 -15 11 -15 41 l0 42 -114 -7 c-241 -14 -499 -83 -656 -173 -178 -103 -327 -282 -393 -471 -28 -80 -30 -98 -31 -222 0 -121 3 -143 28 -215 82 -237 312 -550 545 -737 233 -188 544 -337 841 -403 98 -22 508 -32 641 -16 215 25 490 120 694 239 395 230 664 546 855 1005 32 77 33 78 134 149 175 124 317 234 425 330 l104 93 -129 7 c-130 7 -237 29 -365 77 l-56 21 -6 128 c-11 275 -122 617 -284 874 -274 436 -690 732 -1211 862 -164 41 -476 58 -652 35z m-349 -1741 c49 -165 149 -318 315 -478 227 -220 451 -358 735 -454 174 -59 273 -71 529 -63 217 6 282 19 499 97 63 22 121 39 129 38 11 -2 0 -31 -43 -113 -202 -388 -504 -666 -908 -839 -464 -198 -1021 -177 -1475 56 -341 175 -617 448 -788 778 l-39 75 0 165 0 165 37 77 c97 203 227 327 462 439 150 71 349 124 478 128 l47 1 22 -72z"></path></g></svg>';

  window.AtlasMap = AtlasMap;
  window.AtlasViewToggle = ViewToggle;
})();
