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

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

const TEST_EMAIL = `smoke-switch-${nanoid(8)}@elevaseo.com`;
const TEST_NAME = "Smoke Switch";
const TEST_PASSWORD = "SmokeSwitch1234!";

async function main() {
  console.log(`→ Signing up ${TEST_EMAIL}`);
  const res = await auth.api.signUpEmail({
    body: { name: TEST_NAME, email: TEST_EMAIL, password: TEST_PASSWORD },
  });
  const userId = res.user.id;

  try {
    const initialMember = await db.select().from(member).where(eq(member.userId, userId)).limit(1);
    if (initialMember.length === 0) throw new Error("Personal org missing");
    const personalOrgId = initialMember[0]!.organizationId;
    console.log(`✓ Personal org: ${personalOrgId}`);

    const teamOrgId = nanoid();
    await db.transaction(async (tx) => {
      await tx.insert(organization).values({
        id: teamOrgId,
        name: `Team Smoke ${nanoid(4)}`,
        slug: `team-smoke-${nanoid(6)}`,
        logo: null,
        metadata: null,
      });
      await tx.insert(member).values({
        id: nanoid(),
        organizationId: teamOrgId,
        userId,
        role: "admin",
      });
    });
    console.log(`✓ Team org: ${teamOrgId}`);

    const allMembers = await db.select().from(member).where(eq(member.userId, userId));
    if (allMembers.length !== 2) {
      throw new Error(`Expected 2 memberships, got ${allMembers.length}`);
    }

    const sess = await db
      .select()
      .from(session)
      .where(eq(session.userId, userId))
      .orderBy(session.createdAt)
      .limit(1);
    if (sess.length === 0) throw new Error("No session row");

    await db
      .update(session)
      .set({ activeOrganizationId: teamOrgId })
      .where(eq(session.id, sess[0]!.id));

    const refreshed = await db.select().from(session).where(eq(session.id, sess[0]!.id));
    if (refreshed[0]!.activeOrganizationId !== teamOrgId) {
      throw new Error(
        `Switch failed: got ${refreshed[0]!.activeOrganizationId}, expected ${teamOrgId}`,
      );
    }
    console.log(`✓ Switch persisted: session.activeOrganizationId = ${teamOrgId}`);
  } finally {
    await db.delete(user).where(eq(user.id, userId));
    await db
      .delete(organization)
      .where(
        and(
          like(organization.name, "Personal — smoke-switch-%"),
          notExists(
            db
              .select({ one: member.id })
              .from(member)
              .where(eq(member.organizationId, organization.id)),
          ),
        ),
      );
    await db
      .delete(organization)
      .where(
        and(
          like(organization.name, "Team Smoke %"),
          notExists(
            db
              .select({ one: member.id })
              .from(member)
              .where(eq(member.organizationId, organization.id)),
          ),
        ),
      );
    console.log(`→ Cleanup done`);
  }

  console.log(`✅ verify-org-switch OK`);
  process.exit(0);
}

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