/* Seed 3 test users to validate the org role hierarchy from Phase 1.
   DEV ONLY — never commit these credentials anywhere prod-adjacent.

   After running:
   - owner-test@elevaseo.com is OWNER of their own Personal Org (auto-created at signup).
   - admin-test@elevaseo.com and member-test@elevaseo.com get TWO memberships:
       (a) their own Personal Org (Owner, auto-created at signup),
       (b) owner-test's Personal Org with role "admin" / "member" respectively (inserted here).
   This validates the multi-membership case + the role enum end-to-end.

   Idempotent: re-running is a no-op if the users already exist. Re-uses
   `createPersonalOrg`'s idempotence semantics + skips re-inserting team
   memberships that already exist. */

import { and, eq } from "drizzle-orm";
import { nanoid } from "nanoid";

import { auth } from "../lib/auth";
import { db } from "../lib/db";
import { member, user } from "../lib/db/schema";

// Hard-stop before doing anything: this script ships well-known passwords
// (`OwnerTest!2026` etc.). Running it against a prod DB would create real
// accounts with brute-forceable credentials. The guard is here, not in a
// runner wrapper, so it survives accidental copy/paste of the bare command.
if (process.env.NODE_ENV === "production") {
  console.error(
    "Refusing to seed test users with NODE_ENV=production — these accounts use hardcoded passwords.",
  );
  process.exit(1);
}

type TestUser = {
  email: string;
  name: string;
  password: string;
  /* Role to assign on the team org (owner-test's Personal Org).
     `null` for the owner — they keep only their own Personal Org membership. */
  teamRole: "admin" | "member" | null;
};

const TEST_USERS: TestUser[] = [
  {
    email: "owner-test@elevaseo.com",
    name: "Owner Test",
    password: "OwnerTest!2026",
    teamRole: null, // owner of their own Personal Org — no extra team membership
  },
  {
    email: "admin-test@elevaseo.com",
    name: "Admin Test",
    password: "AdminTest!2026",
    teamRole: "admin",
  },
  {
    email: "member-test@elevaseo.com",
    name: "Member Test",
    password: "MemberTest!2026",
    teamRole: "member",
  },
];

async function ensureUser(t: TestUser): Promise<string> {
  const existing = await db
    .select({ id: user.id })
    .from(user)
    .where(eq(user.email, t.email))
    .limit(1);
  if (existing.length > 0) {
    console.log(`  · ${t.email} already exists (${existing[0]!.id})`);
    return existing[0]!.id;
  }
  const res = await auth.api.signUpEmail({
    body: { name: t.name, email: t.email, password: t.password },
  });
  console.log(`  ✓ ${t.email} signed up (${res.user.id})`);
  return res.user.id;
}

async function ensureTeamMembership(args: {
  userId: string;
  email: string;
  organizationId: string;
  role: "admin" | "member";
}) {
  const existing = await db
    .select({ id: member.id })
    .from(member)
    .where(and(eq(member.userId, args.userId), eq(member.organizationId, args.organizationId)))
    .limit(1);
  if (existing.length > 0) {
    console.log(`  · ${args.email} already member of team org with role ${args.role}`);
    return;
  }
  await db.insert(member).values({
    id: nanoid(),
    organizationId: args.organizationId,
    userId: args.userId,
    role: args.role,
  });
  console.log(`  ✓ ${args.email} added to team org as ${args.role}`);
}

async function main() {
  console.log(`→ Seeding 3 test users on @elevaseo.com`);

  // Sign up (or re-use) all 3 users. Phase 1 hook auto-creates each user's Personal Org.
  const ids: Record<string, string> = {};
  for (const t of TEST_USERS) {
    ids[t.email] = await ensureUser(t);
  }

  // Find owner-test's Personal Org — it's the team org we'll add admin + member into.
  const ownerEmail = TEST_USERS[0]!.email;
  const ownerId = ids[ownerEmail]!;
  const ownerMembership = await db
    .select({ organizationId: member.organizationId })
    .from(member)
    .where(eq(member.userId, ownerId))
    .limit(1);

  if (ownerMembership.length === 0) {
    throw new Error(
      `${ownerEmail} has no membership — the Phase 1 signup hook should have created one. Aborting.`,
    );
  }
  const teamOrgId = ownerMembership[0]!.organizationId;
  console.log(`→ Team org (owner-test's Personal Org): ${teamOrgId}`);

  // Add admin + member memberships into the team org.
  for (const t of TEST_USERS) {
    if (t.teamRole === null) continue;
    await ensureTeamMembership({
      userId: ids[t.email]!,
      email: t.email,
      organizationId: teamOrgId,
      role: t.teamRole,
    });
  }

  console.log(`\n=== Test users ready ===`);
  console.log(`Team org id: ${teamOrgId}`);
  console.log(``);
  for (const t of TEST_USERS) {
    const role = t.teamRole ?? "owner";
    console.log(`  ${role.padEnd(6)}  ${t.email}  →  password: ${t.password}`);
  }
  console.log(``);
  console.log(`✅ seed-test-users done`);
  process.exit(0);
}

main().catch((e) => {
  console.error(`❌ seed-test-users FAILED:`, e instanceof Error ? e.message : e);
  process.exit(1);
});
