import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";

mock.module("server-only", () => ({}));

const RUN_DB = process.env.DB_TESTS === "1";
const NOW = new Date("2026-07-01T10:00:00Z");
const LATER = new Date("2026-07-01T11:00:00Z");
const USER = "dfo-user";
const ORG_OLD = "dfo-org-old";
const ORG_NEW = "dfo-org-new";

describe.skipIf(!RUN_DB)("resolveDefaultOrgId (postgres)", () => {
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let db: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let authSchema: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let mod: any;

  async function cleanup() {
    const { inArray } = await import("drizzle-orm");
    await db
      .delete(authSchema.organization)
      .where(inArray(authSchema.organization.id, [ORG_OLD, ORG_NEW]));
    await db.delete(authSchema.user).where(inArray(authSchema.user.id, [USER]));
  }

  async function seedOrg(id: string) {
    await db
      .insert(authSchema.organization)
      .values({ id, name: id, slug: id, createdAt: NOW });
  }

  async function seedMember(orgId: string, createdAt: Date) {
    await db.insert(authSchema.member).values({
      id: `${orgId}-m`,
      organizationId: orgId,
      userId: USER,
      role: "owner",
      createdAt,
    });
  }

  async function setLastActive(orgId: string | null) {
    const { eq } = await import("drizzle-orm");
    await db
      .update(authSchema.user)
      .set({ lastActiveOrgId: orgId })
      .where(eq(authSchema.user.id, USER));
  }

  beforeEach(async () => {
    ({ db } = await import("@/lib/db/client"));
    authSchema = await import("@/lib/db/auth-schema");
    mod = await import("./default-org");
    const { assertTestDb } = await import("@/lib/db/assert-test-db");
    await assertTestDb();
    await cleanup();
    await db.insert(authSchema.user).values({
      id: USER,
      name: USER,
      email: `${USER}@test.dev`,
      emailVerified: true,
      createdAt: NOW,
      updatedAt: NOW,
    });
  });

  afterAll(async () => {
    if (!RUN_DB) return;
    await cleanup();
  });

  test("aucune membership → undefined (jamais de throw)", async () => {
    expect(await mod.resolveDefaultOrgId(USER)).toBeUndefined();
  });

  test("sans lastActiveOrgId → la plus ancienne membership", async () => {
    await seedOrg(ORG_OLD);
    await seedOrg(ORG_NEW);
    await seedMember(ORG_NEW, LATER);
    await seedMember(ORG_OLD, NOW);
    expect(await mod.resolveDefaultOrgId(USER)).toBe(ORG_OLD);
  });

  test("lastActiveOrgId gagne quand l'utilisateur en est encore membre", async () => {
    await seedOrg(ORG_OLD);
    await seedOrg(ORG_NEW);
    await seedMember(ORG_OLD, NOW);
    await seedMember(ORG_NEW, LATER);
    await setLastActive(ORG_NEW);
    expect(await mod.resolveDefaultOrgId(USER)).toBe(ORG_NEW);
  });

  test("lastActiveOrgId ignoré quand la membership n'existe plus", async () => {
    await seedOrg(ORG_OLD);
    await seedMember(ORG_OLD, NOW);
    await setLastActive("dfo-org-gone");
    expect(await mod.resolveDefaultOrgId(USER)).toBe(ORG_OLD);
  });
});
