// Root app — wires sidebar, canvas, console, and theme tweak together
function App() {
  const [flow, setFlow] = React.useState([]);
  const [selected, setSelected] = React.useState(null);
  const [query, setQuery] = React.useState("");
  const [logs, setLogs] = React.useState([]);
  const [running, setRunning] = React.useState(false);
  const [activeId, setActiveId] = React.useState(null);

  // --- Persistence & Multi-Flow ---
  const [maxFlows, setMaxFlows] = React.useState(1);
  const [savedFlows, setSavedFlows] = React.useState([]);
  const [activeSlot, setActiveSlot] = React.useState(1);
  const [isSaving, setIsSaving] = React.useState(false);

  React.useEffect(() => {
    fetchFlows();
  }, []);

  const fetchFlows = async () => {
    try {
      const res = await fetch('/api/agent-flows');
      const data = await res.json();
      if (data.flows) {
        setSavedFlows(data.flows);
        setMaxFlows(data.maxFlows || 1);
        // Load Slot 1 by default if it exists
        const slot1 = data.flows.find(f => f.slotId === 1);
        if (slot1 && slot1.data) {
          setFlow(slot1.data);
        } else {
          setFlow(window.EXAMPLE_FLOW.map((n) => ({ ...n, params: n.params ? n.params.map((p) => ({ ...p })) : [] })));
        }
      }
    } catch (e) {
      console.error("Failed to load flows:", e);
    }
  };

  const changeSlot = (slotId) => {
    // Save current flow to the previous slot state locally before switching? 
    // For simplicity, we just load from the server-provided savedFlows
    const target = savedFlows.find(f => f.slotId === slotId);
    if (target && target.data) {
      setFlow(target.data);
    } else {
      setFlow([]);
    }
    setActiveSlot(slotId);
    setSelected(null);
  };

  const saveFlow = async () => {
    setIsSaving(true);
    try {
      const res = await fetch('/api/agent-flow', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          slotId: activeSlot,
          flowData: flow,
          flowName: `Flow ${activeSlot}`
        })
      });
      const data = await res.json();
      if (data.success) {
        // Refresh local saved flows
        setSavedFlows(prev => {
          const next = [...prev];
          const idx = next.findIndex(f => f.slotId === activeSlot);
          const entry = { slotId: activeSlot, name: `Flow ${activeSlot}`, data: flow };
          if (idx !== -1) next[idx] = entry;
          else next.push(entry);
          return next;
        });
        alert("Flow salvato correttamente!");
      } else {
        alert("Errore salvataggio: " + data.error);
      }
    } catch (e) {
      alert("Errore di connessione.");
    } finally {
      setIsSaving(false);
    }
  };

  // --- Tweaks (persisted) ---
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "theme": "light"
  }/*EDITMODE-END*/;
  const [tweaks, setTweaks] = React.useState(TWEAK_DEFAULTS);
  const [tweaksOpen, setTweaksOpen] = React.useState(false);

  React.useEffect(() => {
    document.documentElement.dataset.theme = tweaks.theme;
  }, [tweaks.theme]);

  React.useEffect(() => {
    const onMsg = (e) => {
      const d = e.data || {};
      if (d.type === "__activate_edit_mode") setTweaksOpen(true);
      if (d.type === "__deactivate_edit_mode") setTweaksOpen(false);
    };
    window.addEventListener("message", onMsg);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const setTweak = (key, val) => {
    setTweaks((t) => ({ ...t, [key]: val }));
    window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { [key]: val } }, "*");
  };

  // --- Flow ops ---
  const addBlock = (blockId, at) => {
    const def = window.findBlock(blockId);
    if (!def) return;
    const node = {
      instanceId: "n_" + Math.random().toString(36).slice(2, 8),
      blockId,
      params: (def.params || []).map((p) => ({ ...p })),
    };
    setFlow((f) => {
      const idx = at == null ? f.length : Math.max(0, Math.min(f.length, at));
      const next = [...f];
      next.splice(idx, 0, node);
      return next;
    });
    setSelected(node.instanceId);
  };

  const removeBlock = (iid) => {
    setFlow((f) => f.filter((n) => n.instanceId !== iid));
    if (selected === iid) setSelected(null);
  };

  const editParam = (iid, pIdx, val) => {
    setFlow((f) =>
      f.map((n) =>
        n.instanceId === iid
          ? { ...n, params: n.params.map((p, i) => (i === pIdx ? { ...p, val } : p)) }
          : n
      )
    );
  };

  // --- Simulated run ---
  const timers = React.useRef([]);
  const clearTimers = () => {
    timers.current.forEach(clearTimeout);
    timers.current = [];
  };

  const time = () => {
    const d = new Date();
    return (
      String(d.getHours()).padStart(2, "0") +
      ":" +
      String(d.getMinutes()).padStart(2, "0") +
      ":" +
      String(d.getSeconds()).padStart(2, "0")
    );
  };

  const runFlow = () => {
    clearTimers();
    setLogs([{ time: time(), level: "info", tag: "run", msg: "— Flow started —" }]);
    setRunning(true);
    let delay = 300;
    flow.forEach((node, i) => {
      const def = window.findBlock(node.blockId);
      if (!def) return;
      timers.current.push(
        setTimeout(() => {
          setActiveId(node.instanceId);
          setLogs((l) => [
            ...l,
            {
              time: time(),
              level: "info",
              tag: def.category.toLowerCase(),
              msg: `[${String(i + 1).padStart(2, "0")}] ${def.label}` +
                (node.params[0] ? ` — ${node.params[0].key}: ${node.params[0].val}` : ""),
            },
          ]);
        }, delay)
      );
      delay += 650;
    });
    timers.current.push(
      setTimeout(() => {
        setLogs((l) => [
          ...l,
          { time: time(), level: "ok", tag: "done", msg: "Flow completed in " + (delay / 1000).toFixed(2) + "s" },
        ]);
        setRunning(false);
        setActiveId(null);
      }, delay)
    );
  };

  const stopFlow = () => {
    clearTimers();
    setRunning(false);
    setActiveId(null);
    setLogs((l) => [...l, { time: time(), level: "warn", tag: "stop", msg: "Stopped by user." }]);
  };

  const clearLogs = () => setLogs([]);

  return (
    <div className="app">
      <TopBar 
        running={running} 
        onRun={runFlow} 
        onStop={stopFlow} 
        maxFlows={maxFlows}
        activeSlot={activeSlot}
        onChangeSlot={changeSlot}
        onSave={saveFlow}
        isSaving={isSaving}
      />
      <div className="workbench">
        <Sidebar onDragStart={() => {}} query={query} setQuery={setQuery} />
        <main className="stage">
          <Canvas
            flow={flow}
            onDrop={addBlock}
            onSelect={setSelected}
            selected={selected}
            onRemove={removeBlock}
            onParamEdit={editParam}
            running={running}
            activeId={activeId}
          />
          <Console
            logs={logs}
            running={running}
            onRun={runFlow}
            onStop={stopFlow}
            onClear={clearLogs}
          />
        </main>
      </div>
      {tweaksOpen && <TweaksPanel tweaks={tweaks} setTweak={setTweak} onClose={() => setTweaksOpen(false)} />}
    </div>
  );
}

