/**
 * Brand-keyword guardrail.
 *
 * Detects affiliates routing paid search traffic through brand-term bids on
 * Google/Bing/Yahoo/DuckDuckGo. If the referrer URL is a search engine and the
 * query contains a brand keyword, the click is flagged SEARCH_ENGINE_BRAND_BID.
 *
 * Rule: setCookie=false when isSuspicious=true — do not attribute.
 */

import { tryParseRefererUrl } from './referer-parse.js';

const SEARCH_ENGINE_HOSTS = [
  'google.',
  'bing.com',
  'yahoo.com',
  'duckduckgo.com',
  'yandex.',
  'baidu.com',
];

export type GuardResult = {
  isSuspicious: boolean;
  codes: string[];
  /** Whether the referral cookie should be set for this request. */
  setCookie: boolean;
};

export type BrandKeywordSettings = {
  brandKeywordBlocklist: string[];
  disallowedRefererHosts: string[];
};

function isSearchEngine(url: URL): boolean {
  const host = url.hostname.toLowerCase();
  return SEARCH_ENGINE_HOSTS.some((h) => host.includes(h));
}

function extractSearchQuery(url: URL): string {
  // Google/Bing/DuckDuckGo use `q`; Yahoo uses `p`.
  return (url.searchParams.get('q') ?? url.searchParams.get('p') ?? '').toLowerCase();
}

/**
 * Evaluate brand-keyword bidding.
 *
 * @param refererUrl - The raw Referer header value (or empty string).
 * @param settings   - Affiliate security settings with brandKeywordBlocklist.
 */
export function evaluateBrandKeyword(
  refererUrl: string,
  settings: BrandKeywordSettings,
): GuardResult {
  if (!refererUrl) {
    return { isSuspicious: false, codes: [], setCookie: true };
  }

  const url = tryParseRefererUrl(refererUrl);
  if (!url) {
    return { isSuspicious: false, codes: [], setCookie: true };
  }

  if (!isSearchEngine(url)) {
    return { isSuspicious: false, codes: [], setCookie: true };
  }

  const query = extractSearchQuery(url);
  const hitsBrandKeyword = settings.brandKeywordBlocklist.some((kw) =>
    query.includes(kw.toLowerCase()),
  );

  if (hitsBrandKeyword) {
    return {
      isSuspicious: true,
      codes: ['SEARCH_ENGINE_BRAND_BID'],
      setCookie: false,
    };
  }

  return { isSuspicious: false, codes: [], setCookie: true };
}
