/**
 * 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.
 */

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 }
  }

  let url: URL
  try {
    url = new URL(refererUrl)
  } catch {
    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 }
}