function TopBar({ running, onRun, onStop, maxFlows, activeSlot, onChangeSlot, onSave, isSaving }) {
  return (
    <header className="topbar">
      <div className="brand">
        <span className="brand-mark">◐</span>
        <span className="brand-name">Socratico</span>
        <span className="brand-sub">workflow studio</span>
      </div>
      <nav className="crumbs">
        <span>Projects</span>
        <span className="sep">/</span>
        <span>Socratico.online agent</span>
        <span className="sep">/</span>
        <span className="cur">Agent Creator.flow</span>
      </nav>
      <div className="topbar-actions">
        <div className="slot-pills">
          {Array.from({ length: maxFlows }).map((_, i) => {
            const num = i + 1;
            return (
              <button 
                key={num}
                className={`btn pill ${activeSlot === num ? 'active' : ''}`}
                onClick={() => onChangeSlot(num)}
              >
                Slot {num}
              </button>
            );
          })}
        </div>
        <div className="sep-v" />
        <button className={`btn ghost ${isSaving ? 'loading' : ''}`} onClick={onSave} disabled={isSaving}>
          {isSaving ? 'Saving...' : 'Save Flow'}
        </button>
        {running ? (
          <button className="btn stop" onClick={onStop}>◼ Stop</button>
        ) : (
          <button className="btn primary" onClick={onRun}>▸ Run</button>
        )}
      </div>
    </header>
  );
}

function TweaksPanel({ tweaks, setTweak, onClose }) {
  return (
    <div className="tweaks">
      <header className="tweaks-head">
        <span className="tweaks-eyebrow">Tweaks</span>
        <button className="tweaks-close" onClick={onClose}>×</button>
      </header>
      <div className="tweaks-row">
        <label>Theme</label>
        <div className="seg">
          <button
            className={tweaks.theme === "light" ? "on" : ""}
            onClick={() => setTweak("theme", "light")}
          >
            Light
          </button>
          <button
            className={tweaks.theme === "dark" ? "on" : ""}
            onClick={() => setTweak("theme", "dark")}
          >
            Dark
          </button>
        </div>
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
