// src/lib/backlink/research.ts — pool global scoré pour un site (CdC backlink/recherche).
import "server-only";
import { eq, inArray, sql } from "drizzle-orm";
import { db } from "@/lib/db/client";
import {
  type BacklinkStatus,
  backlinks,
  domainRatings,
  linkSources,
  sites,
} from "@/lib/db/domain-schema";
import { footprintAlert, relevanceScore } from "./relevance";
import type { LinkSource } from "./types";

export type ResearchRow = LinkSource & {
  score: number;
  footprint: number;
  alert: boolean;
  targetedByCurrent: boolean;
  currentStatus: BacklinkStatus | null;
};

export async function getResearchPool(
  orgId: string,
  siteId: string,
): Promise<ResearchRow[]> {
  const site = (await db.select().from(sites).where(eq(sites.id, siteId)))[0];
  const siteLanguage = site?.primaryLanguage ?? "fr";

  const rows = await db
    .select()
    .from(linkSources)
    .where(eq(linkSources.orgId, orgId))
    .orderBy(linkSources.platform);
  if (rows.length === 0) return [];

  const domains = [...new Set(rows.map((r) => r.domainNorm))];
  const drRows = await db
    .select({ domainNorm: domainRatings.domainNorm, dr: domainRatings.dr })
    .from(domainRatings)
    .where(inArray(domainRatings.domainNorm, domains));
  const drByDomain = new Map(drRows.map((d) => [d.domainNorm, d.dr]));

  const ids = rows.map((r) => r.id);
  const rels = await db
    .select({
      linkSourceId: backlinks.linkSourceId,
      footprint: sql<string>`count(distinct ${backlinks.siteId})`,
      currentStatus: sql<
        string | null
      >`max(${backlinks.status}) filter (where ${backlinks.siteId} = ${siteId})`,
    })
    .from(backlinks)
    .where(inArray(backlinks.linkSourceId, ids))
    .groupBy(backlinks.linkSourceId);
  const relBySource = new Map(rels.map((r) => [r.linkSourceId, r]));

  return rows
    .map((r) => {
      const dr = drByDomain.get(r.domainNorm) ?? null;
      const rel = relBySource.get(r.id);
      const footprint = rel ? Number(rel.footprint) : 0;
      const currentStatus = (rel?.currentStatus ??
        null) as BacklinkStatus | null;
      return {
        id: r.id,
        platform: r.platform,
        url: r.url,
        domainNorm: r.domainNorm,
        kind: r.kind,
        da: r.da,
        dr,
        effort: r.effort,
        linkType: r.linkType,
        language: r.language,
        themes: r.themes,
        tags: r.tags,
        flags: r.flags,
        note: r.note ?? undefined,
        global: r.global,
        score: relevanceScore(
          { language: r.language, dr, da: r.da },
          siteLanguage,
        ),
        footprint,
        alert: footprintAlert(footprint),
        targetedByCurrent: currentStatus != null,
        currentStatus,
      };
    })
    .sort((a, b) => b.score - a.score);
}
