import React, { useState, useRef, useEffect, useCallback } from "react";
import { ChatArea } from "../../chat";
import { SessionSidebar, FileSystemNavigator } from "../../../shared/components";
import useSwarmControl from "../hooks/useSwarmControl";
import {
  updateSession, getSessionNodeStatus, attachNodesToSession,
  detachNodeFromSession, getUserAccessibleNodes, getUserNodePreferences, nodeFsList,
  clearSessionHistory
} from "../../../services/apiService";
import {
  SwarmControlConsoleOverlay,
  SwarmControlFileExplorerOverlay
} from "../components/SwarmControlOverlays";
import { SwarmControlNodeSelectorModal } from "../components/SwarmControlNodeSelectorModal";
import { useWebMcp } from "../../../shared/components/WebMcpProvider";

const CodeAssistantPage = () => {
  const pageContainerRef = useRef(null);
  const confirmClearHistory = async () => {
    if (!sessionId) return;
    setIsClearingHistory(true);
    try {
      await clearSessionHistory(sessionId);
      // Reload the page to refresh chat history from the server
      window.location.reload();
    } catch (e) {
      alert(`Failed to clear history: ${e.message}`);
    } finally {
      setIsClearingHistory(false);
      setShowClearChatModal(false);
    }
  };

  const handleClearHistory = () => {
    if (!sessionId) return;
    setShowClearChatModal(true);
  };

  const [showNodeSelector, setShowNodeSelector] = useState(false);
  const isEditingMeshRef = useRef(false);
  useEffect(() => {
    isEditingMeshRef.current = showNodeSelector;
  }, [showNodeSelector]);
  const [sidebarRefreshTick, setSidebarRefreshTick] = useState(0);

  // M3/M6 Node Integration State
  const [sessionNodeStatus, setSessionNodeStatus] = useState({}); // node_id -> { status, last_sync }
  const [accessibleNodes, setAccessibleNodes] = useState([]);
  const [attachedNodeIds, setAttachedNodeIds] = useState([]);
  const [workspaceId, setWorkspaceId] = useState("");
  const [showConsole, setShowConsole] = useState(false);
  const [syncConfig, setSyncConfig] = useState({ source: 'server', path: '', source_node_id: '', read_only_node_ids: [] });
  const [activeSyncConfig, setActiveSyncConfig] = useState(null);
  const [pathSuggestions, setPathSuggestions] = useState([]);
  const [isSearchingPath, setIsSearchingPath] = useState(false);
  const [showPathSuggestions, setShowPathSuggestions] = useState(false);
  const [hasLoadedDefaults, setHasLoadedDefaults] = useState(false);
  const [isInitiatingSync, setIsInitiatingSync] = useState(false);
  const [showFileExplorer, setShowFileExplorer] = useState(false);
  const [isConsoleExpanded, setIsConsoleExpanded] = useState(false);
  const [consoleHeight, setConsoleHeight] = useState(256); // Default 64 * 4px = 256px
  const [isDraggingConsole, setIsDraggingConsole] = useState(false);
  const isDraggingConsoleRef = useRef(false);

  // Persistence for Auto-Collapse
  const [autoCollapse, setAutoCollapse] = useState(() => {
    return localStorage.getItem("swarm_auto_collapse") === "true";
  });

  const { registerTool, unregisterTool } = useWebMcp();

  const onNewSessionCreated = useCallback(async (newSid) => {
    try {
      const [accessibleNodes, prefs] = await Promise.all([
        getUserAccessibleNodes(),
        getUserNodePreferences()
      ]);

      let targetIds = [];
      const defaultIds = prefs.default_node_ids || [];

      if (defaultIds.length > 0) {
        // Filter defaults by what is actually accessible
        const accessibleIds = accessibleNodes.map(n => n.node_id);
        targetIds = defaultIds.filter(id => accessibleIds.includes(id));
      } else {
        // Fallback: attach all accessible nodes if no defaults specified
        targetIds = accessibleNodes.map(n => n.node_id);
      }

      if (targetIds.length > 0) {
        const syncConfig = prefs.data_source || { source: 'server' };
        await attachNodesToSession(newSid, targetIds, syncConfig);

        // Immediate local sync for UI
        setAttachedNodeIds(targetIds);
        setSyncConfig(syncConfig); // Ensure UI matches the applied config

        // Refresh full status from server to stay in sync
        const status = await getSessionNodeStatus(newSid);
        const apiIds = (status.nodes || []).map(n => n.node_id);
        setAttachedNodeIds(apiIds);
      }
    } catch (e) {
      console.warn("M3: Failed auto attaching defaults on new session", e);
    }
  }, []);

  const {
    chatHistory,
    isProcessing,
    errorMessage,
    showErrorModal,
    tokenUsage,
    handleSendChat,
    handleCancelChat,
    setShowErrorModal,
    handleSwitchSession,
    sessionId,
    userConfigData,
    localActiveLLM,
    setLocalActiveLLM,
    isConfigured,
    missingConfigs
  } = useSwarmControl({ pageContainerRef, onNewSessionCreated });

  const [showConfigModal, setShowConfigModal] = useState(false);
  const [showClearChatModal, setShowClearChatModal] = useState(false);
  const [isClearingHistory, setIsClearingHistory] = useState(false);

  // ── WebMCP Tools for the Swarm Control page ──────────────────────────────
  useEffect(() => {
    registerTool({
      name: 'get_session_nodes',
      description: 'Get the list of agent nodes currently attached to the active Swarm session.',
      inputSchema: { type: 'object', properties: {} },
      execute: async () => {
        return {
          content: [{ type: 'text', text: JSON.stringify({
            session_id: sessionId,
            attached_nodes: accessibleNodes
              .filter(n => attachedNodeIds.includes(n.node_id))
              .map(n => ({ id: n.node_id, name: n.display_name, status: n.last_status }))
          }, null, 2) }]
        };
      }
    });

    registerTool({
      name: 'list_accessible_nodes',
      description: 'List all agent nodes accessible to the current user in the swarm mesh.',
      inputSchema: { type: 'object', properties: {} },
      execute: async () => {
        try {
          const nodes = await getUserAccessibleNodes();
          return {
            content: [{ type: 'text', text: JSON.stringify({
              nodes: nodes.map(n => ({ id: n.node_id, name: n.display_name, status: n.last_status, os: n.capabilities?.os }))
            }, null, 2) }]
          };
        } catch (err) {
          return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
        }
      }
    });

    registerTool({
      name: 'get_swarm_status',
      description: 'Get the current Swarm Control session status including attached nodes, workspace, and LLM provider.',
      inputSchema: { type: 'object', properties: {} },
      execute: async () => {
        return {
          content: [{ type: 'text', text: JSON.stringify({
            session_id: sessionId,
            active_llm: localActiveLLM,
            attached_node_count: attachedNodeIds.length,
            total_accessible_nodes: accessibleNodes.length,
            workspace_id: workspaceId || null,
            is_configured: isConfigured,
          }, null, 2) }]
        };
      }
    });

    return () => {
      unregisterTool('get_session_nodes');
      unregisterTool('list_accessible_nodes');
      unregisterTool('get_swarm_status');
    };
  }, [sessionId, accessibleNodes, attachedNodeIds, workspaceId, localActiveLLM, isConfigured, registerTool, unregisterTool]);
  // ─────────────────────────────────────────────────────────────────────────


  const toggleAutoCollapse = () => {
    const newState = !autoCollapse;
    setAutoCollapse(newState);
    localStorage.setItem("swarm_auto_collapse", newState);
  };

  // Handle Dragging Console Resizer explicitly
  useEffect(() => {
    const handleMouseMove = (e) => {
      if (!isDraggingConsoleRef.current) return;
      e.preventDefault();
      const newHeight = window.innerHeight - e.clientY;
      const clampedHeight = Math.max(100, Math.min(window.innerHeight * 0.9, newHeight));
      setConsoleHeight(clampedHeight);
    };

    const handleMouseUp = () => {
      if (isDraggingConsoleRef.current) {
        isDraggingConsoleRef.current = false;
        setIsDraggingConsole(false);
        document.body.style.cursor = 'default';
        // Auto-fit xterm when dragged
        window.dispatchEvent(new Event('resize'));
      }
    };

    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);

    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, []);

  const handleConsoleDragStart = (e) => {
    e.preventDefault(); // Prevents text selection while dragging
    e.stopPropagation();
    isDraggingConsoleRef.current = true;
    setIsDraggingConsole(true);
    document.body.style.cursor = 'row-resize';
  };

  // M6: Persistence - if we have an active config, populate the form with it when modal opens
  useEffect(() => {
    if (showNodeSelector && activeSyncConfig) {
      setSyncConfig({
        source: activeSyncConfig.source || 'server',
        path: activeSyncConfig.path || '',
        source_node_id: activeSyncConfig.source_node_id || '',
        read_only_node_ids: activeSyncConfig.read_only_node_ids || []
      });
    }
  }, [showNodeSelector, activeSyncConfig]);

  // Auto-enforce Receiver Only logic in UI
  useEffect(() => {
    if (syncConfig.source === 'server') {
      setSyncConfig(prev => ({ ...prev, read_only_node_ids: [...attachedNodeIds] }));
    } else if (syncConfig.source === 'node_local' && syncConfig.source_node_id) {
      const others = attachedNodeIds.filter(id => id !== syncConfig.source_node_id);
      setSyncConfig(prev => ({ ...prev, read_only_node_ids: others }));
    }
  }, [syncConfig.source, syncConfig.source_node_id, attachedNodeIds]);

  const handleInitiateSync = async () => {
    if (!sessionId) return;
    setIsInitiatingSync(true);
    try {
      await attachNodesToSession(sessionId, attachedNodeIds, syncConfig);
      // M3: Explicitly turn off the editing mesh ref and modal BEFORE fetching
      // so the server's newly saved attached nodes replace the user checkboxes immediately
      isEditingMeshRef.current = false;
      setShowNodeSelector(false);

      await fetchNodeInfo();
    } catch (err) {
      alert(`Sync Error: ${err.message}`);
    } finally {
      setIsInitiatingSync(false);
    }
  };

  const fetchNodeInfo = async () => {
    if (!sessionId) return;
    try {
      const [status, nodes] = await Promise.all([
        getSessionNodeStatus(sessionId),
        getUserAccessibleNodes()
      ]);
      const apiNodes = status.nodes || [];
      const apiIds = apiNodes.map(n => n.node_id);

      // Sanitized ID List: only show IDs that are actually in the live accessible list
      const liveIds = nodes.map(n => n.node_id);
      const sanitizedIds = apiIds.filter(id => liveIds.includes(id));

      const syncStatusMap = {};
      apiNodes.forEach(n => {
        syncStatusMap[n.node_id] = { status: n.status, last_sync: n.last_sync };
      });

      setSessionNodeStatus(syncStatusMap);
      setWorkspaceId(status.sync_workspace_id || "");
      setAccessibleNodes(nodes);

      // Stop auto-poll from wiping out user's active checkbox edits
      if (!isEditingMeshRef.current) {
        setAttachedNodeIds(sanitizedIds);
        setActiveSyncConfig(status.sync_config || null);
      }
    } catch (e) {
      console.warn("M3: Failed to fetch session node info", e);
    }
  };

  useEffect(() => {
    fetchNodeInfo();
    const interval = setInterval(fetchNodeInfo, 5000); // Polling status
    return () => clearInterval(interval);
  }, [sessionId]);

  // M3: Path Autocomplete Logic
  useEffect(() => {
    const fetchSuggestions = async () => {
      if (syncConfig.source !== 'node_local' || !syncConfig.source_node_id || !syncConfig.path) {
        setPathSuggestions([]);
        return;
      }

      const path = syncConfig.path;
      // Determine the directory to list and the fragment being typed
      let dirToList = ".";
      let fragment = "";

      if (path.includes('/')) {
        const lastSlashIndex = path.lastIndexOf('/');
        dirToList = path.substring(0, lastSlashIndex) || "/";
        fragment = path.substring(lastSlashIndex + 1);
      } else {
        fragment = path;
      }

      setIsSearchingPath(true);
      try {
        const results = await nodeFsList(syncConfig.source_node_id, dirToList);
        const fileList = results.files || [];

        // Filter: must be directory AND must start with the current fragment
        const dirs = fileList
          .filter(item => item.is_dir && item.name.toLowerCase().startsWith(fragment.toLowerCase()))
          .map(item => item.name);

        setPathSuggestions(dirs);
      } catch (e) {
        setPathSuggestions([]);
      } finally {
        setIsSearchingPath(false);
      }
    };

    const timer = setTimeout(fetchSuggestions, 500);
    return () => clearTimeout(timer);
  }, [syncConfig.path, syncConfig.source_node_id, syncConfig.source]);

  useEffect(() => {
    const loadDefaults = async () => {
      try {
        const prefs = await getUserNodePreferences();
        if (prefs && prefs.data_source && !hasLoadedDefaults) {
          setSyncConfig(prefs.data_source);
          setHasLoadedDefaults(true);
        }
      } catch (e) {
        console.warn("M3: Failed to load node defaults", e);
      }
    };
    loadDefaults();
  }, [hasLoadedDefaults]);

  const handleToggleNode = (nodeId, isCurrentlyAttached) => {
    if (isCurrentlyAttached) {
      setAttachedNodeIds(prev => prev.filter(id => id !== nodeId));
      // Also remove from read-only if it's there
      setSyncConfig(prev => ({
        ...prev,
        read_only_node_ids: (prev.read_only_node_ids || []).filter(id => id !== nodeId)
      }));
    } else {
      setAttachedNodeIds(prev => [...prev, nodeId]);
    }
  };

  const handleToggleReadOnly = (nodeId) => {
    setSyncConfig(prev => {
      const current = prev.read_only_node_ids || [];
      if (current.includes(nodeId)) {
        return { ...prev, read_only_node_ids: current.filter(id => id !== nodeId) };
      } else {
        return { ...prev, read_only_node_ids: [...current, nodeId] };
      }
    });
  };

  const handleSaveQuickConfig = async () => {
    try {
      if (sessionId && localActiveLLM) {
        await updateSession(sessionId, { provider_name: localActiveLLM });
        setSidebarRefreshTick(t => t + 1);
      }
      setShowConfigModal(false);
    } catch (e) {
      console.error("Failed to update session configs:", e);
    }
  };

  useEffect(() => {
    if (pageContainerRef.current) {
      pageContainerRef.current.scrollTop = pageContainerRef.current.scrollHeight;
    }
  }, [chatHistory]);


  return (
    <div className="flex flex-row flex-grow h-full overflow-hidden bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 relative">
      {/* Invisible overlay to catch events across the entire screen during fast drag */}
      {isDraggingConsole && (
        <div className="fixed inset-0 z-[9999] cursor-row-resize bg-transparent" />
      )}

      <SessionSidebar
        featureName="swarm_control"
        currentSessionId={sessionId}
        onSwitchSession={handleSwitchSession}
        onNewSession={() => handleSendChat("/new")}
        refreshTick={sidebarRefreshTick}
      />

      {/* Main content area */}
      <div className="flex-grow flex flex-col min-h-0 min-w-0 bg-transparent" ref={pageContainerRef}>
        <div className={`px-6 md:px-16 ${showFileExplorer ? 'lg:px-8' : 'lg:px-24'} w-full h-full pt-12 flex flex-col min-h-0 min-w-0 mx-auto transition-all duration-300`}>
          {/* Chat Area & Header */}
            <div className="flex-grow flex flex-row min-h-0 min-w-0 gap-4 mb-4">
              <div className="flex-grow bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 flex flex-col min-h-0 min-w-0 transition-all duration-300">
                <h2 className="p-4 text-xl font-bold flex flex-col md:flex-row justify-between items-start md:items-center border-b border-gray-100 dark:border-gray-700 gap-4 md:gap-0">
                  <div className="flex flex-wrap items-center gap-3 w-full md:w-auto">
                    <div className="p-2 bg-indigo-100 dark:bg-indigo-900/30 rounded-lg">
                      <svg className="w-6 h-6 text-indigo-600 dark:text-indigo-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
                      </svg>
                    </div>
                    <div className="flex flex-col">
                      <span className="text-lg">Swarm Control</span>
                      <span className="text-[10px] text-gray-500 font-medium uppercase tracking-widest whitespace-nowrap">
                        Mesh: {accessibleNodes.filter(n => n.last_status === 'online' || n.last_status === 'idle').length} Online / {accessibleNodes.length} Total
                      </span>
                    </div>

                    {/* Nodes Indicator Bar (M3/M6) */}
                    <div className="flex items-center space-x-2 ml-0 md:ml-4 border-l-0 md:border-l pl-0 md:pl-4 dark:border-gray-700 h-10 overflow-visible">
                      {attachedNodeIds.length === 0 ? (
                        <span
                          className="text-[10px] text-gray-400 italic cursor-pointer hover:text-indigo-500 transition-colors"
                          onClick={() => setShowNodeSelector(true)}
                        >
                          {accessibleNodes.length === 0 ? 'No nodes found in mesh' : 'Click to attach nodes'}
                        </span>
                      ) : (
                        <div className="flex items-center space-x-1.5 relative group cursor-pointer" onClick={() => setShowNodeSelector(true)}>
                          <div className="flex -space-x-1.5 mr-1">
                            {accessibleNodes.filter(n => attachedNodeIds.includes(n.node_id)).slice(0, 3).map((node, i) => {
                              const isOnline = node.last_status === 'online' || node.last_status === 'idle' || node.last_status === 'busy';
                              return (
                                <div key={node.node_id} style={{ zIndex: 10 - i }} className={`w-5 h-5 rounded-full border border-white dark:border-gray-800 flex items-center justify-center text-[9px] font-bold text-white shadow-sm ring-1 ${isOnline ? 'bg-indigo-500 ring-indigo-300' : 'bg-gray-400 ring-gray-300'}`} title={node.display_name}>
                                  {node.display_name.charAt(0).toUpperCase()}
                                </div>
                              )
                            })}
                            {attachedNodeIds.length > 3 && (
                              <div style={{ zIndex: 1 }} className="w-5 h-5 rounded-full border border-white dark:border-gray-800 flex items-center justify-center text-[9px] font-bold text-indigo-700 bg-indigo-50 z-0">
                                +{attachedNodeIds.length - 3}
                              </div>
                            )}
                          </div>

                          <span className="text-[11px] font-bold text-indigo-700 dark:text-indigo-300 whitespace-nowrap">
                            {attachedNodeIds.length} Attached
                          </span>

                          {(workspaceId || syncConfig.source !== 'empty') && (
                            <div className="relative group/sync flex items-center h-full ml-1">
                              <div className="p-1 bg-emerald-50 dark:bg-emerald-900/40 rounded-full border border-emerald-200 dark:border-emerald-800">
                                <svg className="w-3.5 h-3.5 text-emerald-600 dark:text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
                                </svg>
                              </div>
                              <div className="absolute top-full left-1/2 -translate-x-1/2 mt-2 px-3 py-2 bg-gray-900 border border-gray-700 text-white text-[10px] font-bold rounded shadow-xl opacity-0 group-hover/sync:opacity-100 transition-all whitespace-nowrap z-[60] pointer-events-none">
                                <span className="text-emerald-400">File Sync Active</span><br />
                                <span className="text-gray-300 font-mono text-[9px] font-normal tracking-wide mt-1 block">
                                  Workspace: {workspaceId || 'Initializing...'}
                                </span>
                              </div>
                            </div>
                          )}

                          <div className="absolute top-full left-0 mt-2 px-2 py-1 bg-gray-900 text-white text-[10px] font-bold rounded opacity-0 group-hover:opacity-100 transition-all whitespace-nowrap z-[50] pointer-events-none delay-150">
                            Click to manage mesh strategy
                          </div>
                        </div>
                      )}
                      {attachedNodeIds.length > 0 && (
                        <div className="flex items-center gap-1 border-l dark:border-gray-700 ml-2 pl-2">
                          <button
                            onClick={() => setShowConsole(!showConsole)}
                            className={`p-1.5 rounded-lg transition-colors ${showConsole ? 'bg-indigo-100 text-indigo-600' : 'text-gray-400 hover:bg-gray-50'}`}
                            title="Toggle Execution Console"
                          >
                            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
                            </svg>
                          </button>
                          {workspaceId && (
                            <button
                              onClick={() => setShowFileExplorer(!showFileExplorer)}
                              className={`p-1.5 rounded-lg transition-colors ${showFileExplorer ? 'bg-indigo-100 text-indigo-600' : 'text-gray-400 hover:bg-gray-50'}`}
                              title="Toggle File Explorer"
                            >
                              <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
                              </svg>
                            </button>
                          )}
                        </div>
                      )}
                    </div>

                    {!isConfigured && (
                      <div className="group relative flex items-center">
                        <svg className="w-5 h-5 text-yellow-500 cursor-pointer" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                        </svg>
                        <div className="absolute left-1/2 -translate-x-1/2 top-full mt-2 w-56 bg-gray-900 text-white text-[11px] rounded shadow-lg p-2.5 opacity-0 group-hover:opacity-100 transition-opacity z-50 pointer-events-none text-left">
                          <p className="font-bold mb-1 text-red-400">Missing Key</p>
                          <ul className="list-disc pl-3 space-y-0.5">
                            {missingConfigs?.map((m, i) => <li key={i}>{m}</li>)}
                          </ul>
                        </div>
                      </div>
                    )}
                    <button
                      onClick={() => setShowConfigModal(true)}
                      className="text-gray-400 hover:text-indigo-600 transition-colors"
                    >
                      <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
                    </button>
                  </div>
                  <div className="flex flex-wrap items-center gap-4 md:gap-6 w-full md:w-auto justify-start md:justify-end">
                    <div className="flex items-center gap-6">
                      <div className="flex items-center gap-2 group/collapse relative">
                        <button
                          onClick={toggleAutoCollapse}
                          className={`flex items-center gap-2 px-3 py-1.5 rounded-lg border text-[10px] font-black uppercase tracking-widest transition-all ${autoCollapse
                            ? 'bg-emerald-50 border-emerald-200 text-emerald-600 dark:bg-emerald-900/20 dark:border-emerald-800'
                            : 'bg-gray-50 border-gray-200 text-gray-400 dark:bg-gray-800/50 dark:border-gray-700'
                            }`}
                        >
                          <div className={`w-1.5 h-1.5 rounded-full ${autoCollapse ? 'bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]' : 'bg-gray-300'}`} />
                          Auto-Collapse
                        </button>
                        <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 border border-gray-700 text-white text-[10px] font-bold rounded shadow-xl opacity-0 group-hover/collapse:opacity-100 transition-all whitespace-nowrap z-[60] pointer-events-none">
                          <span className="text-emerald-400">Conversational focus mode</span><br />
                          <span className="text-gray-300 font-normal">Collapses previous AI steps when finished</span>
                        </div>
                      </div>

                      <div className="flex flex-col items-end hidden md:flex">
                        <div className="text-[10px] font-bold text-gray-400 dark:text-gray-500 uppercase tracking-widest mb-1">
                          Token Usage
                        </div>
                        <div className="flex items-center gap-2">
                          <div className="w-24 h-1.5 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
                            <div
                              className={`h-full transition-all duration-700 ease-out ${tokenUsage?.percentage > 80 ? 'bg-red-500' : 'bg-indigo-500'}`}
                              style={{ width: `${Math.min(tokenUsage?.percentage || 0, 100)}%` }}
                            ></div>
                          </div>
                          <span className={`text-xs font-mono font-bold ${tokenUsage?.percentage > 80 ? 'text-red-500' : 'text-gray-400'}`}>
                            {tokenUsage?.percentage || 0}%
                          </span>
                        </div>
                      </div>
                    </div>
                    <div className="relative group/clearchat">
                      <button
                        onClick={handleClearHistory}
                        disabled={isClearingHistory}
                        className="text-xs font-bold px-4 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-600 dark:text-gray-300 rounded-lg transition-all active:scale-95 disabled:opacity-50"
                      >
                        {isClearingHistory ? '...' : 'Clear Chat'}
                      </button>
                      <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 border border-gray-700 text-white text-[10px] font-bold rounded shadow-xl opacity-0 group-hover/clearchat:opacity-100 transition-all whitespace-nowrap z-[60] pointer-events-none text-center">
                        <span className="text-amber-400">Clear Chat History</span><br />
                        <span className="text-gray-300 font-normal">Nodes &amp; workspace sync are preserved</span>
                      </div>
                    </div>
                    <button
                      onClick={() => handleSendChat("/new")}
                      className="text-xs font-bold px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-all shadow-md hover:shadow-indigo-500/20 active:scale-95"
                    >
                      + NEW
                    </button>
                  </div>
                </h2>

                <div className="flex-grow flex flex-col min-h-0">
                  <ChatArea
                    chatHistory={chatHistory}
                    onSendMessage={handleSendChat}
                    onCancel={handleCancelChat}
                    isProcessing={isProcessing}
                    featureName="swarm_control"
                    workspaceId={workspaceId}
                    syncConfig={activeSyncConfig}
                    autoCollapse={autoCollapse}
                    isSourceDisconnected={
                      activeSyncConfig?.source === 'node_local' &&
                      activeSyncConfig?.source_node_id &&
                      (() => {
                        const sourceNode = accessibleNodes.find(n => n.node_id === activeSyncConfig.source_node_id);
                        return !sourceNode || (sourceNode.last_status !== 'online' && sourceNode.last_status !== 'idle');
                      })()
                    }
                  />
                </div>
              </div>

              <SwarmControlFileExplorerOverlay
                showFileExplorer={showFileExplorer}
                workspaceId={workspaceId}
                attachedNodeIds={attachedNodeIds}
                setShowFileExplorer={setShowFileExplorer}
              />
            </div>

            <SwarmControlConsoleOverlay
              showConsole={showConsole}
              attachedNodeIds={attachedNodeIds}
              accessibleNodes={accessibleNodes}
              isConsoleExpanded={isConsoleExpanded}
              consoleHeight={consoleHeight}
              handleConsoleDragStart={handleConsoleDragStart}
              setIsConsoleExpanded={setIsConsoleExpanded}
              isProcessing={isProcessing}
            />
          </div>
        </div>

      <SwarmControlNodeSelectorModal
        show={showNodeSelector}
        onClose={() => setShowNodeSelector(false)}
        onCancel={() => {
          setShowNodeSelector(false);
          isEditingMeshRef.current = false;
          fetchNodeInfo();
        }}
        accessibleNodes={accessibleNodes}
        attachedNodeIds={attachedNodeIds}
        syncConfig={syncConfig}
        setSyncConfig={setSyncConfig}
        workspaceId={workspaceId}
        isSearchingPath={isSearchingPath}
        showPathSuggestions={showPathSuggestions}
        setShowPathSuggestions={setShowPathSuggestions}
        pathSuggestions={pathSuggestions}
        setPathSuggestions={setPathSuggestions}
        handleInitiateSync={handleInitiateSync}
        isInitiatingSync={isInitiatingSync}
        handleToggleNode={handleToggleNode}
        handleToggleReadOnly={handleToggleReadOnly}
      />

      {/* Error Modal */}
      {showErrorModal && (
        <div className="fixed inset-0 bg-gray-900/60 backdrop-blur-sm flex justify-center items-center z-50 animate-in fade-in duration-300">
          <div className="bg-white dark:bg-gray-800 p-8 rounded-2xl shadow-2xl max-w-sm w-full text-center border border-red-100 dark:border-red-900/30">
            <div className="w-16 h-16 bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
              <svg className="w-8 h-8 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
            </div>
            <h2 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">Attention Required</h2>
            <p className="text-gray-500 dark:text-gray-400 mb-6 text-sm">{errorMessage}</p>
            <button
              onClick={() => setShowErrorModal(false)}
              className="w-full bg-gray-900 dark:bg-white dark:text-gray-900 text-white font-bold py-3 rounded-xl transition-all active:scale-95"
            >
              Understand
            </button>
          </div>
        </div>
      )}

      {showConfigModal && (
        <div className="fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex justify-center items-center z-50">
          <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-md overflow-hidden animate-in zoom-in-95 duration-200">
            <div className="px-6 py-5 border-b border-gray-100 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 flex justify-between items-center">
              <h3 className="text-lg font-bold text-gray-900 dark:text-gray-100 flex items-center gap-2">
                <svg className="w-5 h-5 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
                Session Engine
              </h3>
              <button onClick={() => setShowConfigModal(false)} className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 p-2">
                <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" /></svg>
              </button>
            </div>
            <div className="p-8 space-y-6">
              <div>
                <label className="block text-xs font-bold text-gray-400 dark:text-gray-500 uppercase tracking-widest mb-2">Active LLM Provider</label>
                <select
                  value={localActiveLLM}
                  onChange={(e) => setLocalActiveLLM(e.target.value)}
                  className="w-full border-2 border-gray-100 dark:border-gray-700 rounded-xl p-3 bg-white dark:bg-gray-800 text-sm font-medium focus:border-indigo-500 focus:ring-0 transition-all outline-none"
                >
                  <option value="">-- Choose Provider --</option>
                  {userConfigData?.effective?.llm?.providers && Object.keys(userConfigData.effective.llm.providers).map(pid => {
                    const modelName = userConfigData.effective.llm.providers[pid].model;
                    return (
                      <option key={pid} value={pid}>
                        {pid} {modelName ? `(${modelName})` : ''}
                      </option>
                    );
                  })}
                </select>
              </div>
            </div>
            <div className="px-8 py-5 bg-gray-50 dark:bg-gray-800/50 border-t border-gray-100 dark:border-gray-700 flex justify-end gap-3">
              <button
                onClick={() => setShowConfigModal(false)}
                className="px-6 py-2.5 text-sm font-bold text-gray-500 hover:text-gray-800 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={handleSaveQuickConfig}
                className="px-6 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl font-bold text-sm shadow-lg shadow-indigo-500/20 active:scale-95 transition-all"
              >
                Apply Changes
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Clear Chat Confirmation Modal */}
      {showClearChatModal && (
        <div className="fixed inset-0 bg-gray-900/60 backdrop-blur-sm flex justify-center items-center z-50 animate-in fade-in duration-300">
          <div className="bg-white dark:bg-gray-800 p-8 rounded-2xl shadow-2xl max-w-sm w-full text-center border border-amber-100 dark:border-amber-900/30">
            <div className="w-16 h-16 bg-amber-100 dark:bg-amber-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
              <svg className="w-8 h-8 text-amber-600 dark:text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>
            </div>
            <h2 className="text-xl font-bold mb-2 text-gray-900 dark:text-white">Clear Chat History?</h2>
            <p className="text-gray-500 dark:text-gray-400 mb-6 text-sm">
              This will permanently delete all messages in this session. Your attached nodes, workspace files, and mesh configurations will be <strong>preserved</strong>.
            </p>
            <div className="flex gap-3 mt-4">
              <button
                onClick={() => setShowClearChatModal(false)}
                className="flex-1 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-900 dark:text-white font-bold py-3 rounded-xl transition-all active:scale-95"
              >
                Cancel
              </button>
              <button
                onClick={confirmClearHistory}
                disabled={isClearingHistory}
                className="flex-1 bg-amber-600 hover:bg-amber-700 text-white font-bold py-3 rounded-xl transition-all shadow-lg shadow-amber-600/20 active:scale-95 disabled:opacity-50 flex items-center justify-center gap-2"
              >
                {isClearingHistory ? (
                  <>
                    <svg className="animate-spin h-4 w-4 text-white" fill="none" viewBox="0 0 24 24"><circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle><path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
                    Clearing...
                  </>
                ) : 'Clear Chat'}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default CodeAssistantPage;