/**
 * Servico de AI — wrapper sobre Gemini 2.5 Flash com structured output.
 *
 * Cada chamada do AI block dentro do fluxo passa por aqui.
 * Retorna { reply, intent?, extracted? } via JSON mode do Gemini.
 */

import {
  GoogleGenerativeAI,
  type GenerativeModel,
} from "@google/generative-ai";
import { interpolate } from "./interpolator.js";

const MODEL_NAME = "gemini-2.5-flash";

let cachedModel: GenerativeModel | null = null;

function getModel(): GenerativeModel {
  if (cachedModel) return cachedModel;
  const key = process.env.GEMINI_API_KEY;
  if (!key) {
    throw new Error("GEMINI_API_KEY nao definida — bloqueia AI blocks");
  }
  const genai = new GoogleGenerativeAI(key);
  cachedModel = genai.getGenerativeModel({ model: MODEL_NAME });
  return cachedModel;
}

export type AiTurnInput = {
  systemPrompt: string;
  history: Array<{ role: "user" | "model"; content: string }>;
  userMessage: string;
  vars: Record<string, string>;
  exitIntents: string[];
};

export type AiTurnResult = {
  reply: string;
  intent?: string;
  extracted?: Record<string, string>;
};

export async function runAiTurn(input: AiTurnInput): Promise<AiTurnResult> {
  const model = getModel();

  const interpolatedSystem = interpolate(input.systemPrompt, input.vars);
  const intentList = input.exitIntents.map((i) => `'${i}'`).join(", ");

  const fullSystem = `${interpolatedSystem}

REGRAS DE SAIDA:
Voce DEVE responder em JSON valido com este formato:
{
  "reply": "sua resposta natural ao usuario, em portugues, conversacional",
  "intent": "um destes valores ou null: ${intentList}",
  "extracted": { "var_nome": "valor" } ou {}
}

Use 'intent' quando detectar com clareza que o usuario:
${input.exitIntents.map((i) => `  - ${i}`).join("\n")}

Se nao houver intent claro, deixe 'intent' como null e continue conversando.`;

  const chat = model.startChat({
    history: input.history.map((m) => ({
      role: m.role,
      parts: [{ text: m.content }],
    })),
    generationConfig: {
      responseMimeType: "application/json",
      temperature: 0.7,
    },
    systemInstruction: { role: "system", parts: [{ text: fullSystem }] },
  });

  const result = await chat.sendMessage(input.userMessage);
  const text = result.response.text();

  let parsed: AiTurnResult;
  try {
    parsed = JSON.parse(text);
  } catch {
    return { reply: text };
  }

  return {
    reply: parsed.reply ?? "",
    intent: parsed.intent && parsed.intent !== "null" ? parsed.intent : undefined,
    extracted: parsed.extracted && Object.keys(parsed.extracted).length > 0
      ? parsed.extracted
      : undefined,
  };
}
