/*!
 * Crafted with ❤ by Salla
 */
'use strict';

var index = require('./index-vstkdqRz.js');

var DiscountType;
(function (DiscountType) {
    DiscountType["PERCENTAGE"] = "percentage";
    DiscountType["FIXED"] = "fixed";
    DiscountType["FREE_PRODUCT"] = "free_product";
})(DiscountType || (DiscountType = {}));
var OfferType;
(function (OfferType) {
    OfferType["PRODUCT_COUNT"] = "products_count";
    OfferType["PRODUCT_PURCHASE"] = "order_amount";
})(OfferType || (OfferType = {}));

const sallaConditionalOfferCss = ":host{display:block}";

const SallaConditionalOffer = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.offer = null;
        this.products = {};
        this.isLoading = false;
        this.canRender = true;
    }
    componentWillLoad() {
        salla.onReady().then(() => {
            if (!salla.config.get('store.features')?.includes('conditional-offer') || (salla.storage.get("cart") !== '' && !salla.storage.get("cart")?.summary?.count)) {
                throw new Error('feature or cart object does not existed');
            }
        })
            .then(() => salla.api.cart.offers())
            .then(({ data }) => {
            this.offer = data.find(offer => offer.type === "conditional");
            if (!this.offer) {
                this.canRender = false;
                return;
            }
            this.isLoading = true;
            this.offer.details.discounts.unshift(({ value: 0, min_spend: 0 }));
            return this.updateInitialOfferValue();
        }).then(() => {
            if (!this.offer)
                return;
            return this.getProducts();
        }).then(() => {
            if (!this.offer)
                return;
            salla.event.on("cart::updated", (updatedCart) => this.updateOfferValues(updatedCart));
        })
            .catch(error => {
            this.canRender = false;
            salla.logger.warn('salla-conditional-offer:: ', error);
        }).finally(() => {
            this.isLoading = false;
        });
    }
    getProducts() {
        const freeProductIDs = this.offer.details.discounts.filter(({ type }) => type === DiscountType.FREE_PRODUCT).map(({ value }) => value).filter(Boolean);
        if (freeProductIDs.length > 0) {
            return salla.product.fetch({ source: 'selected', source_value: freeProductIDs }).then((response) => {
                const data = response?.data;
                if (data && Array.isArray(data)) {
                    const updatedProducts = { ...this.products };
                    data.forEach(({ id, url, image, name, price }) => {
                        if (id && name && image?.url && url && price !== undefined) {
                            updatedProducts[id] = { url, image, name, price };
                        }
                    });
                    this.products = updatedProducts;
                }
            });
        }
    }
    updateInitialOfferValue() {
        return salla.api.cart.details().then(({ data: { cart } }) => this.updateOfferValues(cart));
    }
    updateOfferValues({ items, sub_total }) {
        const current_value = this.offer.details.based_on === OfferType.PRODUCT_COUNT ? items?.reduce((count, { quantity }) => count + quantity, 0) ?? 0 : sub_total;
        //we need to assign the offer object a new reference to trigger re-rendering
        this.offer = {
            ...this.offer, details: {
                ...this.offer?.details, current_value,
            }
        };
        return this.offer;
    }
    renderTooltip(discount) {
        const productId = discount.value;
        const productItem = this.products[productId];
        const targetId = `avatar-product-${productId}`;
        if (!productItem) {
            salla.logger.error(`salla-conditional-offer:: there is no product with id (${discount.value})!`);
            return null;
        }
        return index.h("salla-tooltip", { class: 'absolute left-0 -top-2', targetId: targetId, theme: "dark" }, index.h("div", { class: "flex gap-3 text-start" }, productItem?.image?.url && index.h("img", { src: productItem.image.url, alt: productItem?.image?.alt || productItem.name || "", class: "w-12 h-12 object-cover rounded-lg flex-shrink-0", loading: "lazy", decoding: "async" }), index.h("div", { class: "flex-1" }, index.h("div", { class: "leading-tight mb-1" }, productItem.name), index.h("div", { class: "text-xs text-gray-300", innerHTML: salla.money(productItem.price) }))));
    }
    getCheckpointContent(discount) {
        if (discount.type === DiscountType.PERCENTAGE)
            return `${discount.value}%`;
        if (discount.type === DiscountType.FIXED)
            return index.h("span", { innerHTML: salla.money(discount.value) });
        if (discount.type !== DiscountType.FREE_PRODUCT) {
            salla.logger.error(`salla-conditional-offer:: unexpected type (${discount.type})!`);
            return "";
        }
        const productItem = this.products[discount.value];
        if (!productItem) {
            salla.logger.error(`salla-conditional-offer:: there is no product with id (${discount.value})!`);
            return "";
        }
        return index.h("a", { class: "s-conditional-offer-product-link", href: productItem.url }, index.h("img", { class: "s-conditional-offer-checkpoint-image-content", loading: "lazy", decoding: "async", alt: productItem?.image?.alt || "", src: productItem?.image?.url }));
    }
    getOfferType(discount) {
        const basedOn = this.offer.details?.based_on;
        if (basedOn === OfferType.PRODUCT_COUNT) {
            try {
                return salla.lang.choice("blocks.header.products_count", discount.min_spend);
            }
            catch (error) {
                // Some stores may define an invalid interval (e.g. [1,*]) in translations.
                // Fallback to a safe plain label so the component does not crash.
                salla.logger.warn("salla-conditional-offer:: invalid products_count interval", error);
                return `${discount.min_spend}`;
            }
        }
        if (basedOn === OfferType.PRODUCT_PURCHASE)
            return salla.money(discount.min_spend);
        salla.logger.warn(`salla-conditional-offer:: Unexpected offer detail's based_on value: ${basedOn}`);
        return `${discount.min_spend}`;
    }
    clamp(value, min, max) {
        return Math.max(min, Math.min(value, max));
    }
    mapValueRanges(value, initialMinRange, initialMaxRange, newMinRange, newMaxRange) {
        const newRange = ((value - initialMinRange) * (newMaxRange - newMinRange)) / (initialMaxRange - initialMinRange) + newMinRange;
        if (newRange === Number.POSITIVE_INFINITY)
            return 100;
        if (newRange === Number.NEGATIVE_INFINITY)
            return 0;
        return this.clamp(newRange, 0, 100);
    }
    getCheckPointView(discount, index$1) {
        const checkpointIndex = this.offer.details.discounts.findIndex(({ min_spend }) => min_spend === discount.min_spend);
        const previousCheckpointValue = this.offer.details.discounts[checkpointIndex - 1]?.min_spend ?? 0;
        const progressPercentage = this.mapValueRanges(this.offer.details.current_value, previousCheckpointValue, discount.min_spend, 0, 100);
        const isActive = discount.min_spend <= this.offer.details.current_value;
        return (index.h("div", { class: "s-conditional-offer-checkpoint-container" }, index$1 > 0 ? [
            index.h("div", { key: "progress-line", class: "s-conditional-offer-progress-line-container" }, index.h("div", { class: "s-conditional-offer-progress-line-inactive" }), index.h("div", { class: "s-conditional-offer-progress-line-active", style: { width: `${progressPercentage}%` } })),
            index.h("div", { key: "checkpoint", class: `s-conditional-offer-checkpoint ${isActive ? "s-conditional-offer-active-checkpoint" : ""}` }, index.h("div", { class: `s-conditional-offer-item-avatar-content ${isActive ? "active" : ""}`, id: discount.type === DiscountType.FREE_PRODUCT ? `avatar-product-${discount.value}` : `avatar-${discount.value ?? index$1}` }, this.products && this.getCheckpointContent(discount)), this.products && discount.type === DiscountType.FREE_PRODUCT && this.renderTooltip(discount), index.h("div", { class: `s-conditional-offer-checkpoint-label ${isActive ? "active" : ""}`, innerHTML: this.getOfferType(discount) }))
        ] :
            index.h("div", { key: "label", class: { "s-conditional-offer-checkpoint-label": true, "first-checkpoint": index$1 === 0, active: isActive, "hidden": index$1 === 0, "sm:block": index$1 === 0 }, innerHTML: this.getOfferType(discount) })));
    }
    getLoadingSkeletonView() {
        return index.h(index.Host, { class: "s-conditional-offer-container" }, index.h("div", { class: "s-conditional-offer-skeleton-inner-container" }, index.h("div", { class: "s-conditional-offer-skeleton-subtitle" }, index.h("salla-skeleton", { height: "16px", width: "30%" })), index.h("div", { class: "s-conditional-offer-skeleton-subtitle" }, index.h("salla-skeleton", { height: "16px", width: "35%" })), index.h("div", { class: "s-conditional-offer-skeleton-checkpoints-wrapper" }, Array(3).fill(null).map(() => ([index.h("salla-skeleton", { key: "checkpoint-line", height: "8px" }), index.h("div", { key: "checkpoint" }, index.h("salla-skeleton", { height: "60px", width: "60px", type: "circle" }))])))));
    }
    render() {
        if (!this.canRender)
            return null;
        if (this.isLoading)
            return this.getLoadingSkeletonView();
        if (!this.offer)
            return null;
        return index.h(index.Host, { class: "s-conditional-offer-container" }, index.h("div", { class: "s-conditional-offer-title-wrapper" }, index.h("div", { class: "s-conditional-offer-title" }, this.offer.title), this.offer.description ? index.h("div", { class: "s-conditional-offer-subtitle" }, this.offer.description, " ", index.h("i", { class: "sicon-information" })) : null), index.h("div", { class: "s-conditional-offer-progress-container" }, this.offer.details.discounts.map((discount, index$1) => (index.h("div", { class: { "flex-1": index$1 > 0 }, key: discount.min_spend }, this.getCheckPointView(discount, index$1))))));
    }
};
SallaConditionalOffer.style = sallaConditionalOfferCss;

exports.salla_conditional_offer = SallaConditionalOffer;
