// src/lib/gsc/discovery.ts — create keywords from GSC queries (idempotent).
import "server-only";
import * as wasm from "import-core";
import { chunk } from "@/lib/db/chunk";
import { db } from "@/lib/db/client";
import { keywords as keywordsTable } from "@/lib/db/domain-schema";
import type { GscTracking } from "@/lib/keywords/types";
import type { GscQueryRow } from "./types";

export type CreateGscResult = { created: number };

/** Create keywords for the given GSC queries. primarySource "gsc", no SEO
 *  metrics, gsc overlay set. Id = `${siteId}-${slug}` (matches CSV import so a
 *  later Mangools/Semrush import merges). onConflictDoNothing → idempotent. */
export async function createGscKeywordsForSite(
  siteId: string,
  rows: GscQueryRow[],
  opts: {
    lang: string;
    /** A fixed alpha-2 country, or a per-query resolver (attribute each query
     *  to the country it actually ranks in — see resolveGscCountry). */
    country: string | ((query: string) => string);
    stages: ("research" | "planning")[];
  },
): Promise<CreateGscResult> {
  if (rows.length === 0) return { created: 0 };
  const now = new Date().toISOString();
  const countryOpt = opts.country;
  const countryOf =
    typeof countryOpt === "function" ? countryOpt : () => countryOpt;
  const values = rows.map((r) => {
    const gsc: GscTracking = {
      clicks: r.clicks,
      impressions: r.impressions,
      ctr: r.ctr,
      position: r.position,
      updatedAt: now,
    };
    return {
      id: `${siteId}-${wasm.slugify(r.query)}`,
      siteId,
      term: r.query,
      lang: opts.lang,
      country: countryOf(r.query),
      theme: null,
      // a query returned by GSC is already ranking → "active", not an idea
      status: "active" as const,
      intent: [],
      stages: opts.stages,
      primarySource: "gsc" as const,
      sources: ["gsc" as const],
      metrics: {},
      gsc,
      trend: [],
    };
  });
  // GSC can return 25 000+ queries → chunk under the Postgres ~65 535
  // bind-parameter cap, atomically (one transaction).
  const created = await db.transaction(async (tx) => {
    let count = 0;
    for (const slice of chunk(values, 500)) {
      const inserted = await tx
        .insert(keywordsTable)
        .values(slice)
        // keywords PK is `id` alone (0057) — id already encodes the site
        // (`${siteId}-${slug}`), so it's globally unique by construction.
        .onConflictDoNothing({
          target: [keywordsTable.id],
        })
        .returning({ id: keywordsTable.id });
      count += inserted.length;
    }
    return count;
  });
  return { created };
}
