import { NextRequest, NextResponse } from "next/server";
import { requireStaffAuth } from "@/lib/staff-auth";
import { prisma } from "@/lib/db";
import { getDataSource } from "@/lib/data-source";

export async function GET(request: NextRequest) {
  try {
    const user = await requireStaffAuth();
    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { searchParams } = new URL(request.url);
    const timeRange = searchParams.get("timeRange") || "week";

    // Calculate date range
    const now = new Date();
    const start = new Date();

    switch (timeRange) {
      case "today":
        start.setHours(0, 0, 0, 0);
        break;
      case "week":
        start.setDate(now.getDate() - 7);
        break;
      case "month":
        start.setMonth(now.getMonth() - 1);
        break;
    }

    // Convex branch -- fetch dashboard metrics from Convex
    if (getDataSource("analytics") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");
        const metrics = await convexQuery(
          "analytics/queries:getDashboardMetrics",
          {
            userId: user.id ?? user.email ?? "",
          },
        );

        if (metrics !== null) {
          // Map Convex response to the same shape the frontend expects
          return NextResponse.json({
            visits: {
              total: metrics.totalBookings ?? 0,
              unique: metrics.totalCustomers ?? 0,
              today: 0,
              week: timeRange === "week" ? (metrics.totalBookings ?? 0) : 0,
              month: timeRange === "month" ? (metrics.totalBookings ?? 0) : 0,
            },
            conversions: {
              visitorToDemo: 0,
              visitorToSignup: 0,
              demoToSignup: 0,
            },
            topPages: [],
            byCountry: {},
            byDevice: { Desktop: 0, Mobile: 0, Tablet: 0 },
          });
        }
      } catch {
        // Fall through to Prisma
      }
    }

    // Fetch from Prisma
    const [
      pTotalVisits,
      pUniqueVisitors,
      pDemos,
      pSignups,
      pTopPages,
      pVisitsByCountry,
      pVisitsByDevice,
    ] = await Promise.all([
      prisma.user_sessions.count({
        where: { createdAt: { gte: start } },
      }),
      prisma.user_sessions.groupBy({
        by: ["userId"],
        where: { createdAt: { gte: start } },
      }),
      prisma.demo_bookings.count({
        where: { createdAt: { gte: start } },
      }),
      prisma.users.count({
        where: {
          role: "CUSTOMER",
          createdAt: { gte: start },
        },
      }),
      prisma.site_visits.groupBy({
        by: ["page"],
        where: { createdAt: { gte: start } },
        _count: { page: true },
        orderBy: { _count: { page: "desc" } },
        take: 10,
      }),
      prisma.user_sessions.groupBy({
        by: ["country"],
        where: {
          createdAt: { gte: start },
          country: { not: null },
        },
        _count: { country: true },
        orderBy: { _count: { country: "desc" } },
      }),
      prisma.user_sessions.groupBy({
        by: ["deviceType"],
        where: { createdAt: { gte: start } },
        _count: { deviceType: true },
      }),
    ]);

    const totalVisits = pTotalVisits;
    const unique = pUniqueVisitors.length;
    const demos = pDemos;
    const signups = pSignups;

    // Conversions
    const visitorToDemo =
      unique > 0 ? ((demos / unique) * 100).toFixed(1) : "0";
    const visitorToSignup =
      unique > 0 ? ((signups / unique) * 100).toFixed(1) : "0";
    const demoToSignup = demos > 0 ? ((signups / demos) * 100).toFixed(1) : "0";

    const topPages = pTopPages.map((p) => ({
      page: p.page,
      visits: p._count.page,
    }));

    const byCountry: Record<string, number> = {};
    pVisitsByCountry.forEach((v) => {
      if (v.country) {
        byCountry[v.country] = v._count.country;
      }
    });

    const byDevice: Record<string, number> = {
      Desktop: 0,
      Mobile: 0,
      Tablet: 0,
    };

    pVisitsByDevice.forEach((v) => {
      const type =
        v.deviceType.charAt(0).toUpperCase() +
        v.deviceType.slice(1).toLowerCase();
      byDevice[type] = (byDevice[type] || 0) + v._count.deviceType;
    });

    const response = {
      visits: {
        total: totalVisits,
        unique,
        today: 0,
        week: timeRange === "week" ? totalVisits : 0,
        month: timeRange === "month" ? totalVisits : 0,
      },
      conversions: {
        visitorToDemo: parseFloat(visitorToDemo),
        visitorToSignup: parseFloat(visitorToSignup),
        demoToSignup: parseFloat(demoToSignup),
      },
      topPages,
      byCountry,
      byDevice,
    };

    return NextResponse.json(response);
  } catch (error) {
    console.error("Failed to fetch analytics:", error);
    return NextResponse.json(
      { error: "Failed to fetch analytics" },
      { status: 500 },
    );
  }
}
