import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

type Target =
  | { userId: string; email?: undefined }
  | { email: string; userId?: undefined };

function parseArgs(argv: string[]): Target {
  const args = [...argv];
  let userId: string | undefined;
  let email: string | undefined;

  while (args.length > 0) {
    const current = args.shift();

    if (current === "--user-id") {
      userId = args.shift()?.trim();
      continue;
    }

    if (current === "--email") {
      email = args.shift()?.trim().toLowerCase();
      continue;
    }
  }

  if (userId && email) {
    throw new Error("Use only one of --user-id or --email.");
  }

  if (!userId && !email) {
    throw new Error("Missing target. Use --user-id <id> or --email <email>.");
  }

  return userId ? { userId } : { email: email! };
}

async function main() {
  const target = parseArgs(process.argv.slice(2));
  const user = await prisma.user.findFirst({
    where: target.userId ? { id: target.userId } : { email: target.email },
    select: {
      id: true,
      email: true,
      username: true,
      displayName: true,
      deletedAt: true,
      _count: {
        select: {
          recipes: true,
          recipeComments: true,
          shoppingLists: true,
          shoppingGroups: true,
          savedRecipes: true,
          favoriteRecipes: true,
          followers: true,
          following: true,
        },
      },
    },
  });

  if (!user) {
    throw new Error("User not found.");
  }

  if (user.deletedAt) {
    console.log("User is already anonymized/deactivated.", {
      id: user.id,
      email: user.email,
      deletedAt: user.deletedAt.toISOString(),
    });
    return;
  }

  const timestamp = Date.now();
  const idSuffix = user.id.replace(/-/g, "").slice(0, 12).toLowerCase();
  const anonymizedEmail = `deleted+${idSuffix}.${timestamp}@dishcrib.invalid`;
  const now = new Date();

  await prisma.$transaction(async (tx) => {
    await tx.userFollow.deleteMany({
      where: {
        OR: [{ followerId: user.id }, { followedId: user.id }],
      },
    });

    await tx.favoriteRecipe.deleteMany({ where: { userId: user.id } });
    await tx.recipeFavorite.deleteMany({ where: { userId: user.id } });
    await tx.shoppingGroupPreference.deleteMany({ where: { userId: user.id } });
    await tx.shoppingGroup.deleteMany({ where: { userId: user.id } });
    await tx.shoppingList.deleteMany({ where: { userId: user.id } });
    await tx.userPreference.deleteMany({ where: { userId: user.id } });
    await tx.authAccount.deleteMany({ where: { userId: user.id } });
    await tx.refreshToken.deleteMany({ where: { userId: user.id } });
    await tx.emailVerificationToken.deleteMany({ where: { userId: user.id } });
    await tx.passwordResetToken.deleteMany({ where: { userId: user.id } });

    await tx.user.update({
      where: { id: user.id },
      data: {
        email: anonymizedEmail,
        emailVerifiedAt: null,
        username: null,
        passwordHash: null,
        displayName: "Deleted User",
        avatarUrl: null,
        plan: "FREE",
        freeAiActionsUsedDate: null,
        freeAiActionsUsedToday: 0,
        lastOccasionalAdAt: null,
        deletedAt: now,
        anonymizedAt: now,
      },
    });
  });

  console.log("User anonymized successfully.", {
    id: user.id,
    previousEmail: user.email,
    anonymizedEmail,
    recipesPreserved: user._count.recipes,
    commentsPreserved: user._count.recipeComments,
    shoppingListsRemoved: user._count.shoppingLists,
    shoppingGroupsRemoved: user._count.shoppingGroups,
    savesRemoved: user._count.savedRecipes,
    favoritesRemoved: user._count.favoriteRecipes,
    followLinksRemoved: user._count.followers + user._count.following,
  });
}

main()
  .catch((error) => {
    console.error("Failed to anonymize user.", error);
    process.exitCode = 1;
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
