import { db, invites, eq, isNull } from "@epicure/db";
import { randomUUID, randomBytes } from "crypto";

export const INVITE_COOKIE = "epicure_invite";

export function generateInviteToken(): string {
  return randomBytes(24).toString("base64url");
}

export async function findValidInvite(token: string, email?: string | null) {
  const [invite] = await db.select().from(invites).where(eq(invites.token, token));
  if (!invite) return null;
  if (invite.usedAt) return null;
  if (invite.expiresAt && invite.expiresAt < new Date()) return null;
  if (invite.email && email && invite.email.toLowerCase() !== email.toLowerCase()) return null;
  return invite;
}

export async function consumeInvite(inviteId: string, userId: string): Promise<void> {
  await db
    .update(invites)
    .set({ usedAt: new Date(), usedById: userId })
    .where(eq(invites.id, inviteId));
}

export async function createInvite(opts: {
  createdById: string;
  email?: string | null;
  role?: "user" | "moderator" | "admin";
  tier?: "free" | "pro" | "family";
  expiresInDays?: number | null;
}) {
  const [invite] = await db
    .insert(invites)
    .values({
      id: randomUUID(),
      token: generateInviteToken(),
      email: opts.email || null,
      role: opts.role ?? "user",
      tier: opts.tier ?? "free",
      createdById: opts.createdById,
      expiresAt: opts.expiresInDays ? new Date(Date.now() + opts.expiresInDays * 86400_000) : null,
    })
    .returning();
  return invite;
}

export async function listInvites() {
  return db.query.invites.findMany({
    where: isNull(invites.usedAt),
    orderBy: (i, { desc }) => [desc(i.createdAt)],
  });
}
