/**
 * Sandbox Client — connects the backend to the separate sandbox-service on Railway.
 * All sandbox operations are proxied to the sandbox service via HTTP.
 */

const SANDBOX_SERVICE_URL = process.env.SANDBOX_SERVICE_URL || 'http://localhost:4300';
const SANDBOX_SERVICE_SECRET = process.env.SANDBOX_SERVICE_SECRET || 'dev-sandbox-secret';

async function sandboxFetch(path, userId, body = null) {
  const opts = {
    method: body ? 'POST' : 'GET',
    headers: {
      'Content-Type': 'application/json',
      'x-sandbox-secret': SANDBOX_SERVICE_SECRET,
      'x-user-id': String(userId),
    },
  };
  if (body) opts.body = JSON.stringify(body);

  const res = await fetch(`${SANDBOX_SERVICE_URL}${path}`, opts);
  const data = await res.json();
  if (!res.ok) throw new Error(data.error || `Sandbox service error: ${res.status}`);
  return data;
}

const sandboxClient = {

  /**
   * Check if the sandbox service is reachable.
   */
  async isAvailable() {
    try {
      const res = await fetch(`${SANDBOX_SERVICE_URL}/health`, { signal: AbortSignal.timeout(3000) });
      return res.ok;
    } catch {
      return false;
    }
  },

  /**
   * Initialize a user's sandbox (creates if doesn't exist).
   */
  async initSandbox(userId) {
    return sandboxFetch('/api/sandbox/init', userId, {});
  },

  /**
   * Get sandbox status.
   */
  async getStatus(userId) {
    return sandboxFetch('/api/sandbox/status', userId);
  },

  /**
   * Destroy a user's sandbox.
   */
  async destroySandbox(userId) {
    const res = await fetch(`${SANDBOX_SERVICE_URL}/api/sandbox`, {
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
        'x-sandbox-secret': SANDBOX_SERVICE_SECRET,
        'x-user-id': String(userId),
      },
    });
    const data = await res.json();
    if (!res.ok) throw new Error(data.error || 'Failed to destroy sandbox');
    return data;
  },

  /**
   * Execute a command in the user's sandbox.
   */
  async exec(userId, command, opts = {}) {
    return sandboxFetch('/api/exec', userId, {
      command,
      cwd: opts.cwd,
      timeout: opts.timeout,
      userKeys: opts.userKeys,
    });
  },

  /**
   * Read a file from the user's sandbox.
   */
  async readFile(userId, filePath) {
    return sandboxFetch('/api/file/read', userId, { filePath });
  },

  /**
   * Write a file to the user's sandbox.
   */
  async writeFile(userId, filePath, content) {
    return sandboxFetch('/api/file/write', userId, { filePath, content });
  },

  /**
   * Get file tree from the user's sandbox.
   */
  async getFileTree(userId, dirPath, depth = 3) {
    return sandboxFetch('/api/file/tree', userId, { dirPath, depth });
  },

  /**
   * Run a git command in the user's sandbox.
   */
  async gitOperation(userId, gitCommand, cwd) {
    return sandboxFetch('/api/git', userId, { gitCommand, cwd });
  },

  /**
   * Get the WebSocket URL for an interactive shell session.
   */
  getShellWsUrl(userId, sessionId) {
    const wsBase = SANDBOX_SERVICE_URL.replace(/^http/, 'ws');
    return `${wsBase}/shell?secret=${encodeURIComponent(SANDBOX_SERVICE_SECRET)}&userId=${userId}&sessionId=${sessionId || 'default'}`;
  },
};

export { sandboxClient, SANDBOX_SERVICE_URL };
