import { GoogleGenAI, Type } from "@google/genai"; import { EventCategory, CalendarEvent, AppSettings } from "../types"; import { v4 as uuidv4 } from 'uuid'; const apiKey = process.env.API_KEY || ''; const ai = new GoogleGenAI({ apiKey }); // --- Event Parsing --- export const parseNaturalLanguageEvent = async ( input: string, referenceDate: Date = new Date() ): Promise<{ title: string; startTime: string; endTime: string; description?: string; category: EventCategory } | null> => { if (!apiKey) { console.warn("No API Key found for Gemini"); return null; } try { const model = 'gemini-3-flash-preview'; const prompt = ` Current Date context: ${referenceDate.toISOString()} User Input: "${input}" Extract event details. Categorize into one of: 'general', 'chore', 'date', 'work', 'fun'. If it sounds romantic, it's a date. If it's cleaning/shopping, it's a chore. `; const response = await ai.models.generateContent({ model, contents: prompt, config: { responseMimeType: "application/json", responseSchema: { type: Type.OBJECT, properties: { title: { type: Type.STRING }, startTime: { type: Type.STRING, description: "ISO 8601 format date string" }, endTime: { type: Type.STRING, description: "ISO 8601 format date string" }, description: { type: Type.STRING }, category: { type: Type.STRING, enum: ['general', 'chore', 'date', 'work', 'fun'] } }, required: ["title", "startTime", "endTime", "category"] } } }); const text = response.text; if (!text) return null; return JSON.parse(text); } catch (error) { console.error("Error parsing event with Gemini:", error); return null; } }; // --- Chat & Assistant --- export const generateChatResponse = async ( input: string, settings: AppSettings, userRole: string ): Promise<{ text: string; event?: CalendarEvent }> => { if (!apiKey) return { text: "I need a Gemini API Key to function properly." }; try { const model = 'gemini-3-flash-preview'; const systemPrompt = ` You are a mystical calendar oracle for a couple. Current Date: ${new Date().toISOString()} User Role: ${userRole} Mom's Sign: ${settings.momZodiac} Dad's Sign: ${settings.dadZodiac} If the user asks to create an event, output JSON with "isEvent": true. Otherwise, output JSON with "isEvent": false and a "message". Keep messages bubbly, mystical, and concise. `; const response = await ai.models.generateContent({ model, contents: `${systemPrompt}\n\nUser: ${input}`, config: { responseMimeType: "application/json", responseSchema: { type: Type.OBJECT, properties: { isEvent: { type: Type.BOOLEAN }, message: { type: Type.STRING }, title: { type: Type.STRING }, description: { type: Type.STRING }, startTime: { type: Type.STRING }, endTime: { type: Type.STRING }, category: { type: Type.STRING, enum: ['general', 'chore', 'date', 'work', 'fun', 'magic'] } }, required: ["isEvent"] } } }); const parsed = JSON.parse(response.text || "{}"); if (parsed.isEvent) { const newEvent: CalendarEvent = { id: uuidv4(), title: parsed.title || "New Event", description: parsed.description || "", startTime: parsed.startTime || new Date().toISOString(), endTime: parsed.endTime || new Date().toISOString(), category: (parsed.category as EventCategory) || 'general', createdBy: userRole as any }; return { text: parsed.message || `I've scheduled "${parsed.title}" for you!`, event: newEvent }; } else { return { text: parsed.message || "The stars are silent." }; } } catch (error) { console.error("Gemini Chat Error", error); return { text: "The cosmic connection is weak right now." }; } }; // --- Daily Horoscope --- export const generateDailyHoroscope = async ( momSign: string, dadSign: string, settings: AppSettings ): Promise => { if (!apiKey) return "Magic requires an API Key."; try { const model = 'gemini-3-flash-preview'; const prompt = ` Generate a very short, mystical horoscope prediction (max 10 words) for a couple with signs ${momSign} and ${dadSign} for today. Focus on their shared energy, love, or domestic life. `; const response = await ai.models.generateContent({ model, contents: prompt, config: { responseMimeType: "application/json", responseSchema: { type: Type.OBJECT, properties: { prediction: { type: Type.STRING } } } } }); const parsed = JSON.parse(response.text || "{}"); return parsed.prediction || "Cosmic energy flows through your home."; } catch (e) { return "The stars are aligning."; } }; // --- Schedule Suggestions --- export const analyzeScheduleAndSuggest = async ( events: CalendarEvent[], settings: AppSettings ): Promise => { if (!apiKey) return ["Plan a surprise dinner!", "Go for a moonlit walk.", "Cook a meal together."]; try { const model = 'gemini-3-flash-preview'; const eventsSummary = events.slice(0, 20).map(e => // Limit to 20 for context window efficiency `- ${e.title} (${e.category}) on ${e.startTime}` ).join('\n'); const prompt = ` Analyze this couple's schedule: ${eventsSummary} Based on these events, suggest 3 specific, thoughtful, or fun additional events they should add to balance their life. Look for missing date nights, overwhelming work blocks, or chores that need doing. Return 3 short strings. `; const response = await ai.models.generateContent({ model, contents: prompt, config: { responseMimeType: "application/json", responseSchema: { type: Type.ARRAY, items: { type: Type.STRING } } } }); return JSON.parse(response.text || "[]"); } catch (e) { return ["Plan a date night", "Take a rest day", "Organize the pantry"]; } };