import * as nanoidGood from 'nanoid-good';
import * as en from 'nanoid-good/locale/en';

/**
 * Nanoid instance configured with English locale.
 * nanoid-good provides URL-friendly, secure unique string generation.
 * The English locale ensures only alphanumeric characters are used.
 */
const nanoid = nanoidGood.nanoid(en);

/**
 * Converts a string into a URL-friendly slug format.
 * This function normalizes text by removing diacritics, special characters,
 * and converting spaces to hyphens to create SEO-friendly URLs.
 *
 * @param name - The input string to convert to a slug
 * @returns {string} A URL-friendly slug, or 'unknown' if the result is empty
 *
 * @example
 * // Basic conversion
 * slugGenerator("Hello World!"); // "hello-world"
 *
 * @example
 * // With special characters and diacritics
 * slugGenerator("Café & Crème"); // "cafe-and-creme"
 *
 * @example
 * // With multiple spaces and slashes
 * slugGenerator("Home / About Us"); // "home-about-us"
 *
 * @example
 * // Empty result fallback
 * slugGenerator("___"); // "unknown"
 *
 * @example
 * // Non-string input (converted to string)
 * slugGenerator(123); // "123"
 */
export const slugGenerator = (name: string): string => {
  // Process the input string through multiple transformations
  const slug =
    name &&
    name
      // Convert to string (handles non-string inputs)
      .toString()
      // Convert to lowercase for consistency
      .toLowerCase()
      // Normalize Unicode characters (NFKD normalization)
      // This separates characters from their diacritical marks
      .normalize('NFKD')
      // Remove all diacritical marks (accents, umlauts, etc.)
      .replace(/[\u0300-\u036f]/g, '')
      // Replace slashes with spaces around them with hyphens
      .replace(/\s*\/\s*/g, '-')
      // Replace HTML-encoded ampersands with '-and-'
      .replace(/\s*&amp;\s*/g, '-and-')
      // Replace one or more spaces with a single hyphen
      .replace(/\s+/g, '-')
      // Remove apostrophe HTML entities
      .replace(/apos;/g, '')
      // Remove underscores
      .replace(/_/g, '')
      // Remove any remaining non-word characters except hyphens
      .replace(/[^\w-]+/g, '');

  // Return the slug, or 'unknown' if the result is an empty string
  return slug === '' ? 'unknown' : slug;
};

/**
 * Generates a cryptographically secure random string using nanoid.
 * Suitable for generating unique IDs, tokens, or secure random strings.
 *
 * @param length - Optional length of the random string.
 *                If not specified, uses nanoid's default (usually 21 characters)
 * @returns {string} A secure random string containing URL-safe characters
 *
 * @example
 * // Default length (usually 21 chars)
 * generateRandomString(); // "Uakgb_J5m9g~0JDMbcJqLJ"
 *
 * @example
 * // Custom length
 * generateRandomString(10); // "V1StGXR8_Z"
 *
 * @example
 * // For database IDs
 * const userId = generateRandomString(16);
 *
 * @example
 * // For secure tokens
 * const resetToken = generateRandomString(32);
 *
 * @note
 * - Uses nanoid which is cryptographically secure
 * - Generates URL-friendly strings (A-Za-z0-9_-)
 * - Alphabet size: 64 characters
 * - Collision probability: Very low (for 1M IDs at 1000 IDs/hour: ~1% chance in ~1000 years for 21 chars)
 */
export const generateRandomString = (length?: number): string => {
  return nanoid(length);
};

/**
 * Common use cases:
 *
 * 1. Generating URL slugs from titles:
 *    const postSlug = slugGenerator("My Blog Post Title") + "-" + generateRandomString(8);
 *    // Result: "my-blog-post-title-V1StGXR8"
 *
 * 2. Creating unique identifiers:
 *    const sessionId = generateRandomString(32);
 *
 * 3. Normalizing user input for URLs:
 *    const profileSlug = slugGenerator(userName);
 *
 * 4. File name generation:
 *    const fileName = slugGenerator(originalName) + "-" + generateRandomString(6) + ".jpg";
 *
 * Security considerations:
 * - nanoid is cryptographically secure (using crypto.getRandomValues())
 * - Slugs are sanitized but not guaranteed to be unique (consider appending a random string)
 * - For high-security applications, ensure appropriate length for random strings
 */
