// Proves the Next *route handler's own code path*: the real @aws-sdk/client-s3 PUT
// (putCsvToR2) + the real fetch enqueue (enqueueAnalyticsJob) — the bits the live
// e2e didn't cover (it used Bun's S3 client). Run with the react-server condition so
// the `server-only` imports resolve to their no-op variant:
//   cd services/analytics && bun --env-file=../../.env.local --conditions=react-server \
//     run scripts/route-path-check.ts
import { randomUUID } from "node:crypto";
import { S3Client } from "bun";
import { and, eq, inArray } from "drizzle-orm";
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
// The actual modules the route handler imports:
import { enqueueAnalyticsJob } from "@/lib/analytics/enqueue";
import { putCsvToR2 } from "@/lib/analytics/r2-upload";
import * as schema from "@/lib/db/domain-schema";

const fail = (m: string): never => {
  console.error(`ROUTE_CHECK_FAIL: ${m}`);
  process.exit(1);
};

const sql = postgres(process.env.DATABASE_URL ?? fail("DATABASE_URL missing"), {
  max: 2,
});
const db = drizzle(sql, { schema });
const s3 = new S3Client({
  accessKeyId: process.env.R2_ACCESS_KEY_ID,
  secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
  bucket: process.env.R2_BUCKET,
  endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  region: "auto",
});

try {
  const [site] = await db.select().from(schema.sites).limit(1);
  if (!site) fail("no sites in DB");
  console.log(`[1] site: ${site.id}`);

  const before = new Set(
    (
      await db
        .select({ id: schema.keywords.id })
        .from(schema.keywords)
        .where(eq(schema.keywords.siteId, site.id))
    ).map((r) => r.id),
  );

  // --- the route's real PUT path (@aws-sdk/client-s3) ---
  const objectKey = `exports/${site.id}/${randomUUID()}.csv`;
  const csv = await Bun.file("test/fixtures/semrush.csv").text();
  await putCsvToR2(objectKey, Buffer.from(csv));
  console.log(`[2] putCsvToR2 (aws-sdk) → ${objectKey}`);

  // --- the route's real enqueue path (fetch → ${ANALYTICS_URL}/jobs) ---
  const jobId = await enqueueAnalyticsJob({
    siteId: site.id,
    source: "semrush",
    objectKey,
  });
  console.log(`[3] enqueueAnalyticsJob (fetch) → job ${jobId}`);

  let job: typeof schema.analyticsJobs.$inferSelect | undefined;
  for (let i = 0; i < 60; i++) {
    await Bun.sleep(500);
    [job] = await db
      .select()
      .from(schema.analyticsJobs)
      .where(eq(schema.analyticsJobs.id, jobId));
    if (job && (job.status === "done" || job.status === "failed")) break;
  }
  if (job?.status !== "done")
    fail(`job not done: ${job?.status} ${job?.error ?? ""}`);
  console.log(`[4] job done — totals ${JSON.stringify(job.totals)}`);

  const created = (
    await db
      .select({ id: schema.keywords.id })
      .from(schema.keywords)
      .where(
        and(
          eq(schema.keywords.siteId, site.id),
          inArray(
            schema.keywords.id,
            ["seo-audit", "link-building"].map((s) => `${site.id}-${s}`),
          ),
        ),
      )
  )
    .map((r) => r.id)
    .filter((id) => !before.has(id));
  if (created.length) {
    await db
      .delete(schema.keywords)
      .where(inArray(schema.keywords.id, created));
  }
  await db
    .delete(schema.analyticsJobs)
    .where(eq(schema.analyticsJobs.id, jobId));

  // sweep any orphaned failed-run artifacts from earlier verification.
  const failed = await db
    .select()
    .from(schema.analyticsJobs)
    .where(
      and(
        eq(schema.analyticsJobs.siteId, site.id),
        eq(schema.analyticsJobs.status, "failed"),
      ),
    );
  for (const f of failed) {
    try {
      if (await s3.file(f.objectKey).exists())
        await s3.file(f.objectKey).delete();
    } catch {}
    await db
      .delete(schema.analyticsJobs)
      .where(eq(schema.analyticsJobs.id, f.id));
  }
  console.log(
    `[5] cleaned ${created.length} keyword(s), this job, + ${failed.length} stale failed job(s)/object(s)`,
  );

  console.log(
    "\nROUTE_CHECK_OK — the route's aws-sdk PUT + fetch enqueue drive the full pipeline.",
  );
  await sql.end();
  process.exit(0);
} catch (e) {
  console.error(e);
  await sql.end();
  fail(String(e));
}
