var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/modules/Payment/cashRecommendationAlgorithm.ts
var cashRecommendationAlgorithm_exports = {};
__export(cashRecommendationAlgorithm_exports, {
  CURRENCY_DENOMINATIONS: () => CURRENCY_DENOMINATIONS,
  recommendOptimalPayments: () => recommendOptimalPayments
});
module.exports = __toCommonJS(cashRecommendationAlgorithm_exports);
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": [1e4, 5e3, 2e3, 1e3, 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": [1e3, 500, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1],
  // 新台币
  "TWD": [2e3, 1e3, 500, 200, 100, 50, 10, 5, 1],
  // 韩元
  "KRW": [5e4, 1e4, 5e3, 1e3, 500, 100, 50, 10, 5, 1],
  // 新加坡元
  "SGD": [1e4, 1e3, 100, 50, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.01],
  // 瑞士法郎
  "CHF": [1e3, 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]
};
function recommendOptimalPayments(targetAmount, denominations) {
  if (targetAmount <= 0 || !isFinite(targetAmount) || isNaN(targetAmount)) {
    return [];
  }
  if (!denominations || !Array.isArray(denominations) || denominations.length === 0) {
    return [Math.ceil(targetAmount)];
  }
  const maxReasonableDenom = targetAmount * 5;
  const validDenoms = denominations.filter((denom) => denom > 0 && isFinite(denom) && !isNaN(denom) && denom <= maxReasonableDenom).slice(0, 8);
  if (validDenoms.length === 0) {
    return [Math.ceil(targetAmount)];
  }
  try {
    const precision = 100;
    const target = Math.round(targetAmount * precision);
    const denoms = validDenoms.map((d) => Math.round(d * precision)).sort((a, b) => b - a);
    const paymentOptions = [];
    const exactCombination = findExactCombination(target, denoms, precision);
    if (exactCombination) {
      paymentOptions.push(exactCombination);
    }
    for (let i = 0; i < Math.min(denoms.length, 6); i++) {
      const denom = denoms[i];
      const count = Math.ceil(target / denom);
      const sum = count * denom;
      if (sum >= target && count <= 12) {
        paymentOptions.push({
          combination: Array(count).fill(denom / precision),
          sum: sum / precision,
          coinCount: count,
          denomTypes: 1
        });
      }
    }
    for (let i = 0; i < Math.min(denoms.length - 1, 5); i++) {
      for (let j = i + 1; j < Math.min(denoms.length, 6); j++) {
        const denom1 = denoms[i];
        const denom2 = denoms[j];
        const maxCount1 = Math.min(Math.ceil(target / denom1) + 1, 8);
        const maxCount2 = Math.min(Math.ceil(target / denom2) + 1, 10);
        for (let count1 = 1; count1 <= maxCount1; count1++) {
          for (let count2 = 1; count2 <= maxCount2; count2++) {
            const sum = count1 * denom1 + count2 * denom2;
            if (sum >= target) {
              const combination = [
                ...Array(count1).fill(denom1 / precision),
                ...Array(count2).fill(denom2 / precision)
              ];
              paymentOptions.push({
                combination,
                sum: sum / precision,
                coinCount: count1 + count2,
                denomTypes: 2
              });
            }
          }
        }
      }
    }
    for (let i = 0; i < Math.min(denoms.length - 2, 3); i++) {
      for (let j = i + 1; j < Math.min(denoms.length - 1, 4); j++) {
        for (let k = j + 1; k < Math.min(denoms.length, 5); k++) {
          const denom1 = denoms[i];
          const denom2 = denoms[j];
          const denom3 = denoms[k];
          const maxCount1 = Math.min(Math.ceil(target / denom1) + 1, 5);
          const maxCount2 = Math.min(Math.ceil(target / denom2) + 1, 6);
          const maxCount3 = Math.min(Math.ceil(target / denom3) + 1, 8);
          for (let count1 = 1; count1 <= maxCount1; count1++) {
            for (let count2 = 1; count2 <= maxCount2; count2++) {
              for (let count3 = 1; count3 <= maxCount3; count3++) {
                const sum = count1 * denom1 + count2 * denom2 + count3 * denom3;
                if (sum >= target) {
                  const combination = [
                    ...Array(count1).fill(denom1 / precision),
                    ...Array(count2).fill(denom2 / precision),
                    ...Array(count3).fill(denom3 / precision)
                  ];
                  paymentOptions.push({
                    combination,
                    sum: sum / precision,
                    coinCount: count1 + count2 + count3,
                    denomTypes: 3
                  });
                }
              }
            }
          }
        }
      }
    }
    for (let i = 0; i < Math.min(denoms.length - 3, 2); i++) {
      for (let j = i + 1; j < Math.min(denoms.length - 2, 3); j++) {
        for (let k = j + 1; k < Math.min(denoms.length - 1, 4); k++) {
          for (let l = k + 1; l < Math.min(denoms.length, 5); l++) {
            const denom1 = denoms[i];
            const denom2 = denoms[j];
            const denom3 = denoms[k];
            const denom4 = denoms[l];
            const maxCount1 = Math.min(Math.ceil(target / denom1) + 1, 3);
            const maxCount2 = Math.min(Math.ceil(target / denom2) + 1, 4);
            const maxCount3 = Math.min(Math.ceil(target / denom3) + 1, 5);
            const maxCount4 = Math.min(Math.ceil(target / denom4) + 1, 6);
            for (let count1 = 1; count1 <= maxCount1; count1++) {
              for (let count2 = 1; count2 <= maxCount2; count2++) {
                for (let count3 = 1; count3 <= maxCount3; count3++) {
                  for (let count4 = 1; count4 <= maxCount4; count4++) {
                    const sum = count1 * denom1 + count2 * denom2 + count3 * denom3 + count4 * denom4;
                    if (sum >= target) {
                      const combination = [
                        ...Array(count1).fill(denom1 / precision),
                        ...Array(count2).fill(denom2 / precision),
                        ...Array(count3).fill(denom3 / precision),
                        ...Array(count4).fill(denom4 / precision)
                      ];
                      paymentOptions.push({
                        combination,
                        sum: sum / precision,
                        coinCount: count1 + count2 + count3 + count4,
                        denomTypes: 4
                      });
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    if (paymentOptions.length === 0) {
      const minValidDenom = validDenoms.find((denom) => denom >= targetAmount);
      if (minValidDenom) {
        return [minValidDenom];
      } else {
        const maxDenom = Math.max(...validDenoms);
        const count = Math.ceil(targetAmount / maxDenom);
        return [count * maxDenom];
      }
    }
    const uniqueCombinations = removeDuplicateAndExtendedCombinations(paymentOptions, targetAmount);
    uniqueCombinations.sort((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;
    });
    const uniqueAmounts = /* @__PURE__ */ new Set();
    const finalResults = [];
    for (const item of uniqueCombinations) {
      const roundedAmount = Math.round(item.sum * 100) / 100;
      if (!uniqueAmounts.has(roundedAmount) && finalResults.length < 10) {
        uniqueAmounts.add(roundedAmount);
        finalResults.push(roundedAmount);
      }
    }
    return finalResults.sort((a, b) => a - b);
  } catch (error) {
    console.warn("推荐支付金额计算出错:", error);
    const 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;
    }
    const denom = denoms[denomIndex];
    const maxCount = Math.min(Math.floor(remaining / denom), 8);
    for (let count = maxCount; count >= 0; count--) {
      const newCombination = [...currentCombination, ...Array(count).fill(denom)];
      const result = dfs(remaining - count * denom, denomIndex + 1, newCombination);
      if (result) {
        return result;
      }
    }
    return null;
  }
  const exactMatch = dfs(target, 0, []);
  if (exactMatch && exactMatch.length > 0) {
    const denomTypes = new Set(exactMatch).size;
    return {
      combination: exactMatch.map((d) => d / precision),
      sum: target / precision,
      coinCount: exactMatch.length,
      denomTypes
    };
  }
  return null;
}
function removeDuplicateAndExtendedCombinations(combinations, targetAmount) {
  const result = [];
  combinations.sort((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 (let i = 0; i < combinations.length; i++) {
    const current = combinations[i];
    let shouldSkip = false;
    for (let j = 0; j < result.length; j++) {
      const existing = result[j];
      if (isSameCombination(current.combination, existing.combination)) {
        shouldSkip = true;
        break;
      }
      if (isExtensionOf(current.combination, existing.combination)) {
        shouldSkip = true;
        break;
      }
    }
    if (!shouldSkip) {
      for (let j = result.length - 1; j >= 0; j--) {
        if (isExtensionOf(result[j].combination, current.combination)) {
          result.splice(j, 1);
        }
      }
      result.push(current);
    }
  }
  return result;
}
function isExtensionOf(combinationA, combinationB) {
  if (combinationA.length <= combinationB.length) {
    return false;
  }
  const countA = {};
  const countB = {};
  combinationA.forEach((coin) => {
    countA[coin] = (countA[coin] || 0) + 1;
  });
  combinationB.forEach((coin) => {
    countB[coin] = (countB[coin] || 0) + 1;
  });
  for (const coin in countB) {
    if (!countA[coin] || countA[coin] < countB[coin]) {
      return false;
    }
  }
  let hasExtra = false;
  for (const 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;
  }
  const countA = {};
  const countB = {};
  combinationA.forEach((coin) => {
    countA[coin] = (countA[coin] || 0) + 1;
  });
  combinationB.forEach((coin) => {
    countB[coin] = (countB[coin] || 0) + 1;
  });
  for (const coin in countA) {
    if (countA[coin] !== (countB[coin] || 0)) {
      return false;
    }
  }
  for (const coin in countB) {
    if (countB[coin] !== (countA[coin] || 0)) {
      return false;
    }
  }
  return true;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  CURRENCY_DENOMINATIONS,
  recommendOptimalPayments
});
