"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBaseMetadataEntityByOfferId = getBaseMetadataEntityByOfferId;
exports.getBaseMetadataEntities = getBaseMetadataEntities;
exports.getProductV1MetadataEntityByOfferId = getProductV1MetadataEntityByOfferId;
exports.getProductV1MetadataEntities = getProductV1MetadataEntities;
exports.getBundleMetadataEntityByOfferId = getBundleMetadataEntityByOfferId;
exports.getBundleMetadataEntities = getBundleMetadataEntities;
exports.getProductV1Brands = getProductV1Brands;
exports.getProductV1Categories = getProductV1Categories;
exports.getProductV1Products = getProductV1Products;
exports.getAllProductsWithVariants = getAllProductsWithVariants;
exports.getAllProductsWithNotVoidedVariants = getAllProductsWithNotVoidedVariants;
exports.getProductWithVariants = getProductWithVariants;
exports.getProductWithVariantsFromOfferId = getProductWithVariantsFromOfferId;
const graphql_1 = require("../utils/graphql");
const subgraph_1 = require("../subgraph");
function getBaseMetadataEntityByOfferId(subgraphUrl_1, offerId_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, offerId, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { baseMetadataEntity } = yield subgraphSdk.getBaseMetadataEntityByIdQuery(Object.assign({ metadataId: `${offerId}-metadata` }, queryVars));
        return baseMetadataEntity;
    });
}
function getBaseMetadataEntities(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { baseMetadataEntities = [] } = yield subgraphSdk.getBaseMetadataEntitiesQuery(Object.assign({}, queryVars));
        return baseMetadataEntities;
    });
}
function getProductV1MetadataEntityByOfferId(subgraphUrl_1, offerId_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, offerId, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1MetadataEntity } = yield subgraphSdk.getProductV1MetadataEntityByIdQuery(Object.assign({ metadataId: `${offerId}-metadata` }, queryVars));
        return productV1MetadataEntity;
    });
}
function getProductV1MetadataEntities(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1MetadataEntities = [] } = yield subgraphSdk.getProductV1MetadataEntitiesQuery(Object.assign({}, queryVars));
        return productV1MetadataEntities;
    });
}
function getBundleMetadataEntityByOfferId(subgraphUrl_1, offerId_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, offerId, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { bundleMetadataEntity } = yield subgraphSdk.getBundleMetadataEntityByIdQuery(Object.assign({ metadataId: `${offerId}-metadata` }, queryVars));
        return bundleMetadataEntity;
    });
}
function getBundleMetadataEntities(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { bundleMetadataEntities = [] } = yield subgraphSdk.getBundleMetadataEntitiesQuery(Object.assign({}, queryVars));
        return bundleMetadataEntities;
    });
}
function getProductV1Brands(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1Brands = [] } = yield subgraphSdk.getProductV1BrandsQuery(Object.assign({}, queryVars));
        return productV1Brands;
    });
}
function getProductV1Categories(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1Categories = [] } = yield subgraphSdk.getProductV1CategoriesQuery(Object.assign({}, queryVars));
        return productV1Categories;
    });
}
function getProductV1Products(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1Products = [] } = yield subgraphSdk.getProductV1ProductsQuery(Object.assign({}, queryVars));
        return productV1Products;
    });
}
function getAllProductsWithVariants(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1Products = [] } = yield subgraphSdk.getProductV1ProductsWithVariantsQuery(Object.assign({}, queryVars));
        return productV1Products;
    });
}
function getAllProductsWithNotVoidedVariants(subgraphUrl_1) {
    return __awaiter(this, arguments, void 0, function* (subgraphUrl, queryVars = {}) {
        const subgraphSdk = (0, graphql_1.getSubgraphSdk)(subgraphUrl);
        const { productV1Products = [] } = yield subgraphSdk.getAllProductsWithNotVoidedVariantsQuery(Object.assign({}, queryVars));
        return productV1Products;
    });
}
function getProductWithVariants(subgraphUrl, sellerId, productUuid) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a;
        // Look for ProductV1MetadataEntities, filtered per productUuid
        const productV1MetadataEntities = yield getProductV1MetadataEntities(subgraphUrl, {
            metadataFilter: {
                productUuid,
                offer_: {
                    sellerId
                }
            }
        });
        // Look for BundleMetadataEntities, filtered per productUuid
        const bundleMetadataEntities = yield getBundleMetadataEntities(subgraphUrl, {
            metadataFilter: {
                productUuids_contains: [productUuid],
                offer_: {
                    sellerId
                }
            }
        });
        if (productV1MetadataEntities.length + bundleMetadataEntities.length === 0) {
            return null;
        }
        const { itemsFromBundles, bundleSets } = bundleMetadataEntities.reduce((prev, bundle) => {
            const itemsFromBundle = getProductV1ItemFromBundle(bundle, productUuid);
            if (!prev.bundleSets.has(bundle.bundleUuid)) {
                prev.bundleSets.set(bundle.bundleUuid, []);
            }
            prev.bundleSets.get(bundle.bundleUuid).push({
                bundle,
                variations: itemsFromBundle[0].variations // LIMITATION: in case the same bundle contains several times the same product (same variation or different), only the first variation is returned here
            });
            return {
                itemsFromBundles: [...prev.itemsFromBundles, ...itemsFromBundle],
                bundleSets: prev.bundleSets
            };
        }, {
            itemsFromBundles: [],
            bundleSets: new Map()
        });
        const product = productV1MetadataEntities.length
            ? productV1MetadataEntities[0].product
            : (_a = itemsFromBundles[0]) === null || _a === void 0 ? void 0 : _a.productV1Item.product;
        const variants = productV1MetadataEntities.map((m) => {
            return {
                offer: m.offer,
                variations: m.variations
            };
        });
        return {
            product, // return the product
            bundleSets, // return all bundles that contain this product, mapped by bundleUuid
            variants // return all variants for this product
        };
    });
}
/** returns the productV1ItemMetadataEntities in a bundle for a given productUuid */
// Note: it may returns several items, in case the BUNDLE contains different variants of
// the same product (or even the same variant several times),
function getProductV1ItemFromBundle(bundle, productUuid) {
    return bundle.items
        .filter((item) => item.type === subgraph_1.ItemMetadataType.ITEM_PRODUCT_V1)
        .filter((item) => item.productUuid === productUuid)
        .map((item) => {
        return {
            productV1Item: item,
            offer: bundle.offer,
            variations: item.variations
        };
    });
}
function getProductWithVariantsFromOfferId(subgraphUrl, offerId) {
    return __awaiter(this, void 0, void 0, function* () {
        // Look for ProductV1MetadataEntity, filtered by offerId
        const metadataEntity = yield getProductV1MetadataEntityByOfferId(subgraphUrl, offerId);
        if (!metadataEntity) {
            return null;
        }
        return getProductWithVariants(subgraphUrl, metadataEntity.offer.seller.id, metadataEntity.product.uuid);
    });
}
//# sourceMappingURL=subgraph.js.map