/**
 * Construtor de payload Vercel AI SDK para POST /api/chat do MinutaIA.
 *
 * Porta direta do backend/minutaia/payload.py para JavaScript.
 * Traduz o formato CearIA → formato exato do frontend MinutaIA.
 */

const EFFORT_MAP = { 1: "normal", 3: "profunda", 5: "muito_profunda" };
const THINKING_MAP = { 1: "low", 3: "medium", 5: "high" };
const VERBOSITY_MAP = { short: "curto", long: "longo", curto: "curto", longo: "longo" };

/**
 * Gera UUID v4 simples.
 */
function uuid() {
  return crypto.randomUUID?.() ||
    "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
      const r = (Math.random() * 16) | 0;
      return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
    });
}

/**
 * Monta o payload para POST /api/chat no formato Vercel AI SDK.
 *
 * @param {object} opts
 * @param {string} opts.prompt — Texto do prompt do usuário
 * @param {Array} opts.documents — [{id, nome, paginas, tokenCount}] (formato paginado)
 * @param {Array} [opts.models] — Modelos de referência no mesmo formato
 * @param {number} [opts.effort=4] — Nível de esforço (1-5)
 * @param {string} [opts.verbosity="long"] — "short" | "long"
 * @param {string} [opts.mode="minuta"]
 * @param {string} [opts.executionMode="instant"]
 * @param {boolean} [opts.rigoroso=true]
 * @param {string} [opts.chatId=""]
 * @param {boolean} [opts.jurisprudencia=true]
 * @param {boolean} [opts.legislacao=true]
 * @param {boolean} [opts.contadoria=false]
 * @param {boolean} [opts.geracaoParalela=false]
 * @param {boolean} [opts.contextoInteligente=false]
 * @param {string} [opts.profileId=""]
 * @returns {object} Payload pronto para enviar ao MinutaIA
 */
export function buildPayload(opts) {
  const {
    prompt,
    documents,
    models = null,
    effort = 4,
    verbosity = "long",
    mode = "minuta",
    executionMode = "instant",
    rigoroso = true,
    chatId = "",
    jurisprudencia = true,
    legislacao = true,
    contadoria = false,
    geracaoParalela = false,
    contextoInteligente = false,
    profileId = "",
  } = opts;

  let totalTokens = documents.reduce((s, d) => s + (d.tokenCount || 0), 0);
  if (models) {
    totalTokens += models.reduce((s, m) => s + (m.tokenCount || 0), 0);
  }

  // Mapear effort para o valor mais próximo no mapa
  const closestEffort = [1, 3, 5].reduce((prev, curr) =>
    Math.abs(curr - effort) < Math.abs(prev - effort) ? curr : prev
  );
  const modo = EFFORT_MAP[closestEffort];
  const thinkingLevel = THINKING_MAP[closestEffort];
  const verbosityMode = VERBOSITY_MAP[verbosity] || "longo";

  const context = {
    modo,
    modoRigoroso: rigoroso,
    esforco: effort,
    isExperimentalMode: false,
    verbosityMode,
    totalTokenCount: totalTokens,
    documentos: documents,
  };
  if (models && models.length > 0) context.modelos = models;
  if (profileId) context.profileId = profileId;

  const agentOpts = {
    jurisprudencia,
    legislacao,
    modelos: !!(models && models.length),
    contadoria,
    geracaoParalela,
    contextoInteligente,
  };

  const messageText = `#createdocument\n\n${prompt}`;

  return {
    interactionMode: mode,
    executionMode,
    thinkingLevel,
    agentAutoOptions: agentOpts,
    modelId: "gemini",
    id: chatId || uuid(),
    messages: [
      {
        role: "user",
        parts: [{ type: "text", text: messageText }],
        metadata: {
          displayContent: prompt,
          context,
          totalTokenCount: totalTokens,
          agentAutoOptions: agentOpts,
        },
      },
    ],
  };
}

/**
 * Converte documentos do formato CearIA para formato paginado do MinutaIA.
 * {content, fileName, pageCount, tokenCount} → {id, nome, paginas: [{numero, texto}], tokenCount}
 *
 * @param {Array} rawDocuments
 * @returns {Array}
 */
export function prepareDocuments(rawDocuments) {
  return rawDocuments.map((doc, i) => {
    const content = doc.content || "";
    const fileName = doc.fileName || `documento_${i + 1}`;
    const tokenCount = doc.tokenCount || Math.floor(content.length / 4);

    const chunks = content.split("\n\n").filter(c => c.trim());
    const pages = chunks.length > 0
      ? chunks.map((chunk, j) => ({ numero: j + 1, texto: chunk.trim() }))
      : [{ numero: 1, texto: content }];

    return {
      id: uuid(),
      nome: fileName,
      paginas: pages,
      tokenCount,
    };
  });
}

/**
 * Converte modelos de referência para formato paginado.
 * {content, title} → {id, nome, paginas, tokenCount}
 *
 * @param {Array} rawModels
 * @returns {Array}
 */
export function prepareModels(rawModels) {
  return rawModels.map((model, i) => {
    const content = model.content || "";
    const title = model.title || `Modelo ${i + 1}`;
    return {
      id: uuid(),
      nome: title,
      paginas: [{ numero: 1, texto: content }],
      tokenCount: Math.floor(content.length / 4),
    };
  });
}
