import "server-only";

import { type ModulePlanKey, type UserRole } from "@prisma/client";
import { isAdminIdentity } from "@/lib/auth/admin";
import { prisma } from "@/lib/prisma";
import { getModulePlanByModuleNumber } from "@/lib/payments/plans";

function isSubscriptionValid(subscription: { isActive: boolean; startsAt: Date; expiresAt: Date | null }, now: Date) {
  if (!subscription.isActive) {
    return false;
  }

  if (subscription.startsAt.getTime() > now.getTime()) {
    return false;
  }

  if (subscription.expiresAt && subscription.expiresAt.getTime() < now.getTime()) {
    return false;
  }

  return true;
}

export async function getActivePlanKeysForUser(userId: string) {
  const now = new Date();

  const subscriptions = await prisma.modulePlanSubscription.findMany({
    where: {
      userId,
      isActive: true,
    },
    select: {
      planKey: true,
      isActive: true,
      startsAt: true,
      expiresAt: true,
    },
  });

  return new Set(
    subscriptions.filter((item) => isSubscriptionValid(item, now)).map((item) => item.planKey as ModulePlanKey),
  );
}

export async function hasAnyPaidModuleAccess(userId: string, email: string, role: UserRole) {
  if (isAdminIdentity(email, role)) {
    return true;
  }

  const plans = await getActivePlanKeysForUser(userId);
  return plans.size > 0;
}

export async function hasModuleAccess(user: { id: string; email: string; role: UserRole }, moduleNumber: number) {
  if (isAdminIdentity(user.email, user.role)) {
    return true;
  }

  const targetPlan = getModulePlanByModuleNumber(moduleNumber);

  if (!targetPlan) {
    return true;
  }

  const activePlans = await getActivePlanKeysForUser(user.id);
  return activePlans.has(targetPlan.key);
}
