import { beforeAll, expect, test } from "bun:test";
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { analyticsJobs } from "@/lib/db/domain-schema";
import { db } from "../src/db";
import { claimNextJob, completeJob, failJob } from "../src/queue";
import { ensureTestSite, TEST_SITE as SITE } from "./fixtures/site";

beforeAll(ensureTestSite);

test("claim → complete transitions", async () => {
  const id = randomUUID();
  await db.insert(analyticsJobs).values({
    id,
    siteId: SITE,
    source: "semrush",
    objectKey: "k",
    status: "queued",
  });
  const job = await claimNextJob();
  expect(job).toBeTruthy();
  if (!job) return; // narrow for TS; expect above already guards
  // the claimed job is running
  const claimed = (
    await db.select().from(analyticsJobs).where(eq(analyticsJobs.id, job.id))
  )[0];
  expect(claimed.status).toBe("running");
  await completeJob(job.id, { read: 5, upserted: 5 });
  const done = (
    await db.select().from(analyticsJobs).where(eq(analyticsJobs.id, job.id))
  )[0];
  expect(done.status).toBe("done");
  expect(done.totals.read).toBe(5);
  await db.delete(analyticsJobs).where(eq(analyticsJobs.id, job.id));
});

test("claimNextJob RETURNING carries payload for serp-semantics jobs", async () => {
  const id = randomUUID();
  const keywordId = randomUUID();
  await db.insert(analyticsJobs).values({
    id,
    siteId: SITE,
    type: "serp-semantics",
    status: "queued",
    payload: {
      keywordId,
      country: "US",
      urls: [{ position: 1, url: "https://example.com", included: true }],
    },
  });
  const job = await claimNextJob();
  expect(job).toBeTruthy();
  if (!job) return; // narrow for TS; expect above already guards
  expect(job.id).toBe(id);
  expect(job.type).toBe("serp-semantics");
  expect(job.payload?.keywordId).toBe(keywordId);
  await db.delete(analyticsJobs).where(eq(analyticsJobs.id, job.id));
});

test("failJob records error", async () => {
  const id = randomUUID();
  await db.insert(analyticsJobs).values({
    id,
    siteId: SITE,
    source: "semrush",
    objectKey: "k",
    status: "running",
  });
  await failJob(id, "boom");
  const f = (
    await db.select().from(analyticsJobs).where(eq(analyticsJobs.id, id))
  )[0];
  expect(f.status).toBe("failed");
  expect(f.error).toBe("boom");
  await db.delete(analyticsJobs).where(eq(analyticsJobs.id, id));
});
