import { spawn } from 'node:child_process';

export interface RunnerOptions {
  claudeBin: string;
  repoPath: string;
  timeoutMs: number;
  onChunk?: (text: string) => void;
}

/**
 * Runs the local `claude` CLI as a sub-agent.
 * Uses the user's existing Claude subscription - no API key needed.
 */
export async function runClaudeCLI(task: string, opts: RunnerOptions): Promise<string> {
  const { claudeBin, repoPath, timeoutMs, onChunk } = opts;

  return new Promise((resolve, reject) => {
    const proc = spawn(claudeBin, ['-p', task], {
      cwd: repoPath,
      env: process.env,
    });

    let stdout = '';
    let stderr = '';
    let timedOut = false;

    const timer = setTimeout(() => {
      timedOut = true;
      proc.kill('SIGTERM');
      reject(new Error(`Claude timed out after ${Math.round(timeoutMs / 1000)}s`));
    }, timeoutMs);

    proc.stdout.on('data', (chunk: Buffer) => {
      const text = chunk.toString();
      stdout += text;
      onChunk?.(text);
    });

    proc.stderr.on('data', (chunk: Buffer) => {
      stderr += chunk.toString();
    });

    proc.on('close', (code) => {
      clearTimeout(timer);
      if (timedOut) return;

      if (code === 0) {
        resolve(stdout.trim());
      } else {
        const errSummary = stderr.slice(0, 500) || `Process exited with code ${code}`;
        reject(new Error(errSummary));
      }
    });

    proc.on('error', (err) => {
      clearTimeout(timer);
      reject(err);
    });
  });
}
