function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
/**
 * 现金支付推荐算法
 * 
 * 核心原理：
 * 1. 每个推荐金额都应该是独立的最优组合
 * 2. 不推荐在已有最优解基础上添加额外面额的组合
 * 3. 优先推荐使用不同数量币种的组合
 * 4. 根据组合判断去重，避免扩展组合
 */

/**
 * 常见国家货币面额配置
 */
export var CURRENCY_DENOMINATIONS = {
  // 美元
  'USD': [100, 50, 20, 10, 5, 1, 0.5, 0.25, 0.1, 0.05, 0.01],
  // 人民币
  'CNY': [100, 50, 20, 10, 5, 1, 0.5, 0.1, 0.05, 0.01],
  'RMB': [100, 50, 20, 10, 5, 1, 0.5, 0.1, 0.05, 0.01],
  // 欧元
  'EUR': [500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01],
  // 日元
  'JPY': [10000, 5000, 2000, 1000, 500, 100, 50, 10, 5, 1],
  // 英镑
  'GBP': [50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01],
  // 澳元
  'AUD': [100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1],
  // 加元
  'CAD': [100, 50, 20, 10, 5, 2, 1, 0.25, 0.1, 0.05],
  // 港元
  'HKD': [1000, 500, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1],
  // 新台币
  'TWD': [2000, 1000, 500, 200, 100, 50, 10, 5, 1],
  // 韩元
  'KRW': [50000, 10000, 5000, 1000, 500, 100, 50, 10, 5, 1],
  // 新加坡元
  'SGD': [10000, 1000, 100, 50, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.01],
  // 瑞士法郎
  'CHF': [1000, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05],
  // 默认通用面额（如果币种不在列表中）
  'DEFAULT': [100, 50, 20, 10, 5, 1, 0.5, 0.25, 0.1, 0.05, 0.01]
};

/**
 * 支付组合类型定义
 */

/**
 * 最优支付金额推荐算法
 * 推荐通过不同数量面额组合刚好足够支付的最小金额
 * 
 * @param targetAmount 目标金额
 * @param denominations 币种面值数组
 * @returns 推荐支付金额数组
 */
