// src/lib/backlink/domain-profile-queries.ts
import "server-only";
import { and, count, countDistinct, desc, eq, sql } from "drizzle-orm";
import { db } from "@/lib/db/client";
import { domainBacklinks } from "@/lib/db/domain-schema";
import type {
  DomainBacklink,
  DomainBacklinksPage,
  DomainProfileStats,
} from "./domain-profile-types";

export async function getDomainProfileStats(
  siteId: string,
): Promise<DomainProfileStats> {
  const [row] = await db
    .select({
      backlinks: count(),
      refDomains: countDistinct(domainBacklinks.sourceDomain),
      dofollow: sql<number>`count(*) filter (where ${domainBacklinks.nofollow} = false)`,
      sitewide: sql<number>`count(*) filter (where ${domainBacklinks.sitewide} = true)`,
      newCount: sql<number>`count(*) filter (where ${domainBacklinks.isNew} = true)`,
      lostCount: sql<number>`count(*) filter (where ${domainBacklinks.isLost} = true)`,
    })
    .from(domainBacklinks)
    .where(eq(domainBacklinks.siteId, siteId));
  const total = Number(row?.backlinks ?? 0);
  const pct = (n: number) => (total ? Math.round((n / total) * 100) : 0);
  return {
    backlinks: total,
    refDomains: Number(row?.refDomains ?? 0),
    dofollowPct: pct(Number(row?.dofollow ?? 0)),
    sitewidePct: pct(Number(row?.sitewide ?? 0)),
    newCount: Number(row?.newCount ?? 0),
    lostCount: Number(row?.lostCount ?? 0),
  };
}

export interface PageOpts {
  dofollow?: boolean;
  status?: "new" | "lost";
  page?: number;
  pageSize?: number;
}

function toDomainBacklink(
  r: typeof domainBacklinks.$inferSelect,
): DomainBacklink {
  return {
    id: r.id,
    siteId: r.siteId,
    sourceUrl: r.sourceUrl,
    sourceTitle: r.sourceTitle,
    sourceDomain: r.sourceDomain,
    targetUrl: r.targetUrl,
    anchor: r.anchor,
    authority: r.authority,
    nofollow: r.nofollow,
    sponsored: r.sponsored,
    ugc: r.ugc,
    sitewide: r.sitewide,
    placement: r.placement,
    firstSeen: r.firstSeen ? r.firstSeen.toISOString() : null,
    lastSeen: r.lastSeen ? r.lastSeen.toISOString() : null,
    isNew: r.isNew,
    isLost: r.isLost,
  };
}

export async function getDomainBacklinksPage(
  siteId: string,
  opts: PageOpts,
): Promise<DomainBacklinksPage> {
  const { dofollow, status, page = 0, pageSize = 50 } = opts;
  const conds = [eq(domainBacklinks.siteId, siteId)];
  if (dofollow === true) conds.push(eq(domainBacklinks.nofollow, false));
  if (dofollow === false) conds.push(eq(domainBacklinks.nofollow, true));
  if (status === "new") conds.push(eq(domainBacklinks.isNew, true));
  if (status === "lost") conds.push(eq(domainBacklinks.isLost, true));
  const where = and(...conds);
  const [{ total }] = await db
    .select({ total: count() })
    .from(domainBacklinks)
    .where(where);
  const rows = await db
    .select()
    .from(domainBacklinks)
    .where(where)
    .orderBy(desc(domainBacklinks.authority))
    .limit(pageSize)
    .offset(page * pageSize);
  return { rows: rows.map(toDomainBacklink), total: Number(total) };
}
