// src/lib/backlink/dr-chunk.test.ts — integration, gated on DB_TESTS=1, *_test DB only.
import { beforeEach, describe, expect, mock, test } from "bun:test";

mock.module("server-only", () => ({}));
const RUN_DB = process.env.DB_TESTS === "1";

const stub =
  (map: Record<string, import("./ahrefs-dr").DrResult>) =>
  async (d: string): Promise<import("./ahrefs-dr").DrResult> =>
    map[d] ?? { ok: false, reason: "error" };

describe.skipIf(!RUN_DB)("runDrChunk (postgres)", () => {
  let db: typeof import("@/lib/db/client").db;
  let schema: typeof import("@/lib/db/domain-schema");
  let runDrChunk: typeof import("./dr-chunk").runDrChunk;
  let eq: typeof import("drizzle-orm").eq;

  beforeEach(async () => {
    ({ db } = await import("@/lib/db/client"));
    schema = await import("@/lib/db/domain-schema");
    ({ runDrChunk } = await import("./dr-chunk"));
    ({ eq } = await import("drizzle-orm"));
    const { assertTestDb } = await import("@/lib/db/assert-test-db");
    await assertTestDb();
    await db.delete(schema.domainRatings);
  });

  test("upserts successful DRs, reports failed + rateLimited", async () => {
    const res = await runDrChunk(
      ["a.com", "b.com", "c.com"],
      stub({
        "a.com": { ok: true, dr: 50 },
        "b.com": { ok: false, reason: "rate_limited" },
        "c.com": { ok: false, reason: "error" },
      }),
    );
    expect(res.updated).toBe(1);
    expect(res.rateLimited).toBe(true);
    expect(res.failed).toEqual(["c.com"]);
    const rows = await db
      .select()
      .from(schema.domainRatings)
      .where(eq(schema.domainRatings.domainNorm, "a.com"));
    expect(rows[0]?.dr).toBe(50);
  });

  test("re-running updates dr + fetchedAt (upsert)", async () => {
    await runDrChunk(["a.com"], stub({ "a.com": { ok: true, dr: 40 } }));
    await runDrChunk(["a.com"], stub({ "a.com": { ok: true, dr: 60 } }));
    const rows = await db
      .select()
      .from(schema.domainRatings)
      .where(eq(schema.domainRatings.domainNorm, "a.com"));
    expect(rows.length).toBe(1);
    expect(rows[0]?.dr).toBe(60);
  });
});
