import { W as WISE_ALIAS } from './provider-constants-b35398f2.js';
import { i as isWiseAlias } from './aliasFilter-a7b9c811.js';
import { e as extractQuote } from './extractQuote-aa1e3309.js';

/**
 * Returns {@code true} if there is no double value strictly between the
 * arguments or the relative difference between them is less than or equal
 * to the given tolerance. Returns {@code false} if either of the arguments
 * is NaN.
 *
 * @param x First value.
 * @param y Second value.
 * @param epsilon Amount of allowed relative error.
 * @return {@code true} if the values are two adjacent floating point
 * numbers or they are within range of each other.
 */
const numberEqualsWithRelativeTolerance = (x, y, epsilon) => {
    if (x === y) {
        return true;
    }
    const absoluteMax = Math.max(Math.abs(x), Math.abs(y));
    const relativeDifference = Math.abs((x - y) / absoluteMax);
    return relativeDifference <= epsilon;
};

var FeeType;
(function (FeeType) {
    FeeType["HIDDEN"] = "HIDDEN";
    FeeType["MARKETED"] = "MARKETED";
})(FeeType || (FeeType = {}));
function sortWiseFirstThenByProviderAlias(firstQuote, secondQuote) {
    if (isWiseQuote(firstQuote)) {
        return -1;
    }
    if (isWiseQuote(secondQuote)) {
        return 1;
    }
    return firstQuote.provider.alias.localeCompare(secondQuote.provider.alias);
}
function isWiseQuote(quote) {
    return quote && quote.provider.alias === WISE_ALIAS;
}
function sortTransferFeeComparisonQuoteByReceiveAmount(quotes) {
    // the use of slice() here is to provide a shallow copy of quotes, otherwise the original array is modified, which could lead to unexpected behaviour
    return quotes.slice().sort((q1, q2) => {
        if (q2.receiveAmount.value === q1.receiveAmount.value) {
            return sortWiseFirstThenByProviderAlias(q1, q2);
        }
        return q2.receiveAmount.value - q1.receiveAmount.value;
    });
}
function transformV2ToComparisonQuote(quote) {
    return {
        alias: quote.provider.alias,
        name: quote.provider.name,
        logo: quote.provider.logoUrl,
        partner: quote.provider.partner,
        fees: quote.fees.total.value,
        rate: quote.rate,
        receivedAmount: quote.receiveAmount.value,
    };
}

// From ISO 4217 (06/12/2021)
const CURRENCIES_WITHOUT_DECIMALS = new Set([
    'CVE',
    'IDR',
    'ISK',
    'BIF',
    'CLP',
    'DJF',
    'GNF',
    'ISK',
    'JPY',
    'KMF',
    'KRW',
    'PYG',
    'RWF',
    'UGX',
    'UYI',
    'VND',
    'VUV',
    'XAF',
    'XOF',
    'XPF',
]);
const isCurrencyWithoutDecimals = (currencyCode) => CURRENCIES_WITHOUT_DECIMALS.has(currencyCode);

const findPaymentOption = (quote) => {
    const selectedPaymentOption = quote.paymentOptions
        .filter((paymentOption) => !paymentOption.disabled)
        .find((paymentOption) => paymentOption.payIn === 'BANK_TRANSFER');
    if (selectedPaymentOption) {
        return selectedPaymentOption;
    }
    return quote.paymentOptions[0];
};
function extractWiseQuote(quote) {
    const paymentOption = findPaymentOption(quote);
    return {
        fee: paymentOption.fee.total + paymentOption.fee.discount,
        rate: quote.rate,
        receivedAmount: paymentOption.targetAmount,
        dateCollected: new Date(),
    };
}

function extractHiddenFeeInSourceCurrency(targetCurrencyCode, sendAmount, receivedAmount, marketedFee, midmarketRate) {
    const noDecimalsCurrencyTolerance = isCurrencyWithoutDecimals(targetCurrencyCode) ? 0.5 : 0;
    const toleranceAmountInPercentage = 0.00001;
    const expectedReceivedAmount = floorToTwoDecimalNumbers(midmarketRate * (sendAmount - marketedFee) - noDecimalsCurrencyTolerance);
    const receivedTheExpectedAmount = numberEqualsWithRelativeTolerance(receivedAmount, expectedReceivedAmount, toleranceAmountInPercentage);
    const receivedHigherThanExpected = receivedAmount > expectedReceivedAmount;
    const hasHiddenFee = !receivedTheExpectedAmount && !receivedHigherThanExpected;
    const hiddenFeePaidOnTargetCurrency = hasHiddenFee ? expectedReceivedAmount - receivedAmount : 0;
    return parseFloat((hiddenFeePaidOnTargetCurrency / midmarketRate).toFixed(2));
}
function extractFees(marketedFee, hiddenFee, sourceCurrency) {
    const fees = [];
    if (marketedFee > 0) {
        fees.push({
            type: FeeType.MARKETED,
            amount: { value: marketedFee, currency: sourceCurrency },
        });
    }
    if (hiddenFee > 0) {
        fees.push({
            type: FeeType.HIDDEN,
            amount: { value: hiddenFee, currency: sourceCurrency },
        });
    }
    return fees;
}
function transformQuotesResponseV2(quotesResults, quoteApi) {
    var _a;
    const wiseQuote = (_a = quotesResults.providers.find((provider) => isWiseAlias(provider.alias))) === null || _a === void 0 ? void 0 : _a.quotes[0].rate;
    const quotes = quotesResults.providers.map((p) => {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
        const quote = quoteApi && isWiseAlias(p.alias)
            ? extractWiseQuote(quoteApi)
            : extractQuote(p.quotes, quotesResults.targetCurrency);
        // eslint-disable-next-line fp/no-mutation
        const midMarketRate = quoteApi ? quoteApi.rate : wiseQuote;
        return buildQuoteObject(quotesResults, p, quote, midMarketRate);
    });
    return {
        quotes,
    };
}
function buildQuoteObject(quotesResults, provider, quote, midMarketRate) {
    const hiddenFee = extractHiddenFeeInSourceCurrency(quotesResults.targetCurrency, quotesResults.sendAmount, quote.receivedAmount, quote.fee, midMarketRate);
    const feesBreakdown = extractFees(quote.fee, hiddenFee, quotesResults.sourceCurrency);
    return {
        provider: {
            alias: provider.alias,
            name: provider.name,
            logoUrl: provider.logos.normal.svgUrl,
            logoAltText: provider.logos.altText,
            partner: provider.partner,
        },
        route: {
            sourceCurrency: quotesResults.sourceCurrency,
            targetCurrency: quotesResults.targetCurrency,
        },
        rate: quote.rate,
        fees: {
            breakdown: feesBreakdown,
            total: { value: quote.fee + hiddenFee, currency: quotesResults.sourceCurrency },
        },
        receiveAmount: { value: quote.receivedAmount, currency: quotesResults.targetCurrency },
        sendAmount: { value: quotesResults.sendAmount, currency: quotesResults.sourceCurrency },
        deliveryEstimation: quote.deliveryEstimation,
    };
}
function floorToTwoDecimalNumbers(value) {
    return Math.floor(value * 100) / 100;
}

export { FeeType as F, transformV2ToComparisonQuote as a, isWiseQuote as i, numberEqualsWithRelativeTolerance as n, sortTransferFeeComparisonQuoteByReceiveAmount as s, transformQuotesResponseV2 as t };
//# sourceMappingURL=transformQuotesResponseV2-6eb16ebc.js.map
