import type { FraudAdapter, SignupCtx, FraudSignal, AdapterConfig } from '../types.js';

// Well-known provider domains that legitimately accept all addresses — never flag these
const KNOWN_PROVIDERS = new Set([
  'gmail.com',
  'googlemail.com',
  'yahoo.com',
  'yahoo.co.il',
  'outlook.com',
  'hotmail.com',
  'live.com',
  'icloud.com',
  'me.com',
  'mac.com',
  'protonmail.com',
  'proton.me',
  'walla.co.il',
  'bezeqint.net',
]);

/**
 * Flag when:
 *   1. Domain is NOT a known major provider.
 *   2. Domain appears for the Nth new user in a rolling window (cfg.params.clusterThreshold).
 * Relies on a simple DB count; no external DNS call (avoids latency in hot path).
 */
export const emailCatchallDomainAdapter: FraudAdapter<SignupCtx> = {
  key: 'email-catchall-domain',
  points: ['SIGNUP'],
  async evaluate(ctx: SignupCtx, cfg: AdapterConfig): Promise<FraudSignal | null> {
    if (!ctx.refereeEmail) return null;
    const domain = ctx.refereeEmail.toLowerCase().split('@')[1] ?? '';
    if (KNOWN_PROVIDERS.has(domain)) return null;

    const threshold = (cfg.params?.['clusterThreshold'] as number | undefined) ?? 3;
    const windowHours = Number(cfg.params?.['windowHours'] ?? 24);
    if (!Number.isInteger(windowHours) || windowHours <= 0 || windowHours > 8760) return null;

    // Count recent signups from same domain
    const { sql } = await import('drizzle-orm');

    // email_canonical_index is plaintext (email column is pgcrypto-encrypted); scoped to referred users with canonical index populated
    const result = (await ctx.db.execute(sql`
      SELECT COUNT(*) AS cnt
      FROM users
      WHERE email_canonical_index ILIKE ${'%@' + domain}
        AND created_at >= NOW() - (INTERVAL '1 hour' * ${windowHours})
    `)) as { rows: Array<{ cnt: string }> };
    const cnt = Number((result.rows[0] as { cnt: string })?.cnt ?? 0);

    if (cnt < threshold) return null;

    return {
      adapter: 'email-catchall-domain',
      action: 'flag',
      codes: ['CATCHALL_DOMAIN_CLUSTER'],
      detail: { domain, signupsInWindow: cnt, threshold, windowHours },
    };
  },
};
