import "@supabase/functions-js/edge-runtime.d.ts"; const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", }; interface AnalyzeRequest { clinicName: string; services: string[]; address: string; scrapeData?: Record; } Deno.serve(async (req) => { if (req.method === "OPTIONS") { return new Response("ok", { headers: corsHeaders }); } try { const { clinicName, services, address } = (await req.json()) as AnalyzeRequest; const PERPLEXITY_API_KEY = Deno.env.get("PERPLEXITY_API_KEY"); if (!PERPLEXITY_API_KEY) { throw new Error("PERPLEXITY_API_KEY not configured"); } // Run multiple Perplexity queries in parallel const queries = [ { id: "competitors", prompt: `${address} 근처 ${services.slice(0, 3).join(", ")} 전문 성형외과/피부과 경쟁 병원 5곳을 분석해줘. 각 병원의 이름, 주요 시술, 온라인 평판, 마케팅 채널(블로그, 인스타그램, 유튜브)을 포함해줘. JSON 형식으로 응답해줘.`, }, { id: "keywords", prompt: `한국 ${services.slice(0, 3).join(", ")} 관련 검색 키워드 트렌드를 분석해줘. 네이버와 구글에서 월간 검색량이 높은 키워드 20개, 경쟁 강도, 추천 롱테일 키워드를 JSON 형식으로 제공해줘.`, }, { id: "market", prompt: `한국 ${services[0] || "성형외과"} 시장 트렌드 2025-2026을 분석해줘. 시장 규모, 성장률, 주요 트렌드(비수술 시술 증가, AI 마케팅, 외국인 환자 유치 등), 마케팅 채널별 효과를 JSON 형식으로 제공해줘.`, }, { id: "targetAudience", prompt: `${clinicName || services[0] + " 병원"}의 잠재 고객을 분석해줘. 연령대별, 성별, 관심 시술, 정보 탐색 채널(강남언니, 바비톡, 네이버, 인스타), 의사결정 요인을 JSON 형식으로 제공해줘.`, }, ]; const perplexityResults = await Promise.allSettled( queries.map(async (q) => { const response = await fetch( "https://api.perplexity.ai/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${PERPLEXITY_API_KEY}`, }, body: JSON.stringify({ model: "sonar", messages: [ { role: "system", content: "You are a Korean medical marketing analyst. Always respond in Korean. Provide data in valid JSON format when requested.", }, { role: "user", content: q.prompt }, ], temperature: 0.3, }), } ); const data = await response.json(); return { id: q.id, content: data.choices?.[0]?.message?.content || "", citations: data.citations || [], }; }) ); const analysis: Record = {}; for (const result of perplexityResults) { if (result.status === "fulfilled") { const { id, content, citations } = result.value; let parsed = content; const jsonMatch = content.match(/```json\n?([\s\S]*?)```/); if (jsonMatch) { try { parsed = JSON.parse(jsonMatch[1]); } catch { // Keep as string if JSON parse fails } } analysis[id] = { data: parsed, citations }; } } return new Response( JSON.stringify({ success: true, data: { clinicName, services, address, analysis, analyzedAt: new Date().toISOString() }, }), { headers: { ...corsHeaders, "Content-Type": "application/json" } } ); } catch (error) { return new Response( JSON.stringify({ success: false, error: error.message }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } } ); } });