import { query, mutation } from "./_generated/server";
import { v } from "convex/values";

// Create invite with encrypted payload
export const create = mutation({
  args: {
    code: v.string(),
    encryptedPayload: v.string(),
    createdBy: v.id("userProfiles"),
    maxUses: v.optional(v.number()),
    expiresAt: v.optional(v.number()),
    keyVersion: v.number(),
  },
  returns: v.object({ success: v.boolean() }),
  handler: async (ctx, args) => {
    await ctx.db.insert("invites", {
      code: args.code,
      encryptedPayload: args.encryptedPayload,
      createdBy: args.createdBy,
      maxUses: args.maxUses,
      uses: 0,
      expiresAt: args.expiresAt,
      keyVersion: args.keyVersion,
    });

    return { success: true };
  },
});

// Fetch and validate invite (returns encrypted payload)
export const use = query({
  args: { code: v.string() },
  returns: v.union(
    v.object({
      encryptedPayload: v.string(),
      keyVersion: v.number(),
    }),
    v.object({ error: v.string() })
  ),
  handler: async (ctx, args) => {
    const invite = await ctx.db
      .query("invites")
      .withIndex("by_code", (q) => q.eq("code", args.code))
      .unique();

    if (!invite) {
      return { error: "Invite not found" };
    }

    if (invite.expiresAt && Date.now() > invite.expiresAt) {
      return { error: "Invite expired" };
    }

    if (
      invite.maxUses !== undefined &&
      invite.maxUses !== null &&
      invite.uses >= invite.maxUses
    ) {
      return { error: "Invite max uses reached" };
    }

    return {
      encryptedPayload: invite.encryptedPayload,
      keyVersion: invite.keyVersion,
    };
  },
});

// Revoke invite
export const revoke = mutation({
  args: { code: v.string() },
  returns: v.object({ success: v.boolean() }),
  handler: async (ctx, args) => {
    const invite = await ctx.db
      .query("invites")
      .withIndex("by_code", (q) => q.eq("code", args.code))
      .unique();

    if (invite) {
      await ctx.db.delete(invite._id);
    }

    return { success: true };
  },
});
