import crypto from 'crypto';

import { default as DOMPurify } from 'dompurify';
import { Request } from 'express';
import { JSDOM } from 'jsdom';

// Create a DOM window for server-side DOMPurify usage
const window = new JSDOM('').window;
const DOMPurifyServer = DOMPurify(window);

/**
 * EN: Utility helper functions
 * VI: Các hàm tiện ích helper
 */

/**
 * EN: Generate random string
 * VI: Tạo chuỗi ngẫu nhiên
 */
export function generateRandomString(length: number = 32): string {
  return crypto.randomBytes(length).toString('hex');
}

/**
 * EN: Hash string with SHA256
 * VI: Hash chuỗi với SHA256
 */
export function hashString(input: string): string {
  return crypto.createHash('sha256').update(input).digest('hex');
}

/**
 * EN: Validate email format
 * VI: Xác thực định dạng email
 */
export function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

/**
 * EN: Sanitize input string to prevent XSS attacks
 * VI: Làm sạch chuỗi input để ngăn chặn tấn công XSS
 */
export function sanitizeInput(input: string): string {
  if (!input || typeof input !== 'string') {
    return '';
  }

  // First trim whitespace
  const trimmed = input.trim();

  // Use DOMPurify to sanitize HTML and prevent XSS
  const sanitized = DOMPurifyServer.sanitize(trimmed, {
    ALLOWED_TAGS: [], // No HTML tags allowed
    ALLOWED_ATTR: [], // No attributes allowed
  });

  return sanitized;
}

/**
 * EN: Get client IP from request
 * VI: Lấy IP client từ request
 */
export function getClientIP(req: Request): string {
  const forwardedFor = req.headers['x-forwarded-for'];
  const forwardedIp = Array.isArray(forwardedFor)
    ? forwardedFor[0]
    : typeof forwardedFor === 'string'
      ? forwardedFor.split(',')[0]
      : undefined;
  return (
    forwardedIp ||
    (Array.isArray(req.headers['x-real-ip'])
      ? req.headers['x-real-ip'][0]
      : req.headers['x-real-ip']) ||
    req.ip ||
    req.socket.remoteAddress ||
    'unknown'
  );
}

/**
 * EN: Parse expiration time string to Date
 * VI: Parse chuỗi thời gian hết hạn thành Date
 */
export function parseExpiration(expiration: string): Date {
  return new Date(expiration);
}

/**
 * EN: Check if date is expired
 * VI: Kiểm tra date đã hết hạn chưa
 */
export function isExpired(date: Date): boolean {
  return date < new Date();
}
