import { createHash } from "crypto";
import type { Request } from "express";
import { extractClientIp } from "@bff/core/http/request-context.util.js";

export function getUserAgentHash(userAgent: string | string[] | undefined): string {
  const value = Array.isArray(userAgent) ? userAgent[0] : userAgent;
  const normalized = typeof value === "string" ? value : "unknown";
  return createHash("sha256").update(normalized).digest("hex").slice(0, 16);
}

export function getRequestRateLimitIdentity(request: Request): {
  ip: string;
  userAgentHash: string;
} {
  return {
    ip: extractClientIp(request),
    userAgentHash: getUserAgentHash(request.headers["user-agent"]),
  };
}

/**
 * Generate a fingerprint from request for session binding
 * Combines IP and User-Agent hash to create a unique identifier
 * Used for OTP verification to detect context changes
 *
 * @param request - Express request object
 * @returns SHA256 hash of IP + User-Agent (truncated to 32 chars)
 */
export function getRateLimitFingerprint(request: Request): string {
  const { ip, userAgentHash } = getRequestRateLimitIdentity(request);
  const combined = `${ip}:${userAgentHash}`;
  return createHash("sha256").update(combined).digest("hex").slice(0, 32);
}

export function buildRateLimitKey(...parts: Array<string | undefined>): string {
  return parts.filter(Boolean).join(":");
}
