import { describe, expect, it } from 'vitest';
import { detectAltAccount } from './alt-detection.js';

describe('detectAltAccount', () => {
  const basePrior = {
    userId: 'user-a',
    inviteCode: 'abc123',
    ipHash: 'ip-hash-1',
    createdAt: new Date(),
    flaggedAsAlt: false
  };

  it('matches identical IP hash within window', () => {
    const match = detectAltAccount({
      userId: 'user-b',
      accountAgeDays: 30,
      inviteCode: null,
      ipHash: 'ip-hash-1',
      priorRecords: [basePrior],
      altIpWindowDays: 30,
      altInviteWindowHours: 48,
      altMaxAccountsPerInvite: 3
    });
    expect(match).toEqual({ reason: 'ip', matchedUserId: 'user-a' });
  });

  it('does not match when IP window expired', () => {
    const match = detectAltAccount({
      userId: 'user-b',
      accountAgeDays: 30,
      inviteCode: null,
      ipHash: 'ip-hash-1',
      priorRecords: [
        {
          ...basePrior,
          createdAt: new Date(Date.now() - 40 * 24 * 60 * 60 * 1000)
        }
      ],
      altIpWindowDays: 30,
      altInviteWindowHours: 48,
      altMaxAccountsPerInvite: 3
    });
    expect(match).toBeNull();
  });

  it('flags invite clusters for young accounts', () => {
    const now = Date.now();
    const match = detectAltAccount({
      userId: 'user-new',
      accountAgeDays: 2,
      inviteCode: 'raid',
      ipHash: null,
      priorRecords: [
        { ...basePrior, userId: 'u1', inviteCode: 'raid', createdAt: new Date(now - 60_000) },
        { ...basePrior, userId: 'u2', inviteCode: 'raid', createdAt: new Date(now - 120_000) },
        { ...basePrior, userId: 'u3', inviteCode: 'raid', createdAt: new Date(now - 180_000) }
      ],
      altIpWindowDays: 30,
      altInviteWindowHours: 48,
      altMaxAccountsPerInvite: 3
    });
    expect(match?.reason).toBe('invite_cluster');
  });

  it('ignores invite clusters for older accounts', () => {
    const now = Date.now();
    const match = detectAltAccount({
      userId: 'user-old',
      accountAgeDays: 90,
      inviteCode: 'raid',
      ipHash: null,
      priorRecords: [
        { ...basePrior, userId: 'u1', inviteCode: 'raid', createdAt: new Date(now - 60_000) },
        { ...basePrior, userId: 'u2', inviteCode: 'raid', createdAt: new Date(now - 120_000) },
        { ...basePrior, userId: 'u3', inviteCode: 'raid', createdAt: new Date(now - 180_000) }
      ],
      altIpWindowDays: 30,
      altInviteWindowHours: 48,
      altMaxAccountsPerInvite: 3
    });
    expect(match).toBeNull();
  });
});
