// scripts/backfill-onboarding.ts — one-off backfill: unblock already-existing
// invited collaborators whose onboarding_completed_at is still NULL. The signup
// code fix only stamps NEW signups; pre-existing invited members (non-owners)
// stay stuck on /onboarding. This stamps onboarding_completed_at = now() for any
// user that is a non-owner member of at least one org.
//
// DRY-RUN by default (prints candidates, changes nothing).
// APPLY only with APPLY=1. Idempotent: re-running after APPLY is a no-op.
//
//   bun run backfill:onboarding              # dry-run on .env.local DB (dev)
//   APPLY=1 bun run backfill:onboarding      # apply on dev
//   prod: APPLY=1 bun --env-file=.env.production run scripts/backfill-onboarding.ts
import { and, count, eq, exists, isNull, ne, sql } from "drizzle-orm";
import { member, user } from "@/lib/db/auth-schema";
import { client, db } from "@/lib/db/client";

const APPLY = process.env.APPLY === "1";

// A user qualifies when onboarding is NULL AND they are a non-owner member of
// some org (the "stuck invited collaborator" shape).
const nonOwnerMembership = exists(
  db
    .select({ one: sql`1` })
    .from(member)
    .where(and(eq(member.userId, user.id), ne(member.role, "owner"))),
);
const candidatePredicate = and(
  isNull(user.onboardingCompletedAt),
  nonOwnerMembership,
);

async function main() {
  const [{ value: before }] = await db
    .select({ value: count() })
    .from(user)
    .where(candidatePredicate);

  const candidates = await db
    .select({ id: user.id, email: user.email })
    .from(user)
    .where(candidatePredicate);

  console.log(`Mode: ${APPLY ? "APPLY" : "DRY-RUN"}`);
  console.log(`Candidates (onboarding NULL & non-owner member): ${before}`);
  for (const c of candidates) console.log(`  - ${c.id}  ${c.email}`);

  if (!APPLY) {
    console.log("\nDry-run: nothing changed. Re-run with APPLY=1 to apply.");
    return;
  }

  const updated = await db
    .update(user)
    .set({ onboardingCompletedAt: sql`now()` })
    .where(candidatePredicate)
    .returning({ id: user.id });

  const [{ value: after }] = await db
    .select({ value: count() })
    .from(user)
    .where(candidatePredicate);

  console.log(`\nUpdated rows: ${updated.length}`);
  console.log(`Remaining candidates after apply: ${after} (expected 0)`);
}

await main();
await client.end();
