// Simple in-memory rate limiting (for production, consider Redis or database)
const loginAttempts = new Map<string, { count: number; lastAttempt: number }>();
const blockedIPs = new Map<string, number>(); // IP -> blocked until timestamp

export const checkRateLimit = (ip: string): { allowed: boolean; attemptsLeft: number } => {
  const now = Date.now();
  const maxAttempts = 5;
  const windowMs = 15 * 60 * 1000; // 15 minutes
  const blockDurationMs = 60 * 60 * 1000; // 1 hour

  // Check if IP is currently blocked
  const blockedUntil = blockedIPs.get(ip);
  if (blockedUntil && now < blockedUntil) {
    return { allowed: false, attemptsLeft: 0 };
  }

  // Remove expired block
  if (blockedUntil && now >= blockedUntil) {
    blockedIPs.delete(ip);
  }

  // Get current attempts for this IP
  const attempts = loginAttempts.get(ip);
  
  // Clean up old attempts outside the window
  if (attempts && (now - attempts.lastAttempt) > windowMs) {
    loginAttempts.delete(ip);
    return { allowed: true, attemptsLeft: maxAttempts };
  }

  const currentCount = attempts?.count || 0;
  
  if (currentCount >= maxAttempts) {
    // Block the IP
    blockedIPs.set(ip, now + blockDurationMs);
    console.warn(`🚨 IP ${ip} blocked due to ${currentCount} failed login attempts`);
    return { allowed: false, attemptsLeft: 0 };
  }

  return { allowed: true, attemptsLeft: maxAttempts - currentCount };
};

export const recordFailedAttempt = (ip: string): void => {
  const now = Date.now();
  const attempts = loginAttempts.get(ip);
  
  if (attempts) {
    attempts.count += 1;
    attempts.lastAttempt = now;
  } else {
    loginAttempts.set(ip, { count: 1, lastAttempt: now });
  }
  
  const newCount = loginAttempts.get(ip)?.count || 1;
  console.warn(`⚠️ Failed login attempt from ${ip} (${newCount}/5)`);
};

export const clearFailedAttempts = (ip: string): void => {
  loginAttempts.delete(ip);
  blockedIPs.delete(ip);
  console.log(`✅ Cleared failed attempts for ${ip}`);
};

// Input validation
export const validateLoginInput = (username: string, password: string): string[] => {
  const errors: string[] = [];
  
  if (!username || typeof username !== 'string') {
    errors.push('Username is required');
  } else if (username.length < 2) {
    errors.push('Username must be at least 2 characters');
  } else if (username.length > 100) {
    errors.push('Username is too long');
  }
  
  if (!password || typeof password !== 'string') {
    errors.push('Password is required');
  } else if (password.length < 6) {
    errors.push('Password must be at least 6 characters');
  } else if (password.length > 200) {
    errors.push('Password is too long');
  }
  
  // Basic sanitization check
  const dangerousChars = /<script|javascript:|data:|vbscript:/i;
  if (dangerousChars.test(username) || dangerousChars.test(password)) {
    errors.push('Invalid characters detected');
  }
  
  return errors;
};

// Get client IP helper
export const getClientIP = (event: any): string => {
  // Try various headers that might contain the real IP
  const headers = getHeaders(event);
  
  return (
    headers['x-forwarded-for']?.split(',')[0]?.trim() ||
    headers['x-real-ip'] ||
    headers['x-client-ip'] ||
    headers['cf-connecting-ip'] || // Cloudflare
    event.node?.req?.connection?.remoteAddress ||
    event.node?.req?.socket?.remoteAddress ||
    'unknown'
  );
};

// Clean up old entries periodically (call this from a cron job or similar)
export const cleanupOldEntries = (): void => {
  const now = Date.now();
  const windowMs = 15 * 60 * 1000; // 15 minutes
  
  // Clean up old login attempts
  for (const [ip, attempts] of loginAttempts.entries()) {
    if ((now - attempts.lastAttempt) > windowMs) {
      loginAttempts.delete(ip);
    }
  }
  
  // Clean up expired blocks
  for (const [ip, blockedUntil] of blockedIPs.entries()) {
    if (now >= blockedUntil) {
      blockedIPs.delete(ip);
    }
  }
  
  console.log('🧹 Cleaned up old security entries');
};

// Password validation function
export const validatePassword = (password: string): { isValid: boolean; errors: string[] } => {
  const errors: string[] = [];
  
  if (!password || typeof password !== 'string') {
    errors.push('Password is required');
    return { isValid: false, errors };
  }

  if (password.length < 8) {
    errors.push('Password must be at least 8 characters long');
  }

  if (password.length > 128) {
    errors.push('Password must not exceed 128 characters');
  }

  if (!/[A-Z]/.test(password)) {
    errors.push('Password must contain at least one uppercase letter');
  }

  if (!/[a-z]/.test(password)) {
    errors.push('Password must contain at least one lowercase letter');
  }

  if (!/[0-9]/.test(password)) {
    errors.push('Password must contain at least one number');
  }

  // Optional: require special characters
  // if (!/[^A-Za-z0-9]/.test(password)) {
  //   errors.push('Password must contain at least one special character');
  // }

  // Check for common weak patterns
  const commonPatterns = [
    /(.)\1{2,}/i, // Three or more consecutive identical characters
    /123456|654321|abcdef|qwerty|password|admin|login/i, // Common weak passwords
  ];

  for (const pattern of commonPatterns) {
    if (pattern.test(password)) {
      errors.push('Password contains common patterns that make it weak');
      break;
    }
  }

  return {
    isValid: errors.length === 0,
    errors
  };
};

// Initialize cleanup interval (runs every 5 minutes)
if (typeof setInterval !== 'undefined') {
  setInterval(cleanupOldEntries, 5 * 60 * 1000);
}
