// 伺服器端呼叫已設定的 AI Provider（OpenCode Go / Grok）
const AI_PROVIDERS = {
  'opencode-go': {
    label: 'OpenCode Go',
    endpoint: 'https://opencode.ai/zen/go/v1/chat/completions',
    keyEnv: 'OPENCODE_GO_API_KEY',
    modelEnv: 'OPENCODE_GO_MODEL',
    mode: 'chat',
  },
  grok: {
    label: 'Grok',
    endpoint: 'https://api.x.ai/v1/responses',
    keyEnv: 'GROK_API_KEY',
    modelEnv: 'GROK_MODEL',
    mode: 'responses',
  },
};

function normalizeAIText(data, mode) {
  if (mode === 'responses') {
    if (data?.output_text) return data.output_text;
    const chunks = [];
    for (const item of data?.output || []) {
      for (const c of item?.content || []) {
        if (typeof c?.text === 'string') chunks.push(c.text);
        else if (typeof c?.content === 'string') chunks.push(c.content);
      }
    }
    return chunks.join('\n').trim();
  }
  return data?.choices?.[0]?.message?.content || data?.choices?.[0]?.text || '';
}

export function getActiveAIConfig() {
  const providerId = String(process.env.AI_ACTIVE_PROVIDER || 'grok').trim();
  const provider = AI_PROVIDERS[providerId];
  if (!provider) return null;
  const apiKey = String(process.env[provider.keyEnv] || '').trim();
  const model = String(process.env[provider.modelEnv] || '').trim();
  if (!apiKey) return null;
  return { providerId, provider, apiKey, model };
}

export function extractJSONObject(text) {
  const raw = String(text || '').trim();
  const fenced = raw.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1];
  const candidate = fenced || raw;
  const start = candidate.indexOf('{');
  const end = candidate.lastIndexOf('}');
  if (start < 0 || end <= start) return null;
  try {
    return JSON.parse(candidate.slice(start, end + 1));
  } catch {
    return null;
  }
}

export async function callAI({ system, user, temperature = 0.15, timeoutMs = 90000 }) {
  const cfg = getActiveAIConfig();
  if (!cfg) return { ok: false, error: 'no_ai_key', text: null };
  let { model, provider, apiKey, providerId } = cfg;
  if (!model) model = 'grok-3-mini';

  const ctrl = new AbortController();
  const timer = setTimeout(() => ctrl.abort(), timeoutMs);
  try {
    const body = provider.mode === 'responses'
      ? { model, store: false, temperature, input: [{ role: 'system', content: system }, { role: 'user', content: user }] }
      : { model, temperature, messages: [{ role: 'system', content: system }, { role: 'user', content: user }] };
    const r = await fetch(provider.endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
      body: JSON.stringify(body),
      signal: ctrl.signal,
    });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) {
      return { ok: false, error: data?.error?.message || data?.message || `HTTP ${r.status}`, text: null, providerId };
    }
    return { ok: true, text: normalizeAIText(data, provider.mode), providerId, model };
  } catch (e) {
    return { ok: false, error: String(e?.message || e), text: null, providerId };
  } finally {
    clearTimeout(timer);
  }
}