/**
 * Calculate Levenshtein distance between two strings
 * @param {string} str1 - First string
 * @param {string} str2 - Second string
 * @returns {number} - Edit distance
 */
function levenshteinDistance(str1, str2) {
  const len1 = str1.length;
  const len2 = str2.length;
  const matrix = Array(len1 + 1).fill(null).map(() => Array(len2 + 1).fill(0));

  for (let i = 0; i <= len1; i++) matrix[i][0] = i;
  for (let j = 0; j <= len2; j++) matrix[0][j] = j;

  for (let i = 1; i <= len1; i++) {
    for (let j = 1; j <= len2; j++) {
      const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
      matrix[i][j] = Math.min(
        matrix[i - 1][j] + 1,      // deletion
        matrix[i][j - 1] + 1,      // insertion
        matrix[i - 1][j - 1] + cost // substitution
      );
    }
  }

  return matrix[len1][len2];
}

/**
 * Calculate similarity percentage between two strings (0-100%)
 * @param {string} str1 - First string
 * @param {string} str2 - Second string
 * @returns {number} - Similarity percentage
 */
export function calculateSimilarity(str1, str2) {
  const lower1 = str1.toLowerCase().trim();
  const lower2 = str2.toLowerCase().trim();

  if (lower1 === lower2) return 100;
  if (lower1.length === 0 || lower2.length === 0) return 0;

  // Check if one string contains the other (substring match)
  if (lower1.includes(lower2) || lower2.includes(lower1)) {
    // Give high similarity for substring matches
    const minLen = Math.min(lower1.length, lower2.length);
    const maxLen = Math.max(lower1.length, lower2.length);
    return Math.round((minLen / maxLen) * 100);
  }

  const distance = levenshteinDistance(lower1, lower2);
  const maxLength = Math.max(lower1.length, lower2.length);
  const similarity = ((maxLength - distance) / maxLength) * 100;

  return Math.round(similarity);
}

/**
 * Find items with similarity >= threshold
 * @param {string} inputName - Item name to check
 * @param {Array} existingItems - Array of existing items with item_name property
 * @param {number} threshold - Minimum similarity percentage (default 80)
 * @returns {Array} - Array of similar items sorted by similarity
 */
export function findSimilarItems(inputName, existingItems, threshold = 70) {
  const similar = [];

  for (const item of existingItems) {
    const similarity = calculateSimilarity(inputName, item.item_name);
    if (similarity >= threshold && similarity < 100) {
      similar.push({ ...item, similarity });
    }
  }

  // Sort by similarity descending
  return similar.sort((a, b) => b.similarity - a.similarity);
}
