import type { FraudAdapter, EarnCtx, FraudSignal, AdapterConfig } from '../types.js';
import { eq, sql } from 'drizzle-orm';
import { paymentMethods } from '@/server/db/schema.js';

export const paymentInstrumentAdapter: FraudAdapter<EarnCtx> = {
  key: 'payment-instrument',
  points: ['EARN'],
  async evaluate(ctx: EarnCtx, _cfg: AdapterConfig): Promise<FraudSignal | null> {
    if (!ctx.cardFingerprintReferee) return null;

    // Check if referrer's payment methods share the same card fingerprint as referee
    const referrerCards = await ctx.db
      .select({ fingerprint: paymentMethods.cardFingerprint })
      .from(paymentMethods)
      .where(eq(paymentMethods.userId, ctx.referrerUserId));

    const referrerFingerprints = new Set(referrerCards.map((c) => c.fingerprint).filter(Boolean));

    if (referrerFingerprints.has(ctx.cardFingerprintReferee)) {
      return {
        adapter: 'payment-instrument',
        action: 'block',
        codes: ['SHARED_CARD_FINGERPRINT'],
        detail: { fingerprintSuffix: ctx.cardFingerprintReferee.slice(-8) },
      };
    }

    // Check for referee using same card across multiple referral accounts (ring)
    const result = (await ctx.db.execute(sql`
      SELECT COUNT(DISTINCT r.referrer_user_id) AS cnt
      FROM referrals r
      JOIN payment_methods pm ON pm.user_id = r.referee_user_id
      WHERE pm.card_fingerprint = ${ctx.cardFingerprintReferee}
        AND r.referee_user_id != ${ctx.refereeUserId}
      LIMIT 1
    `)) as { rows: Array<{ cnt: string }> };
    const cnt = Number((result.rows[0] as { cnt: string })?.cnt ?? 0);
    if (cnt > 0) {
      return {
        adapter: 'payment-instrument',
        action: 'flag',
        codes: ['CARD_SEEN_IN_OTHER_REFERRAL'],
        detail: { fingerprintSuffix: ctx.cardFingerprintReferee.slice(-8), otherReferrals: cnt },
      };
    }

    return null;
  },
};
