// Drag-and-drop state + undo toast for the Overview status grid.
//
// The drag state lives on `window` (not React) because HTML5 drag events
// fire on DOM nodes that don't always re-render during the drag; forcing
// everything through React state would cause the drop-zone highlight to
// lag behind the cursor. Instead, components subscribe via a custom event
// and a tiny `useDragState` hook that tracks whether *a* drag is active.
//
// The undo toast is a global overlay; `window.__pulseShowUndo({label, onUndo})`
// pushes a new toast that auto-dismisses after 5 seconds.

(function () {
  // --- drag state singleton --------------------------------------------------
  window.__pulseDnD = window.__pulseDnD || { activeNodeId: null, sourceGroup: null };

  function setDragActive(nodeId, sourceGroup) {
    window.__pulseDnD = { activeNodeId: nodeId, sourceGroup };
    window.dispatchEvent(new CustomEvent('pulse:dnd-change'));
  }
  function clearDragActive() {
    window.__pulseDnD = { activeNodeId: null, sourceGroup: null };
    window.dispatchEvent(new CustomEvent('pulse:dnd-change'));
  }
  function useDragState() {
    const [state, setState] = React.useState(window.__pulseDnD);
    React.useEffect(() => {
      function onChange() { setState({ ...window.__pulseDnD }); }
      window.addEventListener('pulse:dnd-change', onChange);
      return () => window.removeEventListener('pulse:dnd-change', onChange);
    }, []);
    return state;
  }

  // --- undo-toast stack ------------------------------------------------------
  // Each toast: { id, label, onUndo, createdAt }
  // Stored on window so multiple components (overview, future views) can push.
  window.__pulseToasts = window.__pulseToasts || [];
  let toastSeq = 0;

  function showUndoToast({ label, onUndo, ttlMs = 5000 }) {
    const id = ++toastSeq;
    const entry = { id, label, onUndo, createdAt: Date.now(), ttlMs };
    // Cap at 3 visible so fast repeated moves don't flood the screen.
    window.__pulseToasts = [entry, ...window.__pulseToasts].slice(0, 3);
    window.dispatchEvent(new CustomEvent('pulse:toasts-change'));
    setTimeout(() => dismissToast(id), ttlMs);
  }
  function dismissToast(id) {
    const before = window.__pulseToasts.length;
    window.__pulseToasts = window.__pulseToasts.filter(t => t.id !== id);
    if (window.__pulseToasts.length !== before) {
      window.dispatchEvent(new CustomEvent('pulse:toasts-change'));
    }
  }

  function UndoToastStack() {
    // All hooks above any early return.
    const [toasts, setToasts] = React.useState(window.__pulseToasts);
    React.useEffect(() => {
      function onChange() { setToasts([...window.__pulseToasts]); }
      window.addEventListener('pulse:toasts-change', onChange);
      // Session-lost → clear toasts so they don't leak across logins.
      function onSessionLost() {
        window.__pulseToasts = [];
        setToasts([]);
      }
      window.addEventListener('pulse:session-lost', onSessionLost);
      return () => {
        window.removeEventListener('pulse:toasts-change', onChange);
        window.removeEventListener('pulse:session-lost', onSessionLost);
      };
    }, []);

    if (!toasts.length) return null;
    return (
      <div style={{
        position: 'fixed', right: 16, bottom: 16, zIndex: 40,
        display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'flex-end',
      }}>
        {toasts.map(t => (
          <div key={t.id} className="undo-toast">
            <span>{t.label}</span>
            <button className="btn" style={{ padding: '2px 10px', fontSize: 10 }}
              onClick={() => { try { t.onUndo && t.onUndo(); } finally { dismissToast(t.id); } }}>
              undo
            </button>
            <button className="btn" style={{ padding: '2px 8px', fontSize: 10, opacity: 0.6 }}
              onClick={() => dismissToast(t.id)}>
              ×
            </button>
          </div>
        ))}
      </div>
    );
  }

  // Expose to window so overview.jsx and app.jsx can use them.
  Object.assign(window, {
    setDragActive, clearDragActive, useDragState,
    __pulseShowUndo: showUndoToast,
    UndoToastStack,
  });
})();
