/**
 * Routes workspace AI chat to Gemini or an OpenAI-compatible API (e.g. DeepSeek).
 *
 * Env:
 *   VIBN_CHAT_PROVIDER=gemini | deepseek | openai_compatible
 *
 * Default: gemini (requires GOOGLE_API_KEY / studio key + VIBN_CHAT_MODEL).
 *
 * DeepSeek / OpenAI-compat:
 *   DEEPSEEK_API_KEY (or VIBN_OPENAI_COMPATIBLE_API_KEY)
 *   Optional: VIBN_OPENAI_COMPATIBLE_CHAT_URL (default https://api.deepseek.com/chat/completions)
 *   Optional: VIBN_OPENAI_COMPATIBLE_MODEL (default deepseek-chat)
 */

import type { ChatMessage, ToolDefinition } from "./gemini-chat";
import { callGeminiChat } from "./gemini-chat";
import { callOpenAiCompatibleChat } from "./openai-compatible-chat";
import { logTrainingTelemetry } from "./telemetry-db";

export type VibnChatCallOpts = {
  systemPrompt: string;
  messages: ChatMessage[];
  tools?: ToolDefinition[];
  temperature?: number;
  includeThoughts?: boolean;
  // Optional metadata for telemetry; not used by the model call itself.
  projectId?: string;
};

export async function callVibnChat(opts: VibnChatCallOpts) {
  const p = (process.env.VIBN_CHAT_PROVIDER || "gemini").toLowerCase().trim();
  const model =
    p === "deepseek" || p === "openai_compatible"
      ? process.env.VIBN_OPENAI_COMPATIBLE_MODEL || "deepseek-chat"
      : process.env.VIBN_CHAT_MODEL || "gemini-3.1-pro-preview";

  const startedAt = Date.now();
  const result =
    p === "deepseek" || p === "openai_compatible"
      ? await callOpenAiCompatibleChat(opts)
      : await callGeminiChat(opts);
  const durationMs = Date.now() - startedAt;

  // Fire-and-forget: capture this turn as training/diagnostic telemetry.
  // Never let logging interfere with the agent loop.
  try {
    logTrainingTelemetry({
      projectId: opts.projectId,
      model,
      systemPrompt: opts.systemPrompt,
      messages: opts.messages,
      response: {
        text: result.text ?? "",
        thoughts: result.thoughts ?? "",
        toolCalls: result.toolCalls ?? [],
      },
      metrics: { durationMs },
    });
  } catch {
    // ignore
  }

  return result;
}