export function recommendOptimalPayments(targetAmount, denominations) {
  // 参数验证
  if (targetAmount <= 0 || !isFinite(targetAmount) || isNaN(targetAmount)) {
    return [];
  }
  if (!denominations || !Array.isArray(denominations) || denominations.length === 0) {
    return [Math.ceil(targetAmount)];
  }

  // 过滤有效面额并限制搜索空间以提高性能
  var maxReasonableDenom = targetAmount * 5; // 适度限制搜索空间
  var validDenoms = denominations.filter(function (denom) {
    return denom > 0 && isFinite(denom) && !isNaN(denom) && denom <= maxReasonableDenom;
  }).slice(0, 8); // 限制面额数量以提高性能

  if (validDenoms.length === 0) {
    // 如果没有合适的面额，返回最接近的整数金额
    return [Math.ceil(targetAmount)];
  }
  try {
    // 处理精度问题，将金额转换为整数计算
    var precision = 100; // 假设最小单位是0.01
    var target = Math.round(targetAmount * precision);
    var denoms = validDenoms.map(function (d) {
      return Math.round(d * precision);
    }).sort(function (a, b) {
      return b - a;
    });

    // 存储不同的支付组合方案
    var paymentOptions = [];

    // 首先尝试找到精确匹配的组合
    var exactCombination = findExactCombination(target, denoms, precision);
    if (exactCombination) {
      paymentOptions.push(exactCombination);
    }

    // 为了提高效率，我们将按币种数量来生成组合
    // 1币种组合：只用一种面额
    for (var i = 0; i < Math.min(denoms.length, 6); i++) {
      var denom = denoms[i];
      var count = Math.ceil(target / denom);
      var sum = count * denom;
      if (sum >= target && count <= 12) {
        // 限制硬币数量以提高性能
        paymentOptions.push({
          combination: Array(count).fill(denom / precision),
          sum: sum / precision,
          coinCount: count,
          denomTypes: 1
        });
      }
    }

    // 2币种组合：使用两种面额（大幅限制搜索范围以提高性能）
    for (var _i = 0; _i < Math.min(denoms.length - 1, 5); _i++) {
      for (var j = _i + 1; j < Math.min(denoms.length, 6); j++) {
        var denom1 = denoms[_i];
        var denom2 = denoms[j];

        // 大幅限制搜索范围，基于目标金额动态调整
        var maxCount1 = Math.min(Math.ceil(target / denom1) + 1, 8);
        var maxCount2 = Math.min(Math.ceil(target / denom2) + 1, 10);
        for (var count1 = 1; count1 <= maxCount1; count1++) {
          for (var count2 = 1; count2 <= maxCount2; count2++) {
            var _sum = count1 * denom1 + count2 * denom2;
            if (_sum >= target) {
              var combination = [].concat(_toConsumableArray(Array(count1).fill(denom1 / precision)), _toConsumableArray(Array(count2).fill(denom2 / precision)));
              paymentOptions.push({
                combination: combination,
                sum: _sum / precision,
                coinCount: count1 + count2,
                denomTypes: 2
              });
            }
          }
        }
      }
    }

    // 3币种组合：使用三种面额（大幅限制搜索以提高效率）
    for (var _i2 = 0; _i2 < Math.min(denoms.length - 2, 3); _i2++) {
      for (var _j = _i2 + 1; _j < Math.min(denoms.length - 1, 4); _j++) {
        for (var k = _j + 1; k < Math.min(denoms.length, 5); k++) {
          var _denom = denoms[_i2];
          var _denom2 = denoms[_j];
          var denom3 = denoms[k];

          // 大幅限制搜索范围
          var _maxCount = Math.min(Math.ceil(target / _denom) + 1, 5);
          var _maxCount2 = Math.min(Math.ceil(target / _denom2) + 1, 6);
          var maxCount3 = Math.min(Math.ceil(target / denom3) + 1, 8);
          for (var _count = 1; _count <= _maxCount; _count++) {
            for (var _count2 = 1; _count2 <= _maxCount2; _count2++) {
              for (var count3 = 1; count3 <= maxCount3; count3++) {
                var _sum2 = _count * _denom + _count2 * _denom2 + count3 * denom3;
                if (_sum2 >= target) {
                  var _combination = [].concat(_toConsumableArray(Array(_count).fill(_denom / precision)), _toConsumableArray(Array(_count2).fill(_denom2 / precision)), _toConsumableArray(Array(count3).fill(denom3 / precision)));
                  paymentOptions.push({
                    combination: _combination,
                    sum: _sum2 / precision,
                    coinCount: _count + _count2 + count3,
                    denomTypes: 3
                  });
                }
              }
            }
          }
        }
      }
    }

    // 4币种组合：使用四种面额（极度限制搜索以提高性能）
    for (var _i3 = 0; _i3 < Math.min(denoms.length - 3, 2); _i3++) {
      for (var _j2 = _i3 + 1; _j2 < Math.min(denoms.length - 2, 3); _j2++) {
        for (var _k = _j2 + 1; _k < Math.min(denoms.length - 1, 4); _k++) {
          for (var l = _k + 1; l < Math.min(denoms.length, 5); l++) {
            var _denom3 = denoms[_i3];
            var _denom4 = denoms[_j2];
            var _denom5 = denoms[_k];
            var denom4 = denoms[l];

            // 极度限制搜索范围
            var _maxCount3 = Math.min(Math.ceil(target / _denom3) + 1, 3);
            var _maxCount4 = Math.min(Math.ceil(target / _denom4) + 1, 4);
            var _maxCount5 = Math.min(Math.ceil(target / _denom5) + 1, 5);
            var maxCount4 = Math.min(Math.ceil(target / denom4) + 1, 6);
            for (var _count3 = 1; _count3 <= _maxCount3; _count3++) {
              for (var _count4 = 1; _count4 <= _maxCount4; _count4++) {
                for (var _count5 = 1; _count5 <= _maxCount5; _count5++) {
                  for (var count4 = 1; count4 <= maxCount4; count4++) {
                    var _sum3 = _count3 * _denom3 + _count4 * _denom4 + _count5 * _denom5 + count4 * denom4;
                    if (_sum3 >= target) {
                      var _combination2 = [].concat(_toConsumableArray(Array(_count3).fill(_denom3 / precision)), _toConsumableArray(Array(_count4).fill(_denom4 / precision)), _toConsumableArray(Array(_count5).fill(_denom5 / precision)), _toConsumableArray(Array(count4).fill(denom4 / precision)));
                      paymentOptions.push({
                        combination: _combination2,
                        sum: _sum3 / precision,
                        coinCount: _count3 + _count4 + _count5 + count4,
                        denomTypes: 4
                      });
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    // 如果没有找到任何组合，提供默认建议
    if (paymentOptions.length === 0) {
      // 找到大于等于目标金额的最小面额
      var minValidDenom = validDenoms.find(function (denom) {
        return denom >= targetAmount;
      });
      if (minValidDenom) {
        return [minValidDenom];
      } else {
        // 使用最大面额的组合
        var maxDenom = Math.max.apply(Math, _toConsumableArray(validDenoms));
        var _count6 = Math.ceil(targetAmount / maxDenom);
        return [_count6 * maxDenom];
      }
    }

    // 移除重复和扩展组合
    var uniqueCombinations = removeDuplicateAndExtendedCombinations(paymentOptions, targetAmount);

    // 按币种类型数量排序，然后按总硬币数量排序，最后按金额排序
    uniqueCombinations.sort(function (a, b) {
      if (a.denomTypes !== b.denomTypes) {
        return a.denomTypes - b.denomTypes;
      }
      if (a.coinCount !== b.coinCount) {
        return a.coinCount - b.coinCount;
      }
      return a.sum - b.sum;
    });

    // 按金额去重并返回推荐的支付金额
    var uniqueAmounts = new Set();
    var finalResults = [];
    for (var _i4 = 0, _uniqueCombinations = uniqueCombinations; _i4 < _uniqueCombinations.length; _i4++) {
      var item = _uniqueCombinations[_i4];
      var roundedAmount = Math.round(item.sum * 100) / 100; // 处理浮点数精度
      if (!uniqueAmounts.has(roundedAmount) && finalResults.length < 10) {
        uniqueAmounts.add(roundedAmount);
        finalResults.push(roundedAmount);
      }
    }
    return finalResults.sort(function (a, b) {
      return a - b;
    });
  } catch (error) {
    // 发生错误时返回安全的默认值
    console.warn('推荐支付金额计算出错:', error);
    // 返回最接近的整数金额作为兜底
    var safeAmount = Math.ceil(targetAmount);
    return [targetAmount, safeAmount];
  }
}

/**
 * 尝试找到精确匹配目标金额的组合
 */
function findExactCombination(target, denoms, precision) {
  // 简单的深度优先搜索，限制搜索深度
  function dfs(remaining, denomIndex, currentCombination) {
    if (remaining === 0) {
      return currentCombination;
    }
    if (remaining < 0 || denomIndex >= denoms.length || currentCombination.length > 10) {
      return null;
    }
    var denom = denoms[denomIndex];

    // 尝试使用当前面额 0 到 maxCount 次
    var maxCount = Math.min(Math.floor(remaining / denom), 8);
    for (var count = maxCount; count >= 0; count--) {
      var newCombination = [].concat(_toConsumableArray(currentCombination), _toConsumableArray(Array(count).fill(denom)));
      var result = dfs(remaining - count * denom, denomIndex + 1, newCombination);
      if (result) {
        return result;
      }
    }
    return null;
  }
  var exactMatch = dfs(target, 0, []);
  if (exactMatch && exactMatch.length > 0) {
    var denomTypes = new Set(exactMatch).size;
    return {
      combination: exactMatch.map(function (d) {
        return d / precision;
      }),
      sum: target / precision,
      coinCount: exactMatch.length,
      denomTypes: denomTypes
    };
  }
  return null;
}

/**
 * 移除重复和扩展组合
 * 核心原理：如果组合A包含组合B的所有硬币，并且还有额外硬币，则A是B的扩展，应该被移除
 */
function removeDuplicateAndExtendedCombinations(combinations, targetAmount) {
  var result = [];

  // 按币种类型数量、硬币数量、金额排序，确保较简单的组合在前面
  combinations.sort(function (a, b) {
    if (a.denomTypes !== b.denomTypes) {
      return a.denomTypes - b.denomTypes;
    }
    if (a.coinCount !== b.coinCount) {
      return a.coinCount - b.coinCount;
    }
    return a.sum - b.sum;
  });
  for (var i = 0; i < combinations.length; i++) {
    var current = combinations[i];
    var shouldSkip = false;

    // 检查当前组合是否与已添加的组合重复或者是扩展
    for (var j = 0; j < result.length; j++) {
      var existing = result[j];

      // 如果完全相同，跳过
      if (isSameCombination(current.combination, existing.combination)) {
        shouldSkip = true;
        break;
      }

      // 如果当前组合是已存在组合的扩展，跳过
      if (isExtensionOf(current.combination, existing.combination)) {
        shouldSkip = true;
        break;
      }
    }

    // 检查是否有其他组合是当前组合的扩展，如果有，移除那些扩展
    if (!shouldSkip) {
      // 移除所有当前组合的扩展
      for (var _j3 = result.length - 1; _j3 >= 0; _j3--) {
        if (isExtensionOf(result[_j3].combination, current.combination)) {
          result.splice(_j3, 1);
        }
      }
      result.push(current);
    }
  }
  return result;
}

/**
 * 检查组合A是否是组合B的扩展（即A包含B的所有硬币，并且还有额外的硬币）
 */
function isExtensionOf(combinationA, combinationB) {
  // 如果A的硬币数量少于等于B，A不可能是B的扩展
  if (combinationA.length <= combinationB.length) {
    return false;
  }

  // 统计每个面额的数量
  var countA = {};
  var countB = {};
  combinationA.forEach(function (coin) {
    countA[coin] = (countA[coin] || 0) + 1;
  });
  combinationB.forEach(function (coin) {
    countB[coin] = (countB[coin] || 0) + 1;
  });

  // 检查B的所有面额在A中是否都有足够的数量
  for (var coin in countB) {
    if (!countA[coin] || countA[coin] < countB[coin]) {
      return false;
    }
  }

  // 检查A是否有B没有的额外硬币
  var hasExtra = false;
  for (var _coin in countA) {
    if (countA[_coin] > (countB[_coin] || 0)) {
      hasExtra = true;
      break;
    }
  }
  return hasExtra;
}

/**
 * 检查两个组合是否本质相同（相同的面额组合）
 */
function isSameCombination(combinationA, combinationB) {
  if (combinationA.length !== combinationB.length) {
    return false;
  }
  var countA = {};
  var countB = {};
  combinationA.forEach(function (coin) {
    countA[coin] = (countA[coin] || 0) + 1;
  });
  combinationB.forEach(function (coin) {
    countB[coin] = (countB[coin] || 0) + 1;
  });

  // 检查两个组合是否有相同的面额和数量
  for (var coin in countA) {
    if (countA[coin] !== (countB[coin] || 0)) {
      return false;
    }
  }
  for (var _coin2 in countB) {
    if (countB[_coin2] !== (countA[_coin2] || 0)) {
      return false;
    }
  }
  return true;
}