import { db, shoppingLists, shoppingListMembers, eq, and } from "@epicure/db";

export type ShoppingListRole = "owner" | "editor" | "viewer";

export type ShoppingListAccess = {
  list: typeof shoppingLists.$inferSelect;
  role: ShoppingListRole;
};

/**
 * Resolves access to a shopping list — owner, member with their assigned role,
 * or (when `userId` is null, i.e. no session) an anonymous visitor via the
 * public link: "editor" if the owner enabled public editing, "viewer" if the
 * list is merely public, else no access. The link's id is the only credential
 * an anonymous visitor has, so this must never fall through to a real role
 * for a non-public list.
 */
export async function getShoppingListAccess(
  listId: string,
  userId: string | null
): Promise<ShoppingListAccess | null> {
  const list = await db.query.shoppingLists.findFirst({ where: eq(shoppingLists.id, listId) });
  if (!list) return null;

  if (userId) {
    if (list.userId === userId) return { list, role: "owner" };

    const member = await db.query.shoppingListMembers.findFirst({
      where: and(eq(shoppingListMembers.listId, listId), eq(shoppingListMembers.userId, userId)),
    });
    if (member) return { list, role: member.role };
  }

  if (!list.isPublic) return null;
  return { list, role: list.publicEditable ? "editor" : "viewer" };
}

export function canWriteShoppingList(role: ShoppingListRole): boolean {
  return role === "owner" || role === "editor";
}
