import 'server-only'
import { spawn } from 'node:child_process'

/**
 * Fire-and-forget SSH to the home Mac mini to start a transient Claude session.
 * Mirrors eorganize's "Start AI pass" launcher and steward's capture trigger.
 *
 * The Mac's authorized_keys entry uses a forced command, so the only thing we
 * can send is the session UUID — it arrives as $SSH_ORIGINAL_COMMAND. The Mac
 * script detaches immediately, so ssh returns fast; we cap it anyway.
 *
 * Rejects on failure. Callers record the failure on the session row: a failed
 * launch must never take down the page the parent clicked from.
 */

interface SshConfig {
  user: string
  host: string
  port: number
  keyPath: string
  knownHostsPath: string
}

function readSshConfig(): SshConfig {
  return {
    user: process.env.AGENT_SSH_USER || 'erictran',
    host: process.env.AGENT_SSH_HOST || '67.182.44.118',
    port: Number(process.env.AGENT_SSH_PORT || 2222),
    keyPath: process.env.AGENT_SSH_KEY || '/etc/learn/agent_to_mac',
    knownHostsPath: process.env.AGENT_KNOWN_HOSTS || '/etc/learn/known_hosts',
  }
}

export function triggerAgent(sessionId: string): Promise<void> {
  const cfg = readSshConfig()
  const args = [
    '-i', cfg.keyPath,
    '-p', String(cfg.port),
    '-o', 'BatchMode=yes',
    '-o', 'ConnectTimeout=10',
    '-o', 'StrictHostKeyChecking=accept-new',
    '-o', `UserKnownHostsFile=${cfg.knownHostsPath}`,
    `${cfg.user}@${cfg.host}`,
    sessionId,
  ]

  return new Promise<void>((resolve, reject) => {
    const child = spawn('ssh', args, { stdio: ['ignore', 'pipe', 'pipe'] })
    let stderr = ''
    const timer = setTimeout(() => {
      child.kill('SIGTERM')
      reject(new Error('ssh timed out launching the agent'))
    }, 15_000)

    child.stderr.on('data', (chunk) => {
      stderr += chunk.toString()
      if (stderr.length > 2000) stderr = stderr.slice(-2000)
    })
    child.on('error', (err) => {
      clearTimeout(timer)
      reject(new Error(`ssh spawn failed: ${err.message}`))
    })
    child.on('exit', (code) => {
      clearTimeout(timer)
      if (code === 0) resolve()
      else reject(new Error(`ssh exited ${code}: ${stderr.trim() || '(no stderr)'}`))
    })
  })
}
