import { IGXE, PriceHelper } from "@intelligentgraphics/igd.core";
const defaultPriceFormatter = ({ currency, rangeMin, rangeMax, value, locale, }) => {
    let price;
    if (rangeMin !== undefined && rangeMax !== undefined) {
        price = {
            min: rangeMin,
            max: rangeMax,
        };
    }
    else if (value !== undefined) {
        price = value;
    }
    else {
        throw new Error(`Detected invalid price without any value`);
    }
    return PriceHelper.getLocalizedDecimal(price, locale, true, 2, currency);
};
export const createBasket = (session, { priceFormatter = defaultPriceFormatter } = {}) => {
    const positionStrings = new Map();
    const update = () => {
        buildPositionStrings(session.getFilteredArticles(article => article.parent === undefined), []);
    };
    const buildPositionStrings = (articles, parentParts) => {
        let skipped = 0;
        for (let index = 0; index < articles.length; index++) {
            const article = articles[index];
            if (article.data.hidden) {
                skipped++;
                continue;
            }
            const articleIndex = index - skipped;
            const articleParts = [...parentParts, articleIndex + 1];
            positionStrings.set(article.comId, articleParts.join("."));
            const children = session.getArticlesByComIds(article.children);
            buildPositionStrings(children, articleParts);
        }
    };
    const getPositionString = (comId) => positionStrings.get(comId);
    const getBomTotals = () => {
        const articles = session.getAllArticles();
        let min = 0;
        let max = 0;
        let currency;
        for (const item of articles) {
            const singlePrice = getSinglePrice(item.comId);
            if (singlePrice === undefined) {
                continue;
            }
            if (singlePrice.Value !== undefined) {
                min += singlePrice.Value;
                max += singlePrice.Value;
            }
            else if (singlePrice.RangeMin !== undefined &&
                singlePrice.RangeMax !== undefined) {
                min += singlePrice.RangeMin;
                max += singlePrice.RangeMax;
            }
            currency = singlePrice.Currency;
        }
        const value = {
            rangeMin: min === max ? undefined : min,
            rangeMax: min === max ? undefined : max,
            value: min === max ? min : undefined,
            currency: currency,
            locale: session.getLanguage(),
        };
        return [
            {
                caption: "@subtotal",
                rangeMin: min === max ? undefined : min,
                rangeMax: min === max ? undefined : max,
                value: min === max ? min : undefined,
                currency,
                type: "subtotal",
                text: priceFormatter(value) || "",
            },
            {
                caption: "@total",
                rangeMin: min === max ? undefined : min,
                rangeMax: min === max ? undefined : max,
                value: min === max ? min : undefined,
                currency,
                type: "total",
                text: priceFormatter(value) || "",
            },
        ];
    };
    const getSinglePrice = (comId) => {
        const { prices } = session.getArticleInfo(comId);
        const singlePrice = prices.find(price => price.Level === IGXE.EPriceLevel.Base);
        return singlePrice;
    };
    const getSinglePriceText = (comId) => {
        const singlePrice = getSinglePrice(comId);
        if (singlePrice === undefined) {
            return undefined;
        }
        const article = session.getArticleByComId(comId);
        if (article === undefined) {
            throw new Error(`Can not find article for comId "${comId}"`);
        }
        return priceFormatter({
            value: singlePrice.Value,
            rangeMax: singlePrice.RangeMax,
            rangeMin: singlePrice.RangeMin,
            currency: singlePrice.Currency,
            locale: session.getLanguage(),
        });
    };
    const subscription = session.subscribe({
        ItemCreated: update,
        ItemRemoved: update,
    });
    const destroy = () => subscription.destroy();
    update();
    return {
        destroy,
        getPositionString,
        getBomTotals,
        getSinglePrice,
        getSinglePriceText,
    };
};
