/* ATLAS — app shell. Plant overview <-> asset detail, shared live input store. */
(function () {
  "use strict";
  const { useState, useMemo, useEffect, useRef } = React;
  const h = React.createElement;
  const LS_KEY = "atlas_inputs_v1";
  const LS_MODEL = "atlas_model_v2";
  const LS_PLANT = "atlas_plant_v1";

  const cloneModel = (m) => JSON.parse(JSON.stringify(m));

  function loadModel() {
    try {
      const saved = JSON.parse(localStorage.getItem(LS_MODEL) || "null");
      if (saved && Array.isArray(saved.assets)) return saved;
    } catch (e) {}
    return cloneModel(ATLAS.DEFAULT_MODEL);
  }

  function loadInputs(model) {
    const defaults = ATLAS.defaultsFromModel(model);
    try {
      const saved = JSON.parse(localStorage.getItem(LS_KEY) || "null");
      if (saved && typeof saved === "object") return Object.assign({}, defaults, saved);
    } catch (e) {}
    return defaults;
  }

  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "accent": "#074D47",
    "calcPalette": "pink",
    "showGrid": true,
    "metricSize": "standard"
  }/*EDITMODE-END*/;

  // ---- Left side rail (global vertical nav) -------------------------------
  // Logo + collapse toggle, the primary view nav (Grid / Map / Reports / Sustainability),
  // and a footer (settings + sign-out). Present on every view, left of all content.
  function railIcon(name) {
    const svg = (children) => h("svg", { width: 20, height: 20, viewBox: "0 0 24 24", fill: "none",
      stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "square", strokeLinejoin: "miter" }, children);
    switch (name) {
      case "grid": return svg([
        h("rect", { key: "a", x: 3.5, y: 3.5, width: 7, height: 7 }),
        h("rect", { key: "b", x: 13.5, y: 3.5, width: 7, height: 7 }),
        h("rect", { key: "c", x: 3.5, y: 13.5, width: 7, height: 7 }),
        h("rect", { key: "d", x: 13.5, y: 13.5, width: 7, height: 7 }),
      ]);
      case "map": return svg([
        h("path", { key: "a", d: "M9 3.5L3.5 6v14.5L9 18l6 2.5 5.5-2.5V3.5L15 6 9 3.5z" }),
        h("path", { key: "b", d: "M9 3.5V18M15 6v14.5" }),
      ]);
      case "report": return svg([
        h("rect", { key: "a", x: 4.5, y: 3.5, width: 15, height: 17 }),
        h("path", { key: "b", d: "M8 9h8M8 12.5h8M8 16h5" }),
      ]);
      case "leaf": return svg([
        h("path", { key: "a", d: "M5 19c0-7 5-12 14-12 0 9-5 14-12 14a6 6 0 0 1-2-2z" }),
        h("path", { key: "b", d: "M8.5 15.5C11 13 14 11.5 17 11" }),
      ]);
      case "gear": return svg([
        h("circle", { key: "c", cx: 12, cy: 12, r: 3 }),
        h("path", { key: "p", strokeLinecap: "round", strokeLinejoin: "round",
          d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" }),
      ]);
      case "exit": return svg([
        h("path", { key: "a", d: "M14 4.5H6.5a1 1 0 0 0-1 1v13a1 1 0 0 0 1 1H14" }),
        h("path", { key: "b", d: "M17 8.5l3.5 3.5L17 15.5M20 12H9" }),
      ]);
      default: return null;
    }
  }

  function SideRail({ active, expanded, onToggle, onHome, items, footItems }) {
    const renderItem = (it) =>
      it.kind === "settings"
        ? h(SettingsMenu, {
            key: it.id, variant: "rail",
            onExport: it.onExport, onImportFile: it.onImportFile, onReset: it.onReset,
          })
        : h("button", {
            key: it.id, type: "button", className: "sr-item" + (it.active ? " active" : ""),
            title: it.label, "aria-label": it.label, "aria-current": it.active ? "page" : undefined,
            onClick: it.onClick,
          }, railIcon(it.icon), h("span", { className: "sr-label" }, it.label));
    return h("aside", { className: "siderail" + (expanded ? " expanded" : ""), "aria-label": "Primary navigation" },
      h("div", { className: "sr-logo", onClick: onHome, title: "Atlas home", role: "button",
        dangerouslySetInnerHTML: { __html: LOGO } }),
      h("button", { className: "sr-collapse", type: "button",
        title: expanded ? "Collapse" : "Expand", "aria-label": expanded ? "Collapse navigation" : "Expand navigation",
        "aria-expanded": expanded, onClick: onToggle },
        h("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor",
          strokeWidth: 2, strokeLinecap: "square" }, h("path", { d: "M9 6l6 6-6 6" })),
      ),
      h("nav", { className: "sr-nav" }, items.map(renderItem)),
      h("div", { className: "sr-spacer" }),
      h("div", { className: "sr-foot" }, footItems.map(renderItem)),
    );
  }
  window.AtlasSideRail = SideRail;

  // Settings menu (gear → Export / Import / Reset). Self-contained: owns the hidden
  // import file input. `variant: "rail"` renders the trigger as a side-rail item and
  // pops the menu up-and-to-the-right from the bottom-left footer.
  function SettingsMenu({ onExport, onImportFile, onReset, variant }) {
    const [open, setOpen] = useState(false);
    const wrapRef = useRef(null);
    const importRef = useRef(null);
    const rail = variant === "rail";
    useEffect(() => {
      if (!open) return;
      const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false); };
      const onEsc = (e) => { if (e.key === "Escape") setOpen(false); };
      document.addEventListener("mousedown", onDoc);
      document.addEventListener("keydown", onEsc);
      return () => { document.removeEventListener("mousedown", onDoc); document.removeEventListener("keydown", onEsc); };
    }, [open]);
    const run = (fn) => () => { setOpen(false); fn && fn(); };
    const gear = h("svg", { width: rail ? 20 : 21, height: rail ? 20 : 21, viewBox: "0 0 24 24", fill: "none",
      stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" },
      h("circle", { cx: 12, cy: 12, r: 3.2 }),
      h("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" }),
    );
    return h("div", { className: "settings-wrap" + (rail ? " settings-wrap-rail" : ""), ref: wrapRef },
      h("button", {
        className: (rail ? "sr-item" : "settings-btn") + (open ? " open active" : ""), type: "button",
        title: "Settings", "aria-label": "Settings", "aria-haspopup": "menu", "aria-expanded": open,
        onClick: () => setOpen((v) => !v),
      },
        gear,
        rail && h("span", { className: "sr-label" }, "Settings"),
      ),
      open && h("div", { className: "settings-menu" + (rail ? " settings-menu-rail" : ""), role: "menu" },
        h("div", { className: "settings-label" }, "Model"),
        h("button", { className: "settings-item", role: "menuitem", type: "button", onClick: run(onExport) },
          "Export", h("span", { className: "si-hint" }, "JSON")),
        h("button", { className: "settings-item", role: "menuitem", type: "button",
          onClick: run(() => importRef.current && importRef.current.click()) },
          "Import", h("span", { className: "si-hint" }, "JSON")),
        h("div", { className: "settings-sep" }),
        h("button", { className: "settings-item danger", role: "menuitem", type: "button", onClick: run(onReset) },
          "Reset", h("span", { className: "si-hint" }, "defaults")),
      ),
      h("input", {
        ref: importRef, type: "file", accept: "application/json,.json",
        style: { display: "none" },
        onChange: (e) => { const f = e.target.files && e.target.files[0]; if (f && onImportFile) onImportFile(f); e.target.value = ""; },
      }),
    );
  }
  window.AtlasSettingsMenu = SettingsMenu;

  // Shared top bar used by every view (map + grid) so the chrome is identical.
  // Settings (Export / Import / Reset) now lives in the bottom-left side rail.
  function AppBar({ active, onMap, onNetwork, onBrandClick }) {
    return h("header", { className: "appbar" },
      h("div", { className: "brand", onClick: onBrandClick, title: "Atlas home map" },
        h("img", { className: "brand-logo", src: "assets/utcl-logo.jpg", alt: "UltraTech" }),
        h("div", { className: "brand-txt" },
          h("span", { className: "brand-name" }, "UltraTech Cement Plants"),
          h("span", { className: "brand-sub" }, "Unified View"),
        ),
      ),
      h("div", { className: "appbar-tools" },
        window.AtlasViewToggle && h(window.AtlasViewToggle, { active, onMap, onNetwork }),
      ),
    );
  }
  window.AtlasAppBar = AppBar;

  function App() {
    const [view, setView] = useState("atlas");            // "atlas" | "network" | "site" | <assetId>
    const [model, setModel] = useState(loadModel);
    const [inputs, setInputs] = useState(() => loadInputs(model));
    const [plantId, setPlantId] = useState(() => {
      try { const s = localStorage.getItem(LS_PLANT); if (s && window.ATLAS_PLANTS && ATLAS_PLANTS.byId[s]) return s; } catch (e) {}
      return "apcw";
    });
    const [agentCollapsed, setAgentCollapsed] = useState(true);
    const [agentWide, setAgentWide] = useState(false);
    const [railExpanded, setRailExpanded] = useState(false);
    const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

    // keep the global pointer synced so non-React readers (ATLAS getters) see the live model
    window.ATLAS.model = model;

    const assets = useMemo(() => ATLAS.assetsMap(model), [model]);
    const assetNodes = useMemo(() => window.buildAssetNodes(model), [model]);
    const processNodes = useMemo(() => window.buildProcessNodes(model), [model]);
    const derived = useMemo(() => window.AtlasEngine.evaluate(inputs, model), [inputs, model]);

    useEffect(() => { try { localStorage.setItem(LS_KEY, JSON.stringify(inputs)); } catch (e) {} }, [inputs]);
    useEffect(() => { try { localStorage.setItem(LS_MODEL, JSON.stringify(model)); } catch (e) {} }, [model]);
    useEffect(() => { try { localStorage.setItem(LS_PLANT, plantId); } catch (e) {} }, [plantId]);

    // switching plant site seeds the live input store with that plant's values, so the
    // detail explorer and the AI agent all operate on the plant the user is looking at.
    const selectPlant = (id) => {
      if (!window.ATLAS_PLANTS || !ATLAS_PLANTS.byId[id]) return;
      setPlantId(id);
      setInputs(ATLAS_PLANTS.inputsFor(id, model));
    };
    // open a plant from the network gallery: seed its inputs, then show its full site
    // (or jump straight into an asset detail when an asset is passed).
    const openPlant = (id, assetId) => {
      selectPlant(id);
      setView(assetId || "site");
    };
    const plant = (window.ATLAS_PLANTS && ATLAS_PLANTS.byId[plantId]) || null;
    // when the model gains new inputs (manual or agent), seed their defaults into the value store
    useEffect(() => {
      setInputs((prev) => {
        const defs = ATLAS.defaultsFromModel(model);
        let changed = false;
        const next = Object.assign({}, prev);
        Object.keys(defs).forEach((k) => { if (!(k in next)) { next[k] = defs[k]; changed = true; } });
        return changed ? next : prev;
      });
    }, [model]);
    useEffect(() => {
      document.documentElement.style.setProperty("--latspace-dark", t.accent);
      document.body.classList.toggle("pal-slate", t.calcPalette === "slate");
      document.body.classList.toggle("mc-lg", t.metricSize === "large");
    }, [t.accent, t.calcPalette, t.metricSize]);

    const setInput = (id, val) => setInputs((prev) => Object.assign({}, prev, { [id]: val }));
    const applyInputChanges = (changes) => setInputs((prev) => {
      const next = Object.assign({}, prev);
      changes.forEach((change) => { next[change.id] = change.value; });
      return next;
    });
    const resetAll = () => {
      const fresh = cloneModel(ATLAS.DEFAULT_MODEL);
      setModel(fresh);
      setPlantId("apcw");
      setInputs(window.ATLAS_PLANTS ? ATLAS_PLANTS.inputsFor("apcw", fresh) : ATLAS.defaultsFromModel(fresh));
      setView("network");
    };

    // export the full state (schema + values) as a JSON file
    const exportJson = () => {
      const blob = new Blob([JSON.stringify({ version: 2, model, inputs }, null, 2)], { type: "application/json" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = "atlas-model.json";
      a.click();
      URL.revokeObjectURL(url);
    };
    const importJson = (file) => {
      const reader = new FileReader();
      reader.onload = () => {
        try {
          const data = JSON.parse(reader.result);
          if (!data.model || !Array.isArray(data.model.assets)) throw new Error("Not an Atlas model file.");
          setModel(data.model);
          setInputs(data.inputs && typeof data.inputs === "object"
            ? Object.assign({}, ATLAS.defaultsFromModel(data.model), data.inputs)
            : ATLAS.defaultsFromModel(data.model));
          setView("network");
        } catch (e) {
          alert("Import failed: " + (e.message || e));
        }
      };
      reader.readAsText(file);
    };

    // Left side rail — shared across every view. Grid stays active for the
    // workspace family (network / site / detail); Map is active on the atlas view.
    const onMap = view === "atlas";
    const sideRail = h(SideRail, {
      active: onMap ? "map" : "grid",
      expanded: railExpanded,
      onToggle: () => setRailExpanded((v) => !v),
      onHome: () => setView("atlas"),
      items: [
        { id: "grid", icon: "grid", label: "Network", active: !onMap, onClick: () => setView("network") },
        { id: "map", icon: "map", label: "Map", active: onMap, onClick: () => setView("atlas") },
        { id: "report", icon: "report", label: "Reports", active: false, onClick: () => {} },
        { id: "leaf", icon: "leaf", label: "Sustainability", active: false, onClick: () => {} },
      ],
      footItems: [
        { id: "settings", kind: "settings", label: "Settings",
          onExport: exportJson, onImportFile: importJson, onReset: resetAll },
        { id: "exit", icon: "exit", label: "Sign out", active: false, onClick: () => setView("atlas") },
      ],
    });

    // The Atlas homepage map is a full-screen landing view that brings its own top nav.
    // It renders standalone (no app chrome); "Open Workspace" drops into the network view.
    if (view === "atlas") {
      const mapEl = window.AtlasMap
        ? h(window.AtlasMap, {
            onEnterApp: () => setView("network"),
            onShowNetwork: () => setView("network"),
            // clicking a modelled plant marker (APCW / RCW / KCW) opens its full site view
            onOpenPlant: (id) => openPlant(id, null),
            // the cross-plant Network Analyst rides along on the map view too
            plants: (window.ATLAS_PLANTS ? ATLAS_PLANTS.list : []),
            model,
            agentCollapsed,
            onAgentCollapsedChange: setAgentCollapsed,
            agentWide,
            onAgentWideChange: setAgentWide,
          })
        : h("div", { className: "app" });
      return h("div", { className: "shell" }, sideRail, h("div", { className: "shell-main" }, mapEl));
    }

    return h("div", { className: "shell" }, sideRail, h("div", { className: "shell-main" },
     h("div", { className: "app" },
      // shared top bar (identical to the map view)
      h(AppBar, {
        active: "network",
        onMap: () => setView("atlas"),
        onNetwork: () => setView("network"),
        onBrandClick: () => setView("atlas"),
      }),

      view === "network"
        ? h("div", { className: "workspace" + (agentCollapsed ? " agent-collapsed" : agentWide ? " agent-wide" : "") },
            h("main", { className: "main-pane" },
              h(window.NetworkView, {
                plants: (window.ATLAS_PLANTS ? ATLAS_PLANTS.list : []),
                model, onOpenPlant: openPlant,
              }),
            ),
            h(window.NetworkAgentPanel, {
              plants: (window.ATLAS_PLANTS ? ATLAS_PLANTS.list : []),
              model, collapsed: agentCollapsed, onCollapsedChange: setAgentCollapsed,
              wide: agentWide, onWideChange: setAgentWide,
            }),
          )
        : h("div", { className: "workspace" + (agentCollapsed ? " agent-collapsed" : agentWide ? " agent-wide" : "") },
            h("main", { className: "main-pane" },
              view === "site"
                ? h(window.SiteView, {
                    plant, derived,
                    onBack: () => setView("network"),
                    onOpenAsset: (id) => setView(id),
                  })
                : h(DetailView, {
                    asset: assets[view], plant, model, setModel, inputs, derived, setInput,
                    onBack: () => setView("site"),
                    onOpenAsset: (id) => setView(id),
                  }),
            ),
            h(AgentPanel, {
              view, model, setModel, assetNodes, processNodes, inputs, derived, applyInputChanges,
              collapsed: agentCollapsed, onCollapsedChange: setAgentCollapsed,
              wide: agentWide, onWideChange: setAgentWide,
            }),
          ),

      // Tweaks panel
      h(TweaksPanel, null,
        h(TweakSection, { label: "Diagram" }),
        h(TweakToggle, { label: "Process-flow grid", value: t.showGrid, onChange: (v) => setTweak("showGrid", v) }),
        h(TweakSection, { label: "Calculated rows" }),
        h(TweakRadio, { label: "Palette", value: t.calcPalette, options: ["pink", "slate"],
          onChange: (v) => setTweak("calcPalette", v) }),
        h(TweakSection, { label: "Metrics" }),
        h(TweakRadio, { label: "Value size", value: t.metricSize, options: ["standard", "large"],
          onChange: (v) => setTweak("metricSize", v) }),
        h(TweakColor, { label: "Accent", value: t.accent,
          options: ["#074D47", "#063F39", "#22867C", "#155E55"],
          onChange: (v) => setTweak("accent", v) }),
      ),
    )));
  }

  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>';

  ReactDOM.createRoot(document.getElementById("root")).render(h(App));
})();
