/**
 * Login risk scorer for SmartAuth.
 *
 * Evaluates risk based on:
 * - IP reputation (new IP vs known)
 * - Location anomaly (new country/city)
 * - Time anomaly (unusual login time)
 * - Device trust level
 * - Recent failure count
 * - Login method
 */

import type { RiskLevel } from './types.js';

export interface RiskInput {
  ip: string;
  userAgent?: string;
  fingerprint?: string;
  isNewIp: boolean;
  isNewDevice: boolean;
  isDeviceTrusted: boolean;
  recentFailures: number;
  method: string;
  hourOfDay: number;
}

export interface RiskResult {
  score: number; // 0-100
  level: RiskLevel;
  flags: string[];
}

export function scoreLoginRisk(input: RiskInput): RiskResult {
  let score = 0;
  const flags: string[] = [];

  // New IP — moderate risk
  if (input.isNewIp) {
    score += 15;
    flags.push('new_ip');
  }

  // New device — moderate risk
  if (input.isNewDevice) {
    score += 20;
    flags.push('new_device');
  }

  // Untrusted device — low risk bump
  if (!input.isDeviceTrusted) {
    score += 10;
    flags.push('untrusted_device');
  }

  // Recent failures — escalating risk
  if (input.recentFailures >= 3) {
    score += Math.min(input.recentFailures * 5, 30);
    flags.push(`recent_failures_${input.recentFailures}`);
  }

  // Unusual hour (2am-5am local) — slight risk
  if (input.hourOfDay >= 2 && input.hourOfDay <= 5) {
    score += 10;
    flags.push('unusual_hour');
  }

  // Password login on a new device is riskier than OAuth/passkey
  if (input.method === 'password' && input.isNewDevice) {
    score += 10;
    flags.push('password_new_device');
  }

  // Cap at 100
  score = Math.min(score, 100);

  // Map score to level
  let level: RiskLevel;
  if (score >= 80) level = 'critical';
  else if (score >= 50) level = 'high';
  else if (score >= 25) level = 'medium';
  else level = 'low';

  return { score, level, flags };
}
