import { NextRequest, NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server";
import { getDatabase } from "@/lib/database";
import { ensureUserSynced } from "@/lib/sync-user";
import { successResponse } from "@/lib/api/responses";
import { db as rawDb, sql } from "@fitai/database";
import { getUsersByGym, getClientsByGym } from "@/lib/gym-context";

interface UserGrowthPoint {
  label: string;
  value: number;
}

interface MembershipDistributionPoint {
  label: string;
  value: number;
  color: string;
}

interface RevenuePoint {
  label: string;
  value: number;
  color: string;
}

interface AnalyticsData {
  userGrowth: UserGrowthPoint[];
  membershipDistribution: MembershipDistributionPoint[];
  revenue: RevenuePoint[];
}

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

    const database = await getDatabase();
    const user = await ensureUserSynced(userId, database);

    if (!user || (user.role !== "admin" && user.role !== "superAdmin")) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

    const url = new URL(req.url);
    const months = parseInt(url.searchParams.get("months") || "6");

    // Get target gym based on role
    const targetGymId =
      user.role === "superAdmin"
        ? (url.searchParams.get("gymId") ?? undefined)
        : (user.gymId ?? undefined);

    // Validate gym access for non-superAdmins
    if (user.role !== "superAdmin" && !targetGymId) {
      return NextResponse.json(
        { error: "Forbidden - No gym assigned" },
        { status: 403 },
      );
    }

    // Get gym-scoped data
    const allUsers = targetGymId
      ? await getUsersByGym(targetGymId)
      : await database.getAllUsers();

    const allClients = targetGymId
      ? await getClientsByGym(targetGymId)
      : await database.getAllClients();

    // For payments, we'd need a similar filter - for now, skip payments if gym-scoped
    // TODO: Add getPaymentsByGym when needed
    const paymentsRaw = targetGymId
      ? [] // Skip payments for gym-scoped for now
      : await rawDb.all(
          sql`SELECT * FROM payments WHERE status = 'completed' AND paid_at IS NOT NULL`,
        );
    const payments: any[] = paymentsRaw || [];

    const now = new Date();
    const userGrowth: UserGrowthPoint[] = [];

    for (let i = months - 1; i >= 0; i--) {
      const date = new Date(now.getFullYear(), now.getMonth() - i, 1);
      const monthLabel = date.toLocaleDateString("en-US", { month: "short" });

      const usersCreatedByMonth = allUsers.filter((u: any) => {
        const createdAt = new Date(u.createdAt);
        return (
          createdAt.getFullYear() === date.getFullYear() &&
          createdAt.getMonth() === date.getMonth()
        );
      });

      userGrowth.push({
        label: monthLabel,
        value: usersCreatedByMonth.length,
      });
    }

    let runningTotal = 0;
    for (const point of userGrowth) {
      runningTotal += point.value;
      point.value = runningTotal;
    }

    const membershipCounts: Record<string, number> = {
      basic: 0,
      premium: 0,
      vip: 0,
    };

    for (const client of allClients) {
      const membershipType = (client as any).membershipType || "basic";
      if (membershipCounts[membershipType] !== undefined) {
        membershipCounts[membershipType]++;
      }
    }

    const membershipDistribution: MembershipDistributionPoint[] = [
      { label: "Basic", value: membershipCounts.basic, color: "#6b7280" },
      { label: "Premium", value: membershipCounts.premium, color: "#3b82f6" },
      { label: "VIP", value: membershipCounts.vip, color: "#f59e0b" },
    ];

    const revenue: RevenuePoint[] = [];

    for (let i = months - 1; i >= 0; i--) {
      const date = new Date(now.getFullYear(), now.getMonth() - i, 1);
      const monthLabel = date.toLocaleDateString("en-US", { month: "short" });
      const nextMonthDate = new Date(
        now.getFullYear(),
        now.getMonth() - i + 1,
        1,
      );

      const monthlyRevenue = payments
        .filter((p: any) => {
          const paidAt = p.paid_at ? new Date(p.paid_at) : null;
          if (!paidAt) return false;
          return paidAt >= date && paidAt < nextMonthDate;
        })
        .reduce((sum: number, p: any) => sum + (p.amount || 0), 0);

      revenue.push({
        label: monthLabel,
        value: monthlyRevenue,
        color: "#10b981",
      });
    }

    const analyticsData: AnalyticsData = {
      userGrowth,
      membershipDistribution,
      revenue,
    };

    return successResponse({ analytics: analyticsData });
  } catch (error) {
    console.error("Analytics error:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}
