import formValueSelector from 'redux-form/lib/formValueSelector';
import { createSelector } from 'reselect';
import FormNames from '../data/enum/FormNames';
import { shopFields } from '../data/enum/FieldNames/AccountFieldNames';
import { makeCollectionSelector } from './collectionSelector';
import { packageCollectionId } from '../data/collectionIds';
import { DISCOUNT_ITEM, VOUCHER } from '../data/entityTypes';
const EMPTY_OBJECT = {};
export const DEFAULT_LIMIT = 20;
/**
* Select all of the packages available for the user
* @returns {{}} Returns a array of packages
*/
export const packagesSelector = state => state.entities.subscriptionPackage;
/**
* Selects the voucher based on the given VoucherCode
* @returns {{}} Returns a voucher
*/
export const voucherSelector = (state, voucherCode) =>
voucherCode ? state.entities[VOUCHER]?.[voucherCode.toLowerCase()] : EMPTY_OBJECT;
export const discountItemSelector = (state, voucherCode) =>
voucherCode && state?.entities?.[DISCOUNT_ITEM]?.[voucherCode];
/**
* Uses SubscriptionPackages and voucher entities. Looks-up the voucher and checks if the package
* is eligible for a discount. Merges the package entity with the discount/voucher.
* @returns {*[]} An array with packages
*/
export const makePackagesWithDiscountSelector = (formName = FormNames.CHECKOUT) => {
const collectionSelector = makeCollectionSelector();
const valueSelector = formValueSelector(formName);
return createSelector(
// Get package for current region
(state, regionCode) =>
collectionSelector(state, {
collectionId: packageCollectionId({
limit: DEFAULT_LIMIT,
regionCode,
}),
}),
// Get voucher code
state => voucherSelector(state, valueSelector(state, shopFields.VOUCHER_CODE)),
// Merge values
({ entities: packages }, voucher) => {
const { discounts } = voucher;
// We can return the packages if there aren't any discounts
if (!discounts) {
return packages;
}
// Returns subscriptionPackages with applied discount (if applicable)
return packages.reduce((accumulator, packageData) => {
// Find a discount for current packageId
const discount = discounts.find(({ productIds }) =>
productIds?.some(productId => productId === packageData.subscriptionProductId),
);
accumulator.push({
...packageData,
discount,
});
return accumulator;
}, []);
},
);
};
/**
* Return the selected package.
* @returns {*}
*/
export const makeSelectedPackageSelector = (formName = FormNames.CHECKOUT) => {
const packagesWithDiscountSelector = makePackagesWithDiscountSelector(formName);
const valueSelector = formValueSelector(formName);
if (formName === FormNames.TRANSFER_TO_ONLINE_PACKAGE) {
return createSelector(
// Get all packages
state => packagesSelector(state),
// Get selected package
state => valueSelector(state, shopFields.PACKAGE),
// Find the package information
(packages, packageId) => packages && packages[packageId],
);
}
return createSelector(
// Get packages with discounts applied to it
packagesWithDiscountSelector,
// Get selected package
state => valueSelector(state, shopFields.PACKAGE),
// Find the package
(packages, packageId) => packages.find(a => a.id === packageId),
);
};
/**
* Return the next possible package to upgrade.
* @returns {*}
*/
export const makeOffsetPackageSelector = (formName = FormNames.CHECKOUT, offset) => {
const packagesWithDiscountSelector = makePackagesWithDiscountSelector(formName);
const valueSelector = formValueSelector(formName);
return createSelector(
// Get packages with discounts applied to it
packagesWithDiscountSelector,
// Get selected package
state => valueSelector(state, shopFields.PACKAGE),
// Find the package
(packages, packageId) => packages[packages.findIndex(a => a.id === packageId) + offset],
);
};