// src/lib/backlink/dr-chunk.ts — fetch + upsert DR for a list of domains (no auth; injectable fetcher).
import { sql } from "drizzle-orm";
import { db } from "@/lib/db/client";
import { domainRatings } from "@/lib/db/domain-schema";
import { type DrResult, fetchDomainRating } from "./ahrefs-dr";

export interface DrChunkResult {
  updated: number;
  rateLimited: boolean;
  failed: string[];
}

const CONCURRENCY = 4;
const DELAY_MS = 150;

const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

/** Fetch DR for each domain (bounded concurrency + delay) and upsert hits. */
export async function runDrChunk(
  domains: string[],
  fetcher: (d: string) => Promise<DrResult> = fetchDomainRating,
): Promise<DrChunkResult> {
  const failed: string[] = [];
  let updated = 0;
  let rateLimited = false;

  for (let i = 0; i < domains.length; i += CONCURRENCY) {
    const batch = domains.slice(i, i + CONCURRENCY);
    const results = await Promise.all(batch.map((d) => fetcher(d)));
    const hits: { domainNorm: string; dr: number }[] = [];
    results.forEach((r, j) => {
      const d = batch[j];
      if (r.ok) hits.push({ domainNorm: d, dr: r.dr });
      else if (r.reason === "rate_limited") rateLimited = true;
      else failed.push(d);
    });
    if (hits.length > 0) {
      await db
        .insert(domainRatings)
        .values(hits.map((h) => ({ domainNorm: h.domainNorm, dr: h.dr })))
        .onConflictDoUpdate({
          target: domainRatings.domainNorm,
          set: { dr: sql`excluded.dr`, fetchedAt: sql`now()` },
        });
      updated += hits.length;
    }
    if (i + CONCURRENCY < domains.length) await sleep(DELAY_MS);
  }
  return { updated, rateLimited, failed };
}
