export type AltSignalMatch = {
  reason: 'ip' | 'invite_cluster';
  matchedUserId: string | null;
};

export type AltDetectionInput = {
  userId: string;
  accountAgeDays: number;
  inviteCode: string | null;
  ipHash: string | null;
  /** Prior verification records in the same guild (excluding current user). */
  priorRecords: Array<{
    userId: string;
    inviteCode: string | null;
    ipHash: string | null;
    createdAt: Date;
    flaggedAsAlt: boolean;
  }>;
  altIpWindowDays: number;
  altInviteWindowHours: number;
  altMaxAccountsPerInvite: number;
  /** Only flag invite clusters when the current account is this young or younger. */
  youngAccountMaxDays?: number;
};

/**
 * Detects likely alt accounts from Discord + captcha signals.
 * Does not use browser fingerprinting beyond salted IP / UA hashes from the captcha page.
 */
export function detectAltAccount(input: AltDetectionInput): AltSignalMatch | null {
  const youngMax = input.youngAccountMaxDays ?? 7;
  const now = Date.now();

  if (input.ipHash) {
    const ipWindowMs = input.altIpWindowDays * 24 * 60 * 60 * 1000;
    const ipMatch = input.priorRecords.find(
      (record) =>
        record.ipHash === input.ipHash &&
        now - record.createdAt.getTime() <= ipWindowMs
    );
    if (ipMatch) {
      return { reason: 'ip', matchedUserId: ipMatch.userId };
    }
  }

  if (input.inviteCode && input.accountAgeDays <= youngMax) {
    const inviteWindowMs = input.altInviteWindowHours * 60 * 60 * 1000;
    const recentSameInvite = input.priorRecords.filter(
      (record) =>
        record.inviteCode === input.inviteCode &&
        now - record.createdAt.getTime() <= inviteWindowMs
    );
    if (recentSameInvite.length >= input.altMaxAccountsPerInvite) {
      return {
        reason: 'invite_cluster',
        matchedUserId: recentSameInvite[0]?.userId ?? null
      };
    }
  }

  return null;
}
