import { spawn } from 'child_process';
import fetch from 'node-fetch';

const SERVER_URL = 'http://127.0.0.1:4096';
const HEALTH_CHECK_INTERVAL = 500;
const MAX_RETRIES = 20;
const MODEL_CONFIG = {
  modelID: 'big-pickle',
  providerID: 'opencode'
};
// ’opencode‘ "glm-4.7-free"/ big-pickle
// ’"siliconflow-cn"‘ "Qwen/Qwen3-32B" Qwen/Qwen2.5-7B-Instruct  。zai-org/GLM-4.6

let serverProcess = null;

/**
 * 启动 opencode 服务器
 * @returns {ChildProcess} 服务器进程
 */
export function startOpencodeServer() {
  console.log('Starting opencode server...');
  const server = spawn('opencode', ['serve', '--port', '4096', '--hostname', '127.0.0.1'], {
    stdio: 'inherit',
    shell: true,
  });

  server.on('error', (err) => {
    if (err.message.includes('ENOENT')) {
      console.error('❌ opencode command not found. Please install it first:');
      console.error('   npm install -g @anomalyco/opencode');
    } else {
      console.error('Failed to start server:', err);
    }
    process.exit(1);
  });

  serverProcess = server;
  return server;
}

/**
 * 等待服务器就绪
 * @returns {Promise<boolean>} 服务器是否就绪
 */
export async function waitForServer() {
  let retries = 0;
  while (retries < MAX_RETRIES) {
    try {
      const res = await fetch(`${SERVER_URL}/global/health`);
      if (res.ok) {
        const data = await res.json();
        console.log(`✅ Server ready (version: ${data.version})`);
        return true;
      }
    } catch (e) {
      // server not up yet
    }
    await new Promise(r => setTimeout(r, HEALTH_CHECK_INTERVAL));
    retries++;
  }
  throw new Error('Server did not start in time');
}

/**
 * 创建会话
 * @returns {Promise<string>} 会话 ID
 */
export async function createSession() {
  console.log('Creating session...');
  const sessionRes = await fetch(`${SERVER_URL}/session`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ title: 'JS Client Session' })
  });

  if (!sessionRes.ok) throw new Error('Failed to create session');
  const session = await sessionRes.json();
  const sessionId = session.id;
  console.log(`Intialized session: ${sessionId}`);
  return sessionId;
}

/**
 * 发送消息到 opencode 服务器
 * @param {string} message 要发送的消息
 * @param {string} sessionId 可选的会话 ID,如果未提供则创建新会话
 * @returns {Promise<string>} AI 的回复
 */
export async function sendMessage(message, sessionId) {
  // 1. 创建会话(如果未提供)
  if (!sessionId) {
    sessionId = await createSession();
  } else {
    console.log(`Using existing session: ${sessionId}`);
  }

  // 2. 发送消息
  console.log(`Sending message: "${message}"`);

  const messageRes = await fetch(`${SERVER_URL}/session/${sessionId}/message`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      agent: 'build',
      model: MODEL_CONFIG,
      parts: [{ type: 'text', text: message }]
    })
  });

  if (!messageRes.ok) {
    const errorText = await messageRes.text();
    throw new Error(`Message send failed: ${messageRes.status} ${errorText}`);
  }

  const response = await messageRes.json();
  // 3. 提取 AI 回复
  let aiReply = '';
  for (const part of response.parts) {
    if (part.type === 'text') aiReply += part.text;
  }
  return aiReply;
}

/**
 * 停止服务器进程
 */
export function stopServer() {
  if (serverProcess) {
    console.log('Shutting down server...');
    serverProcess.kill();
    serverProcess = null;
  }
}

/**
 * 初始化并确保服务器就绪
 * @returns {Promise<void>}
 */
export async function initializeServer() {
  try {
    await waitForServer();
  } catch (e) {
    console.log('No running server detected. Starting one...');
    startOpencodeServer();
    await waitForServer();
  }
}