import { fetchWithAuth, getUserId } from './apiClient';

/**
 * [USER] List nodes accessible to the current user's group.
 */
export const getUserAccessibleNodes = async () => {
  return await fetchWithAuth(`/nodes/`);
};

/**
 * [USER] Fetch node preferences.
 */
export const getUserNodePreferences = async () => {
  return await fetchWithAuth(`/nodes/preferences`);
};

/**
 * [USER] Update node preferences.
 */
export const updateUserNodePreferences = async (prefs) => {
  return await fetchWithAuth(`/nodes/preferences`, {
    method: "PATCH",
    body: prefs
  });
};

/**
 * [USER] Fetch sync status for all nodes attached to a session.
 */
export const getSessionNodeStatus = async (sessionId) => {
  return await fetchWithAuth(`/sessions/${sessionId}/nodes`);
};

/**
 * [USER] Attach more nodes to an active session.
 */
export const attachNodesToSession = async (sessionId, nodeIds, config = null) => {
  return await fetchWithAuth(`/sessions/${sessionId}/nodes`, {
    method: "POST",
    body: { node_ids: nodeIds, config }
  });
};

/**
 * [USER] Detach a node from a session.
 */
export const detachNodeFromSession = async (sessionId, nodeId) => {
  return await fetchWithAuth(`/sessions/${sessionId}/nodes/${nodeId}`, {
    method: "DELETE"
  });
};

/**
 * [AI Observability] Fetch terminal history for a node.
 */
export const getNodeTerminalHistory = async (nodeId) => {
  return await fetchWithAuth(`/nodes/${nodeId}/terminal`);
};

/**
 * Dispatch a task to a node.
 */
export const dispatchNodeTask = async (nodeId, payload) => {
  return await fetchWithAuth(`/nodes/${nodeId}/dispatch`, {
    method: 'POST',
    body: payload
  });
};

/**
 * Cancel a task on a node.
 */
export const cancelNodeTask = async (nodeId, taskId = "") => {
  return await fetchWithAuth(`/nodes/${nodeId}/cancel?task_id=${taskId}`, {
    method: 'POST'
  });
};

/**
 * WebSocket helper for live node streams.
 */
export const getNodeStreamUrl = (nodeId = null) => {
  const { API_BASE_URL } = require('./apiClient');
  const wsBase = API_BASE_URL.replace(/^http/, 'ws');
  const userId = getUserId();
  const token = localStorage.getItem('authToken');
  const params = new URLSearchParams({ user_id: userId });
  if (token) params.append('token', token);

  if (nodeId) {
    return `${wsBase}/nodes/${nodeId}/stream?${params.toString()}`;
  }
  return `${wsBase}/nodes/stream/all?${params.toString()}`;
};

/**
 * [FS] List directory contents on an agent node.
 */
export const nodeFsList = async (nodeId, path = ".", sessionId = null) => {
  const params = new URLSearchParams({ path });
  if (sessionId) params.append("session_id", sessionId);
  return await fetchWithAuth(`/nodes/${nodeId}/fs/ls?${params.toString()}`);
};

/**
 * [FS] Read file content from an agent node.
 */
export const nodeFsCat = async (nodeId, path, sessionId = null) => {
  const params = new URLSearchParams({ path });
  if (sessionId) params.append("session_id", sessionId);
  return await fetchWithAuth(`/nodes/${nodeId}/fs/cat?${params.toString()}`);
};

/**
 * [FS] Create or update a file or directory on an agent node.
 */
export const nodeFsTouch = async (nodeId, path, content = "", isDir = false, sessionId = null) => {
  return await fetchWithAuth(`/nodes/${nodeId}/fs/touch`, {
    method: "POST",
    body: { path, content, is_dir: isDir, session_id: sessionId }
  });
};

/**
 * [FS] Upload a file to an agent node via multipart form.
 */
export const nodeFsUpload = async (nodeId, path, file, sessionId = null) => {
  const formData = new FormData();
  formData.append("file", file);
  
  const params = new URLSearchParams({ path });
  if (sessionId) params.append("session_id", sessionId);

  return await fetchWithAuth(`/nodes/${nodeId}/fs/upload?${params.toString()}`, {
    method: "POST",
    body: formData
  });
};

/**
 * [FS] Downloads a file as a blob.
 */
export const nodeFsDownloadBlob = async (nodeId, path, sessionId = null) => {
  const params = new URLSearchParams({ path });
  if (sessionId) params.append("session_id", sessionId);
  
  const response = await fetchWithAuth(`/nodes/${nodeId}/fs/download?${params.toString()}`, {
    method: "GET",
    raw: true
  });
  return await response.blob();
};

/**
 * [FS] Delete a file or directory from an agent node.
 */
export const nodeFsRm = async (nodeId, path, sessionId = null) => {
  return await fetchWithAuth(`/nodes/${nodeId}/fs/rm`, {
    method: "POST",
    body: { path, session_id: sessionId }
  });
};

/**
 * Fetch status of pre-compiled binaries on the central hub.
 */
export const getBinaryStatus = async () => {
  return await fetchWithAuth(`/nodes/provision/binaries/status`);
};
