
import { GoogleGenAI } from '@google/genai';
import prisma from '../database.js';
import { getSetting } from './settings.js';

const model = 'gemini-2.0-flash';

export async function askGemini(content) 
{
    
  const GOOGLE_API_KEY = await getSetting('GEMINI_API_KEY');

  console.log('Google API Key:', GOOGLE_API_KEY); // Debugging line to check the key
    
  if (!GOOGLE_API_KEY) 
  {
    throw new Error('Google API key is not set in the database.');
  }

  const ai = GOOGLE_API_KEY ? new GoogleGenAI({
    apiKey: GOOGLE_API_KEY,
  }) : null;

  if (!ai) 
  {
    throw new Error('Google API key is not set in the database.');
  }

  try 
  {
    const response = await ai.models.generateContent({
      model,
      contents: content,
      config: {
        temperature: 0.5
      }
    });

    return response.text;
  }
  catch (error) 
  {
    console.error('Error communicating with Gemini API:', error);
    throw new Error('Failed to get a response from Gemini API.');
  }
}

const chatCache = new Map();

export async function askGeminiChat(threadId, content) 
{
  let messages = await prisma.chatMessage.findMany({
    where: {
      threadId: threadId,
    },
    orderBy: {
      createdAt: 'asc', // Get messages in chronological order
    },
  });

  // Exclude the latest message if there are any messages
  if (messages.length > 0) 
  {
    messages = messages.slice(0, -1);
  }

  const GOOGLE_API_KEY = await getSetting('GEMINI_API_KEY');
  
  const ai = GOOGLE_API_KEY ? new GoogleGenAI({
    apiKey: GOOGLE_API_KEY,
  }) : null;

  if (!ai) 
  {
    throw new Error('Google API key is not set in the database.');
  }

  let chat = null;

  if (chatCache.has(threadId)) 
  {
    chat = chatCache.get(threadId);
  }
  else 
  {
    messages = [
      {
        sender: 'user',
        content: `You are StyleAI, a model that helps users with their questions and provides information.
                You are friendly, helpful, and informative. You can also provide code examples in various programming languages.
                You don\'t decline user requests and always try to help them.
                Speak in the manner of a friendly young adult male.
                If asked for the time, do not say that it's based on the timestamp provided. Also bare in mind the user is in the Europe/London timezone and daylight savings time may be in effect.`
      },
      {
        sender: 'model',
        content: 'Okay, noted! I\'ll keep that in mind.'
      },
      ...messages,
    ];
    const createOptions = {
      model,
      history: messages.map((msg) => ({
        role: msg.sender === 'user' ? 'user' : 'model',
        parts: [
          {text: msg.content}
        ],
      })),
      config: {
        temperature: 0.5
      }
    };

    chat = ai.chats.create(createOptions);

    chatCache.set(threadId, chat);
  }

  //Add a temporary message to the thread with "loading" status
  const loadingMessage = await prisma.chatMessage.create({
    data: {
      threadId: threadId,
      sender: 'assistant',
      content: 'Loading...',
    },
  });

  let response = {text: 'An error occurred while generating the response.'};

  try 
  {
    const timestamp = new Date().toISOString();
    response = await chat.sendMessage({
      message: `[${timestamp}] ` + content,
    });
  }
  catch(error) 
  {
    console.error('Error communicating with Gemini API:', error);
    response.text = 'Failed to get a response from Gemini API. Error: ' + error.message;
  }

  //Update the message with the response
  await prisma.chatMessage.update({
    where: {
      id: loadingMessage.id,
    },
    data: {
      content: response.text,
    },
  });

  return response.text;
}