"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var ig_utilities_1 = require("@intelligentgraphics/ig.utilities");
var igd_core_1 = require("@intelligentgraphics/igd.core");
exports.createIGXB = function (articleQuery, _a) {
    var e_1, _b;
    var _c = _a === void 0 ? {} : _a, _d = _c.autoGrouping, autoGrouping = _d === void 0 ? true : _d, _e = _c.priceType, priceType = _e === void 0 ? igd_core_1.IGXB.EPriceType.Gross : _e, _f = _c.vat, vat = _f === void 0 ? 0 : _f, _g = _c.projectData, projectData = _g === void 0 ? {
        Id: ig_utilities_1.generateId(),
        Title: "A new Project",
        Creation: new Date().toUTCString(),
    } : _g, _h = _c.customData, customData = _h === void 0 ? {} : _h, basket = _c.basket;
    var result = {
        FormatVersion: igd_core_1.IGXB.CurrentMajorVersion + "." + igd_core_1.IGXB.CurrentMinorVersion,
        VAT: vat,
        PriceType: priceType,
        CustomData: customData,
        ProjectData: projectData,
        Items: [],
    };
    var roots = articleQuery.getFilteredArticles(function (article) { return article.parent === undefined; });
    try {
        for (var roots_1 = tslib_1.__values(roots), roots_1_1 = roots_1.next(); !roots_1_1.done; roots_1_1 = roots_1.next()) {
            var article = roots_1_1.value;
            var parentItems = void 0;
            if (!autoGrouping) {
                parentItems = result.Items;
            }
            else {
                parentItems = findOrCreateSourceGroup(article, result.Items);
            }
            buildItemTree(articleQuery, article, parentItems, basket);
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (roots_1_1 && !roots_1_1.done && (_b = roots_1.return)) _b.call(roots_1);
        }
        finally { if (e_1) throw e_1.error; }
    }
    return result;
};
var findOrCreateSourceGroup = function (article, existingRootItems) {
    var parent = existingRootItems.find(function (item) {
        return item.ItemType === igd_core_1.IGXB.EItemType.Group &&
            item.Identifier === article.source;
    });
    if (parent !== undefined) {
        return parent.Items;
    }
    var _a = article.info, manufacturerName = _a.manufacturerName, programName = _a.programName;
    var newParent = {
        ItemType: igd_core_1.IGXB.EItemType.Group,
        Items: [],
        UID: ig_utilities_1.generateId(),
        Caption: manufacturerName + " " + programName,
        Identifier: article.source,
    };
    existingRootItems.push(newParent);
    return newParent.Items;
};
var buildItemTree = function (articleQuery, article, parentItems, basket) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var item, children, childArray_1;
    return tslib_1.__generator(this, function (_a) {
        switch (_a.label) {
            case 0:
                item = createIGXBItem(article, basket);
                parentItems.push(item);
                if (!(article.children.length > 0)) return [3 /*break*/, 2];
                children = article.children.map(function (comId) { return articleQuery.getArticleByComId(comId); });
                if (item.ItemType === igd_core_1.IGXB.EItemType.Group ||
                    item.ItemType === igd_core_1.IGXB.EItemType.Set) {
                    childArray_1 = item.Items;
                }
                else if (item.ItemType === igd_core_1.IGXB.EItemType.Article) {
                    childArray_1 = item.SubItems;
                }
                if (childArray_1 === undefined) {
                    throw new Error("Article \"" + article.comId + "\" has children, but they can not be reflected in the igxb since the igxb representation of the article doesn't allow children");
                }
                return [4 /*yield*/, Promise.all(children.map(function (article) {
                        return buildItemTree(articleQuery, article, childArray_1, basket);
                    }))];
            case 1:
                _a.sent();
                _a.label = 2;
            case 2: return [2 /*return*/];
        }
    });
}); };
var createCommercialArticle = function (article, priceFormatter) {
    var normalArticle = createArticle(article, priceFormatter);
    normalArticle.Data.dontRestore = true;
    normalArticle.IsCommercial = true;
    return normalArticle;
};
var createArticle = function (article, priceFormatter) {
    var _a = article.info, manufacturerName = _a.manufacturerName, manufacturerId = _a.manufacturerId, prices = _a.prices, programName = _a.programName, programId = _a.programId, shortText = _a.shortText, longText = _a.longText, image = _a.image, name = _a.name;
    var item = {
        ItemType: igd_core_1.IGXB.EItemType.Article,
        ComId: article.comId,
        Configuration: article.configuration,
        Source: article.source,
        ManufacturerId: manufacturerId,
        ManufacturerName: manufacturerName,
        ProgramId: programId,
        ProgramName: programName,
        ArticleShortText: shortText,
        ArticleLongText: longText,
        Data: tslib_1.__assign({}, article.data),
        SubItems: [],
        Image: image,
        ArticleId: article.articleId,
        ArticlePackageId: article.articleNumber !== undefined
            ? article.articleNumber.articlePackageId
            : undefined,
        IsCommercial: false,
        UID: ig_utilities_1.generateId(),
        Categories: tslib_1.__assign({}, article.categories),
        Hidden: article.data.hidden,
        ArticleName: name,
        ArticleNumber: article.articleNumber,
    };
    if (article.placement !== undefined) {
        item.Position = article.placement.position;
        item.Rotation = article.placement.rotation;
    }
    addPrices(item, prices, priceFormatter);
    return item;
};
var createImpression = function (article, basket) {
    var _a = createArticle(article, basket), ItemType = _a.ItemType, SubItems = _a.SubItems, Position = _a.Position, Rotation = _a.Rotation, baseItem = tslib_1.__rest(_a, ["ItemType", "SubItems", "Position", "Rotation"]);
    return tslib_1.__assign({ ItemType: igd_core_1.IGXB.EItemType.Impression }, baseItem);
};
var createSet = function (article, basket) {
    var prices = article.info.prices;
    var item = {
        ItemType: igd_core_1.IGXB.EItemType.Set,
        ComId: article.comId,
        Items: [],
        Source: article.source,
        Configuration: article.configuration,
        SetId: article.articleId,
        UID: ig_utilities_1.generateId(),
        Categories: article.categories,
        Hidden: article.data.hidden,
    };
    addPrices(item, prices, basket);
    return item;
};
var itemBuilders = {
    commercial: createCommercialArticle,
    graphical: createArticle,
    impression: createImpression,
    set: createSet,
    headItem: createCommercialArticle,
};
var createIGXBItem = function (article, basket) {
    var builder = itemBuilders[article.type];
    return builder(article, basket);
};
var addPrices = function (item, prices, basket) {
    var e_2, _a;
    try {
        for (var prices_1 = tslib_1.__values(prices), prices_1_1 = prices_1.next(); !prices_1_1.done; prices_1_1 = prices_1.next()) {
            var price = prices_1_1.value;
            if (price.Level === igd_core_1.IGXE.EPriceLevel.Base) {
                //TODO: price range for this
                item.SinglePrice = price.Value;
                item.Currency = price.Currency;
                break;
            }
            if (item.ItemType !== igd_core_1.IGXB.EItemType.Article) {
                continue;
            }
            if (item.AdditionalPrices === undefined) {
                item.AdditionalPrices = [];
            }
            var tNewAddPrice = {
                Text: price.Text || "",
                Currency: price.Currency,
                Level: price.Level === igd_core_1.IGXE.EPriceLevel.AddToBase
                    ? igd_core_1.IGXB.EAddPriceRule.ToBase
                    : igd_core_1.IGXB.EAddPriceRule.ToSum,
                Value: price.Value,
                RangeMin: price.RangeMin,
                RangeMax: price.RangeMax,
            };
            item.AdditionalPrices.push(tNewAddPrice);
        }
    }
    catch (e_2_1) { e_2 = { error: e_2_1 }; }
    finally {
        try {
            if (prices_1_1 && !prices_1_1.done && (_a = prices_1.return)) _a.call(prices_1);
        }
        finally { if (e_2) throw e_2.error; }
    }
    if (basket !== undefined) {
        item.SinglePriceText = basket.getSinglePriceText(item.ComId);
    }
};
