/**
 * UID Generator Utility
 * Generates unique identifiers for inventory items (barcodes/QR codes)
 */

// Import crypto for random generation
const crypto = require('crypto');
// Import app configuration
const appConfig = require('../config/app');

/**
 * Generate unique UID for inventory item
 * Generates a unique identifier for inventory items
 * Format: {PREFIX}-{TIMESTAMP}-{RANDOM}
 * @param {string} prefix - Optional prefix (defaults to app barcode prefix)
 * @returns {string} Generated UID
 */
const generateUID = (prefix = null) => {
  // Get prefix from config or use provided prefix
  const uidPrefix = prefix || appConfig.barcode.prefix || 'UID'; // Default to 'UID' if not configured
  
  // Get current timestamp (milliseconds since epoch)
  const timestamp = Date.now(); // Current timestamp
  
  // Generate random string (8 characters, hex)
  const randomBytes = crypto.randomBytes(4); // Generate 4 random bytes
  const randomString = randomBytes.toString('hex').toUpperCase(); // Convert to uppercase hex string
  
  // Generate UID: PREFIX-TIMESTAMP-RANDOM
  const uid = `${uidPrefix}-${timestamp}-${randomString}`; // Combine prefix, timestamp, and random string
  
  // Return generated UID
  return uid; // Return UID
};

/**
 * Generate barcode (numeric)
 * Generates a numeric barcode for inventory items
 * Format: {PREFIX}{SEQUENTIAL}
 * @param {number} length - Barcode length (defaults to app config)
 * @returns {string} Generated barcode
 */
const generateBarcode = (length = null) => {
  // Get barcode length from config or use provided length
  const barcodeLength = length || appConfig.barcode.length || 12; // Default to 12 if not configured
  
  // Get prefix from config
  const prefix = appConfig.barcode.prefix || ''; // Get prefix (can be empty)
  
  // Calculate remaining length for sequential part
  const remainingLength = barcodeLength - prefix.length; // Remaining length for sequential number
  
  // Generate random numeric string for remaining length
  const randomNumeric = Math.floor(Math.random() * Math.pow(10, remainingLength)).toString().padStart(remainingLength, '0'); // Generate random number with leading zeros
  
  // Combine prefix and random numeric string
  const barcode = `${prefix}${randomNumeric}`; // Combine prefix and numeric part
  
  // Return generated barcode
  return barcode; // Return barcode
};

/**
 * Validate UID format
 * Validates if a string is a valid UID format
 * @param {string} uid - UID to validate
 * @returns {boolean} True if valid, false otherwise
 */
const isValidUID = (uid) => {
  // Check if UID is a non-empty string
  if (!uid || typeof uid !== 'string') {
    return false; // Invalid if not a string
  }
  
  // Check UID length (max 100 characters as per model)
  if (uid.length > 100 || uid.length < 1) {
    return false; // Invalid if length is out of range
  }
  
  // Basic format validation (contains alphanumeric, dashes, underscores)
  const uidPattern = /^[A-Z0-9_-]+$/i; // Pattern for valid UID characters
  if (!uidPattern.test(uid)) {
    return false; // Invalid if doesn't match pattern
  }
  
  // Return true if valid
  return true; // Valid UID
};

/**
 * Validate barcode format
 * Validates if a string is a valid barcode format
 * @param {string} barcode - Barcode to validate
 * @returns {boolean} True if valid, false otherwise
 */
const isValidBarcode = (barcode) => {
  // Check if barcode is a non-empty string
  if (!barcode || typeof barcode !== 'string') {
    return false; // Invalid if not a string
  }
  
  // Check barcode length (max 100 characters as per model)
  if (barcode.length > 100 || barcode.length < 1) {
    return false; // Invalid if length is out of range
  }
  
  // Basic format validation (alphanumeric only)
  const barcodePattern = /^[A-Z0-9]+$/i; // Pattern for valid barcode characters (alphanumeric only)
  if (!barcodePattern.test(barcode)) {
    return false; // Invalid if doesn't match pattern
  }
  
  // Return true if valid
  return true; // Valid barcode
};

// Export utility functions
module.exports = {
  generateUID, // Generate UID function
  generateBarcode, // Generate barcode function
  isValidUID, // Validate UID function
  isValidBarcode, // Validate barcode function
};

