// /respuesta/respuestaBrave.js
import fs from 'fs/promises';
import { log } from '../logger.js';
import {
  sendText,
  fetchChatMessages,
  setTypingStatus
} from '../whatsapp.js';
import { processMessage } from '../utils/processMessage.js';
import { saveMedia } from '../utils/saveMedia.js';

import { GoogleGenAI } from '@google/genai';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';

function sanitizeSchema(obj) {
  if (Array.isArray(obj)) return obj.map(sanitizeSchema);
  if (obj && typeof obj === 'object') {
    const out = {};
    for (const [k, v] of Object.entries(obj)) {
      if (k === 'additionalProperties' || k === '$schema') continue;
      out[k] = sanitizeSchema(v);
    }
    return out;
  }
  return obj;
}

const cleanForGemini = ({ media, reactions, preview, ...rest }) => rest;

export async function respuestaBrave(msg) {
  const text = msg.text || '';

  setTypingStatus(msg.chatId, true);
  log('info', '🧠  Generando respuesta para @nucleo (Brave)…');

  try {
    const allraw = await fetchChatMessages(msg.chatId);
    const allMsgs = allraw.map(processMessage);

    const context = allMsgs.map(cleanForGemini);
    let json = JSON.stringify(context);
    while (json.length > 100_000 && context.length) {
      context.shift();
      json = JSON.stringify(context);
    }

    const chatName = context.length > 0 ? context[0]?.chatName : 'chat';
    const prompt = [
      `Eres un asistente con acceso a Brave Search mediante herramientas externas.`,
      `Pregunta del usuario: ${text}`,
      ...context
    ];

    const medias = allraw.filter(m => m.type !== 'chat');
    const settled = await Promise.allSettled(medias.map(saveMedia));

    const MAX = 20 * 1024 * 1024;
    let total = 0;
    const files = {};

    for (const r of settled) {
      if (r.status !== 'fulfilled' || !r.value) continue;
      const entries = Object.entries(r.value);
      if (entries.length === 0) continue;
      const [msgId, obj] = entries[0];
      let size = Number(obj.sizeBytes || 0);
      if (!size && obj.filePath) {
        try { size = (await fs.stat(obj.filePath)).size; } catch { size = 0; }
      }
      if (total + size > MAX && total > 0) break;
      if (size > MAX) continue;

      total += size;
      files[msgId] = { uri: obj.uri || obj.filePath, mimeType: obj.mimeType };
    }

    // === MCP Brave Search ===
    const client = new Client({ name: 'brave-agent', version: '1.0.0' });
    const serverParams = new StdioClientTransport({
        command: 'uvx',
        args: ['mcp-server-fetch']
      });
      
      
    await client.connect(serverParams);

    const mcp = await client.listTools();
    const tools = mcp.tools.map(t => ({
      name: t.name,
      description: t.description,
      parameters: sanitizeSchema({
        type: 'object',
        ...t.inputSchema
      })
    }));

    const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
    const response = await ai.models.generateContent({
      model: 'gemini-2.5-flash-preview-04-17',
      contents: prompt,
      config: {
        tools: [{ functionDeclarations: tools }],
        temperature: 0
      }
    });

    let respuesta;
    if (response.functionCalls && response.functionCalls.length > 0) {
      const call = response.functionCalls[0];
      const result = await client.callTool({ name: call.name, arguments: call.args });
      await client.close();
      respuesta = result.content?.[0]?.text ?? JSON.stringify(result);
    } else {
      await client.close();
      respuesta = response.text;
    }

    await sendText(msg.chatId, respuesta);
    log('info', '🧠  Respuesta enviada');

  } catch (error) {
    log('error', 'Error en respuestaBrave:', error);
    await sendText(msg.chatId, 'Hubo un error al procesar tu solicitud.');
  } finally {
    setTypingStatus(msg.chatId, false);
  }
}
