import { __read, __values } from "tslib";
import * as React from "react";
import { IGXE } from "@intelligentgraphics/igd.core";
import { createBasket, } from "@intelligentgraphics/igd.productdata";
import { useSessionContext } from "../SessionContext";
import { convert, getDefaultUnitString, getGroupOfUnit } from "../Units";
import { EBomComponentEntryType, } from "./Types";
var buildState = function (session, basket, _a) {
    var _b = _a.flatten, flatten = _b === void 0 ? false : _b, _c = _a.useVarText, useVarText = _c === void 0 ? false : _c, units = _a.units;
    var response = [];
    var buildLevel = function (articles, parentUID) {
        var e_1, _a;
        var levelItems = [];
        try {
            for (var articles_1 = __values(articles), articles_1_1 = articles_1.next(); !articles_1_1.done; articles_1_1 = articles_1.next()) {
                var item = articles_1_1.value;
                if (item.data.hidden) {
                    continue;
                }
                // if (item.ItemType === IGXB.EItemType.Group) {
                // 	if (item.Items.every(subItem => subItem.Hidden === true)) {
                // 		continue;
                // 	}
                // 	const groupEntry: IBomComponentGroupEntry = {
                // 		Caption: item.Caption || [],
                // 		ItemType: EBomComponentEntryType.Group,
                // 		UID: item.UID,
                // 		Items: []
                // 	};
                // 	if (flatten) {
                // 		response.push(groupEntry);
                // 	}
                // 	if (item.Items) {
                // 		const result = buildLevel(item.Items, item.UID);
                // 		if (result.length === 0) {
                // 			continue;
                // 		}
                // 		if (!flatten) {
                // 			groupEntry.Items = result;
                // 		}
                // 	}
                // 	levelItems.push(groupEntry);
                // 	continue;
                // }
                if (item.type === "set") {
                    var setEntry = {
                        Caption: item.info.shortText || [],
                        ItemType: EBomComponentEntryType.Set,
                        UID: item.comId,
                        Items: [],
                        SetId: item.articleId,
                        InstanceId: item.comId,
                        Position: basket.getPositionString(item.comId),
                        Price: basket.getSinglePriceText(item.comId) || "",
                        ShortText: item.info.shortText,
                        LongText: item.info.longText,
                        VarText: getVarText(item.info.varText),
                        Name: item.info.name,
                    };
                    if (flatten) {
                        response.push(setEntry);
                    }
                    if (item.children) {
                        var result = buildLevel(session.getArticlesByComIds(item.children), item.comId);
                        if (!flatten) {
                            setEntry.Items = result;
                        }
                    }
                    levelItems.push(setEntry);
                }
                if (item.type === "commercial" || item.type === "graphical") {
                    var properties = getArticleProperties(session, item.comId, useVarText, units);
                    var articleEntry = {
                        UID: item.comId,
                        ItemType: EBomComponentEntryType.Article,
                        Position: basket.getPositionString(item.comId),
                        ArticleId: item.articleId,
                        Image: item.info.image,
                        InstanceId: item.comId,
                        ShortText: item.info.shortText,
                        LongText: item.info.longText,
                        VarText: getVarText(item.info.varText),
                        Quantity: "1",
                        SinglePrice: basket.getSinglePriceText(item.comId) || "",
                        TotalPrice: basket.getSinglePriceText(item.comId) || "",
                        Properties: properties,
                        Name: item.info.name,
                    };
                    if (flatten) {
                        response.push(articleEntry);
                    }
                    if (item.children) {
                        var result = buildLevel(session.getArticlesByComIds(item.children), item.comId);
                        if (!flatten) {
                            articleEntry.SubItems = result;
                        }
                    }
                    levelItems.push(articleEntry);
                    continue;
                }
                // if (item.ItemType === IGXB.EItemType.Text) {
                // 	if (!Array.isArray(item.Text)) {
                // 		item.Text = [item.Text];
                // 	}
                // 	const textEntry: IBomComponentTextEntry = {
                // 		Text: item.Text,
                // 		UID: item.UID,
                // 		ItemType: EBomComponentEntryType.Text
                // 	};
                // 	if (flatten) {
                // 		response.push(textEntry);
                // 	}
                // 	levelItems.push(textEntry);
                // }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (articles_1_1 && !articles_1_1.done && (_a = articles_1.return)) _a.call(articles_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return levelItems;
    };
    var deepResult = buildLevel(session.getFilteredArticles(function (article) { return article.parent === undefined; }), undefined);
    var items = flatten ? response : deepResult;
    var totals = basket.getBomTotals();
    var totalEntry = totals.find(function (entry) { return entry.type === "total"; });
    if (!totalEntry) {
        throw new Error("Total calculation requires one entry with a type of \"total\" to be returned by the basket.");
    }
    return {
        items: items,
        total: totalEntry.text,
    };
};
var getVarText = function (textEntries) {
    if (!textEntries) {
        return [];
    }
    return textEntries.map(function (_a) {
        var key = _a.key, value = _a.value;
        return key + ": " + value;
    });
};
var getArticleProperties = function (session, comId, useVarText, units) {
    var article = session.getArticleByComId(comId);
    if (article === undefined) {
        throw new Error("Can not read properties and configuration of unknown article: " + comId);
    }
    if (useVarText) {
        return article.info.varText.map(function (entry) { return ({
            property: entry.key,
            value: entry.value,
        }); });
    }
    var properties = article.properties, configuration = article.configuration;
    var visibleConfiguredProperties = properties.filter(function (prop) { return prop.Visible && configuration[prop.Key]; });
    return IGXE.createActiveSubPropertyInjectedPropertyList(visibleConfiguredProperties).map(function (prop) {
        var text = "";
        if (prop.ValueType === IGXE.EPropertyType.Int ||
            prop.ValueType === IGXE.EPropertyType.Float) {
            var tUnitGroup = getGroupOfUnit(prop.ValueUnit);
            text = prop.Value ? prop.Value.toString() : "";
            if (units) {
                var newUnit = units[tUnitGroup];
                text =
                    convert(prop.Value, prop.ValueUnit, newUnit).toString() +
                        " " +
                        getDefaultUnitString(newUnit);
            }
        }
        else if (prop.Value !== undefined) {
            var valueDefinition = IGXE.findValueDefinition(prop, prop.Value);
            if (valueDefinition !== undefined && valueDefinition.Text) {
                text = valueDefinition.Text.join(" ");
            }
        }
        var propText = prop.Text.join(" ");
        propText =
            propText.indexOf(":") === -1 ? propText : propText.slice(0, -1);
        return {
            property: propText,
            value: text,
        };
    });
};
var BasketComponent = function (props) {
    var _a = useSessionContext(), session = _a.session, basket = _a.basket;
    var providedBasket = props.basket || basket;
    //TODO: update on settings change
    var settingsRef = React.useRef(undefined);
    settingsRef.current = {
        flatten: props.flatten,
        locale: props.locale || session.getLanguage(),
        units: props.units,
        useVarText: props.useVarText,
    };
    var _b = __read(React.useState({
        items: [],
        total: "",
    }), 2), state = _b[0], setState = _b[1];
    React.useEffect(function () {
        var batchTimer;
        var basket = providedBasket !== undefined
            ? providedBasket
            : createBasket(session);
        var update = function () {
            if (batchTimer !== undefined) {
                return;
            }
            batchTimer = setTimeout(function () {
                setState(buildState(session, basket, settingsRef.current));
                batchTimer = undefined;
            });
        };
        var subscription = session.subscribe({
            ItemCreated: update,
            ItemConfigured: update,
            ItemRemoved: update,
        });
        update();
        return function () {
            if (providedBasket === undefined) {
                basket.destroy();
            }
            subscription.destroy();
            clearTimeout(batchTimer);
        };
    }, [session, providedBasket]);
    return props.children(state);
};
BasketComponent.displayName = "BasketComponent";
export default BasketComponent;
