// ─── Citation parser ──────────────────────────────────────────────────────────
// Normalizes and deduplicates citations across engine responses.

import { extractDomain, normalizeUrl } from "./engines/shared";
import type { Citation } from "./engines/shared";

export interface NormalizedCitation extends Citation {
  normalizedUrl: string;
  apexDomain: string;
}

export function parseCitations(raw: Citation[]): NormalizedCitation[] {
  const seen = new Set<string>();
  const out: NormalizedCitation[] = [];

  for (const c of raw) {
    if (!c.url) continue;
    const normalized = normalizeUrl(c.url);
    if (seen.has(normalized)) continue;
    seen.add(normalized);

    out.push({
      ...c,
      normalizedUrl: normalized,
      apexDomain: apexDomain(c.url),
      domain: c.domain || extractDomain(c.url),
    });
  }

  return out;
}

export function apexDomain(url: string): string {
  try {
    const host = new URL(url.startsWith("http") ? url : `https://${url}`).hostname.replace(
      /^www\./,
      "",
    );
    const parts = host.split(".");
    return parts.length > 2 ? parts.slice(-2).join(".") : host;
  } catch {
    return url;
  }
}

export interface DomainFrequency {
  domain: string;
  count: number;
  titles: string[];
  sampleUrl: string;
}

export function aggregateDomainFrequencies(
  citations: NormalizedCitation[],
): DomainFrequency[] {
  const map = new Map<string, DomainFrequency>();

  for (const c of citations) {
    const d = c.apexDomain;
    const entry = map.get(d) ?? { domain: d, count: 0, titles: [], sampleUrl: c.url };
    entry.count++;
    if (c.title && !entry.titles.includes(c.title)) entry.titles.push(c.title);
    map.set(d, entry);
  }

  return [...map.values()].sort((a, b) => b.count - a.count);
}
