import { NextResponse, NextRequest } from "next/server"; import { createServiceClient } from "@/lib/supabase"; import { requireAdmin } from "@/lib/admin-auth"; export const dynamic = "force-dynamic"; type DateRange = "today" | "7days" | "30days"; function getDateRange(range: DateRange): { start: string; end: string } { const end = new Date(); const start = new Date(); switch (range) { case "today": start.setHours(0, 0, 0, 0); break; case "7days": start.setDate(start.getDate() - 7); break; case "30days": start.setDate(start.getDate() - 30); break; } return { start: start.toISOString(), end: end.toISOString() }; } export async function GET(request: NextRequest) { const check = await requireAdmin(); if (check instanceof NextResponse) return check; const searchParams = request.nextUrl.searchParams; const range = (searchParams.get("range") || "today") as DateRange; const { start, end } = getDateRange(range); try { const db = createServiceClient(); const todayStart = new Date(); todayStart.setHours(0, 0, 0, 0); const todayISO = todayStart.toISOString(); const { count: todayCount } = await db .from("phone_clicks") .select("*", { count: "exact" }) .gte("timestamp", todayISO) .lte("timestamp", new Date().toISOString()); const callsToday = todayCount || 0; const yesterdayStart = new Date(todayStart); yesterdayStart.setDate(yesterdayStart.getDate() - 1); const yesterdayEnd = new Date(yesterdayStart); yesterdayEnd.setDate(yesterdayEnd.getDate() + 1); const { count: yesterdayCount } = await db .from("phone_clicks") .select("*", { count: "exact" }) .gte("timestamp", yesterdayStart.toISOString()) .lt("timestamp", yesterdayEnd.toISOString()); const callsYesterday = yesterdayCount || 0; const callsTodayTrend = callsYesterday > 0 ? Math.round(((callsToday - callsYesterday) / callsYesterday) * 100) : callsToday > 0 ? 100 : 0; const { data: uniqueData } = await db .from("phone_clicks") .select("phone_number") .gte("timestamp", start) .lte("timestamp", end); const uniqueNumbers = new Set((uniqueData || []).map((d) => d.phone_number)).size; const { data: elementData } = await db .from("phone_clicks") .select("source_element") .gte("timestamp", start) .lte("timestamp", end); const elementCounts: Record = {}; (elementData || []).forEach((item) => { elementCounts[item.source_element] = (elementCounts[item.source_element] || 0) + 1; }); const totalClicks = elementData?.length || 0; const elementEntries = Object.entries(elementCounts).sort(([, a], [, b]) => b - a); const [topSourceElement, topSourceElementCount] = elementEntries[0] || [null, 0]; const topSourceElementPercent = totalClicks > 0 ? Math.round((topSourceElementCount / totalClicks) * 100) : 0; const numberCounts: Record = {}; (uniqueData || []).forEach((item) => { numberCounts[item.phone_number] = (numberCounts[item.phone_number] || 0) + 1; }); const phoneNumbers = Object.entries(numberCounts) .map(([phone_number, click_count]) => ({ phone_number, click_count })) .sort((a, b) => b.click_count - a.click_count); const elements = Object.entries(elementCounts) .map(([source_element, count]) => ({ source_element, count, percent: totalClicks > 0 ? Math.round((count / totalClicks) * 100) : 0, })) .sort((a, b) => b.count - a.count); const { data: timeseriesRaw } = await db .from("phone_clicks") .select("timestamp") .gte("timestamp", start) .lte("timestamp", end) .order("timestamp", { ascending: true }); const timeseriesMap: Record = {}; (timeseriesRaw || []).forEach((item) => { const date = item.timestamp.split("T")[0]; timeseriesMap[date] = (timeseriesMap[date] || 0) + 1; }); const timeseries = Object.entries(timeseriesMap).map(([date, count]) => ({ date, count })); return NextResponse.json({ kpis: { callsToday, callsTodayTrend, uniqueNumbers, topSourceElement, topSourceElementPercent }, phoneNumbers, elements, timeseries, }); } catch (error) { console.error("Phone calls analytics error:", error); return NextResponse.json({ error: "Internal server error" }, { status: 500 }); } }