/**
 * One-off / ops: assign referralCode to rows that are still null.
 * Run: npm run prisma:referral-backfill
 */
import { PrismaClient } from '@prisma/client';
import { randomInt } from 'crypto';

const prisma = new PrismaClient();

function randomSegment(): string {
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
  let s = '';
  for (let i = 0; i < 6; i++) {
    s += chars[randomInt(0, chars.length)];
  }
  return `CASHI-${s}`;
}

async function allocateUniqueCode(): Promise<string> {
  for (let attempt = 0; attempt < 48; attempt++) {
    const code = randomSegment();
    const clash = await prisma.user.findUnique({
      where: { referralCode: code },
      select: { id: true },
    });
    if (!clash) return code;
  }
  throw new Error('Could not allocate a unique referral code');
}

async function main() {
  const users = await prisma.user.findMany({
    where: { referralCode: null },
    select: { id: true },
  });
  let updated = 0;
  for (const u of users) {
    for (let tries = 0; tries < 8; tries++) {
      const code = await allocateUniqueCode();
      try {
        await prisma.user.update({
          where: { id: u.id },
          data: { referralCode: code },
        });
        updated += 1;
        break;
      } catch (e: unknown) {
        const p = e as { code?: string };
        if (p?.code === 'P2002') continue;
        throw e;
      }
    }
  }
  console.log(`referral-backfill: updated ${updated} of ${users.length} users without codes`);
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(() => void prisma.$disconnect());
