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();
const USER = "cred-user";

describe.skipIf(!RUN_DB)("hasCredentialAccount (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.user).where(inArray(authSchema.user.id, [USER]));
  }

  async function seedAccount(providerId: string, password: string | null) {
    await db.insert(authSchema.account).values({
      id: `${USER}-${providerId}`,
      accountId: USER,
      providerId,
      userId: USER,
      password,
      createdAt: NOW,
      updatedAt: NOW,
    });
  }

  beforeEach(async () => {
    ({ db } = await import("@/lib/db/client"));
    authSchema = await import("@/lib/db/auth-schema");
    mod = await import("./credential");
    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("aucun compte lié → false (magic link pur)", async () => {
    expect(await mod.hasCredentialAccount(USER)).toBe(false);
  });

  test("compte social seul → false", async () => {
    await seedAccount("google", null);
    expect(await mod.hasCredentialAccount(USER)).toBe(false);
  });

  test("compte credential avec hash → true", async () => {
    await seedAccount("credential", "hash");
    expect(await mod.hasCredentialAccount(USER)).toBe(true);
  });

  test("compte credential sans hash → false (même règle que setPassword)", async () => {
    await seedAccount("credential", null);
    expect(await mod.hasCredentialAccount(USER)).toBe(false);
  });
});

// Garde de surface d'endpoint : password-actions.ts ("use server") ne doit
// exposer QUE l'action publique auth-guardée.
test("password-actions.ts n'exporte que setInitialPasswordAction", async () => {
  const mod = await import("./password-actions");
  expect(Object.keys(mod).sort()).toEqual(["setInitialPasswordAction"]);
});
