import { GoogleGenAI, Type } from "@google/genai"; const ai = new GoogleGenAI({ apiKey: process.env.API_KEY }); export interface DetailedSearchResult { title: string; uri: string; lat?: number; lng?: number; } export const geminiService = { async searchNearbyWiFi(query: string, location: { lat: number, lng: number }) { try { console.log("Stage 1: 정보 검색 시작..."); // Stage 1: Google Search/Maps Grounding을 통해 원시 데이터 확보 const searchResponse = await ai.models.generateContent({ model: "gemini-2.5-flash", contents: `내 위치(위도: ${location.lat}, 경도: ${location.lng}) 주변에서 "${query}" 장소들을 찾아주세요. 각 장소의 이름, 주소, 그리고 가능한 경우 위도와 경도 정보를 상세히 포함해서 답변해 주세요.`, config: { tools: [{ googleSearch: {} }, { googleMaps: {} }], toolConfig: { retrievalConfig: { latLng: { latitude: location.lat, longitude: location.lng } } } }, }); const rawText = searchResponse.text || ""; console.log("Stage 1 원문 결과:", rawText); if (!rawText) { return { text: "검색 결과를 가져오지 못했습니다.", results: [] }; } console.log("Stage 2: 데이터 구조화 추출 시작..."); // Stage 2: 획득한 텍스트에서 JSON 형태로 좌표 및 정보 정밀 추출 const parseResponse = await ai.models.generateContent({ model: "gemini-3-flash-preview", contents: `다음은 주변 장소 검색 결과 텍스트입니다. 이 텍스트에서 언급된 모든 장소를 추출하여 JSON 배열로 응답해 주세요. 각 객체는 title, uri(구글맵 링크), lat(숫자), lng(숫자) 속성을 가져야 합니다. 좌표가 텍스트에 직접 없더라도 문맥상 추론 가능하거나 본문에 포함되어 있다면 반드시 숫자로 변환하세요. 텍스트: ${rawText}`, config: { responseMimeType: "application/json", responseSchema: { type: Type.ARRAY, items: { type: Type.OBJECT, properties: { title: { type: Type.STRING, description: "장소 이름" }, uri: { type: Type.STRING, description: "구글 맵 링크" }, lat: { type: Type.NUMBER, description: "위도 (Latitude)" }, lng: { type: Type.NUMBER, description: "경도 (Longitude)" }, }, required: ["title", "lat", "lng"] } } } }); let results: DetailedSearchResult[] = []; try { results = JSON.parse(parseResponse.text || "[]"); console.log("Stage 2 추출 성공:", results); } catch (e) { console.error("JSON 파싱 실패:", e); } return { text: rawText, results }; } catch (error: any) { console.error("Gemini 검색 에러:", error); return { text: `에러: ${error.message}`, results: [] }; } } };