'use strict';

const { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold } = require("@google/generative-ai");

class GeminiProvider {
	constructor(config) {
		this.config = config;
		this.session = null;
	}

	async start(history) {
		const genAI = new GoogleGenerativeAI(this.config.key);
		const model = genAI.getGenerativeModel({
			model: this.config.model || "gemini-2.0-flash-exp",
		});

		this.session = model.startChat(this.__settings(history));
	}

	__settings(history) {
		return {
			generationConfig: {
				temperature: this.config.temperature || 1,
				topP: this.config.topP || 0.95,
				topK: this.config.topK || 64,
				maxOutputTokens: this.config.maxOutputTokens || 8192,
				responseMimeType: "application/json",
			},
			safetySettings: [
				{
					category: HarmCategory.HARM_CATEGORY_HARASSMENT,
					threshold: HarmBlockThreshold.BLOCK_NONE,
				},
				{
					category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
					threshold: HarmBlockThreshold.BLOCK_NONE,
				},
				{
					category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
					threshold: HarmBlockThreshold.BLOCK_NONE,
				},
				{
					category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
					threshold: HarmBlockThreshold.BLOCK_NONE,
				},
			],
			history: history || [
				{
					role: "user",
					parts: [{ text: this.config.prompt }],
				},
				{
					role: "model",
					parts: [{ text: "Chat stuff" }],
				},
			],
		};
	}

	async chat(message, retryCount = 0) {
		try {
			let result = await this.session.sendMessage(message);
			return result;
		} catch (error) {
			if (retryCount > 3) {
				throw new Error(`Gemini API error after ${retryCount} retries: ${error.message}`);
			}
			// Recover by removing last history entry and restarting
			this.session.params.history.pop();
			await this.start(this.session.params.history);
			return await this.chat(message, retryCount + 1);
		}
	}

	setPrompt(prompt) {
		this.config.prompt = prompt;
	}

	getResponse(result) {
		return result.response.text();
	}

	async close() {
		this.session = null;
	}
}

module.exports = GeminiProvider;