/**
 * Companion text module: AI-generated or fallback text for greetings,
 * letter introductions, and forest comments.
 *
 * Strategy: Try Gemini API first (with rate-limit check), fall back
 * to curated static texts when API is unavailable.
 */

import { companions } from "./characters";
import type { CompanionType } from "../types";
import { loadConfig } from "../api/config";
import { generateText, checkRateLimit, incrementApiCall } from "../api/gemini";
import {
	type TimeOfDay,
	getRandomFallbackGreeting,
	getFallbackLetterIntro,
	getRandomFallbackForestComment,
} from "./fallbacks";

function getTimeOfDay(): TimeOfDay {
	const hour = new Date().getHours();
	if (hour < 12) return "morgen";
	if (hour < 17) return "mittag";
	return "abend";
}

function getCompanion(type: CompanionType) {
	return companions.find((c) => c.type === type)!;
}

export async function getGreeting(
	characterType: CompanionType,
	db: IDBDatabase,
): Promise<string> {
	const timeOfDay = getTimeOfDay();
	const config = await loadConfig();
	if (!config) return getRandomFallbackGreeting(timeOfDay);

	const canCall = await checkRateLimit(db, "text");
	if (!canCall) return getRandomFallbackGreeting(timeOfDay);

	const companion = getCompanion(characterType);
	const systemPrompt = `Du bist ${companion.name}, ein(e) ${companion.personality} im Zauberwald.
Du sprichst mit einem 7-jährigen Kind, das Tippen lernt.

Regeln:
- Max. 2 kurze Sätze (insgesamt max. 25 Wörter)
- Einfache Sprache, kurze Wörter
- Freundlich und warm, nie belehrend
- Keine Bewertung von Leistung
- Kein Englisch
- Beziehe dich auf die Tageszeit: ${timeOfDay}`;

	const result = await generateText(
		"Schreib eine Begrüssung.",
		systemPrompt,
		config,
	);
	if (!result) return getRandomFallbackGreeting(timeOfDay);

	await incrementApiCall(db, "text");
	return result;
}

export async function getLetterIntro(
	characterType: CompanionType,
	letter: string,
	fingerDescription: string,
	db: IDBDatabase,
): Promise<string> {
	const config = await loadConfig();
	if (!config) {
		return (
			getFallbackLetterIntro(letter)?.text ??
			"Drücke die leuchtende Taste!"
		);
	}

	const canCall = await checkRateLimit(db, "text");
	if (!canCall) {
		return (
			getFallbackLetterIntro(letter)?.text ??
			"Drücke die leuchtende Taste!"
		);
	}

	const companion = getCompanion(characterType);
	const systemPrompt = `Du bist ${companion.name}, ein(e) ${companion.personality} im Zauberwald.
Du stellst einem 7-jährigen Kind den Buchstaben ${letter} vor.

Regeln:
- Max. 2 Sätze (max. 25 Wörter)
- Erkläre, welcher Finger den Buchstaben drückt: ${fingerDescription}
- Verwende eine bildhafte Eselsbrücke, die zum Wald/Natur/Tiere-Thema passt
- Einfache Sprache
- Kein Englisch`;

	const result = await generateText(
		"Stelle den Buchstaben vor.",
		systemPrompt,
		config,
	);
	if (!result) {
		return (
			getFallbackLetterIntro(letter)?.text ??
			"Drücke die leuchtende Taste!"
		);
	}

	await incrementApiCall(db, "text");
	return result;
}

export async function getForestComment(
	characterType: CompanionType,
	elementDescription: string,
	db: IDBDatabase,
): Promise<string> {
	const config = await loadConfig();
	if (!config) return getRandomFallbackForestComment();

	const canCall = await checkRateLimit(db, "text");
	if (!canCall) return getRandomFallbackForestComment();

	const companion = getCompanion(characterType);
	const systemPrompt = `Du bist ${companion.name}, ein(e) ${companion.personality} im Zauberwald.
Ein Kind hat gerade eine Tippübung abgeschlossen. Im Wald ist ein neues Wesen erschienen: ${elementDescription}.

Regeln:
- Max. 2 kurze Sätze (insgesamt max. 25 Wörter)
- Drücke Staunen und Freude aus
- Einfache Sprache für 7-Jährige
- Kein Lob für Leistung, sondern Begeisterung über das neue Waldelement
- Kein Englisch`;

	const result = await generateText(
		"Kommentiere das neue Element.",
		systemPrompt,
		config,
	);
	if (!result) return getRandomFallbackForestComment();

	await incrementApiCall(db, "text");
	return result;
}
