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

var index = require('./index-vstkdqRz.js');
var check = require('./check-BnVBPQNp.js');
var anime_es = require('./anime.es-BqW8JHZi.js');
var Helper = require('./Helper-CU4Xuiki.js');
var star2 = require('./star2-R146a27p.js');
var arrowLeft = require('./arrow-left-xSEmRpp6.js');
var shoppingBag = require('./shopping-bag-C1gvTVHr.js');

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

const SallaCommentForm = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.commentAdded = index.createEvent(this, "commentAdded");
        this.placeholder = salla.lang.get('blocks.comments.placeholder');
        this.submitText = salla.lang.get('blocks.comments.submit');
        salla.lang.onLoaded(() => {
            this.placeholder = salla.lang.get('blocks.comments.placeholder');
            this.submitText = salla.lang.get('blocks.comments.submit');
        });
        salla.onReady(() => {
            this.canComment = salla.config.get('user.can_comment');
            this.itemId = salla.config.get('page.id');
            this.type = salla.url.is_page('page-single') ? 'page' : salla.url.is_page('blog.single') ? 'blog' : 'product';
        });
    }
    submit() {
        if (!this.commentForm.reportValidity()) {
            salla.log('CommentForm:: validation error!');
            return;
        }
        const commentText = this.commentField.value;
        this.submitBtn.load()
            .then(() => salla.comment.add({ id: this.itemId, comment: commentText, type: this.type }))
            .then(() => {
            this.commentAdded.emit({
                name: salla.config.get('user.name'),
                avatar: salla.config.get('user.avatar'),
                content: commentText,
                is_pending: true,
                created_at: { date: new Date().toISOString().replace('T', ' ').substring(0, 19) },
                images: [],
            });
            this.commentField.value = '';
        })
            .finally(() => this.submitBtn.stop());
    }
    render() {
        return (index.h(index.Host, { key: '2203b9f365e0658a3bc40fb0274ba9ddc0d1e040' }, !!this.canComment ? index.h("form", { ref: frm => this.commentForm = frm }, index.h("div", { class: "s-comment-form-wrapper" }, this.showAvatar ?
            index.h("img", { class: "s-comment-form-avatar", src: salla.config.get('user.avatar'), alt: "user avatar" }) : '', index.h("div", { class: "s-comment-form-content" }, index.h("textarea", { cols: 30, rows: 5, minlength: "4", maxlength: "500", ref: field => this.commentField = field, placeholder: this.placeholder, class: "s-comment-form-input", required: true }), index.h("br", null), index.h("div", { class: "s-comment-form-action" }, index.h("salla-button", { ref: btn => this.submitBtn = btn, "loader-position": 'center', onClick: () => this.submit() }, this.submitText))))) : ''));
    }
};
SallaCommentForm.style = sallaCommentFormCss;

var Reply = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>reply</title>
<path d="M20 14.667h-12.609l9.401-6.927c0.592-0.436 0.72-1.271 0.283-1.863-0.439-0.595-1.273-0.72-1.864-0.283l-12.667 9.333c-0.343 0.251-0.544 0.649-0.544 1.072s0.201 0.821 0.543 1.073l12.667 9.333c0.237 0.176 0.515 0.26 0.789 0.26 0.409 0 0.813-0.188 1.075-0.543 0.437-0.592 0.309-1.427-0.283-1.863l-9.4-6.928h12.609c4.412 0 8 3.588 8 8 0 0.737 0.597 1.333 1.333 1.333s1.333-0.596 1.333-1.333c0-5.881-4.785-10.667-10.667-10.667z"></path>
</svg>
`;

var ThumbsUp = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>thumbs-up</title>
<path d="M26.667 10.667h-8.261l1.279-3.38c0.723-1.911 0.087-4.051-1.549-5.203-0.909-0.639-2.004-0.881-3.085-0.684-1.101 0.203-2.061 0.837-2.703 1.787l-5.452 8.067c-0.148 0.22-0.228 0.48-0.228 0.747v12c0 3.676 2.991 6.667 6.667 6.667h8.688c2.535 0 4.817-1.407 5.955-3.671l2.548-5.063c0.093-0.187 0.143-0.392 0.143-0.6v-6.667c0-2.205-1.795-4-4-4zM28 21.017l-2.405 4.78c-0.683 1.359-2.052 2.203-3.573 2.203h-8.688c-2.205 0-4-1.795-4-4v-11.592l5.223-7.728c0.237-0.352 0.584-0.585 0.975-0.657 0.367-0.067 0.749 0.017 1.068 0.241 0.631 0.444 0.879 1.317 0.591 2.079l-1.963 5.185c-0.156 0.409-0.099 0.869 0.149 1.229s0.66 0.576 1.099 0.576h10.192c0.735 0 1.333 0.599 1.333 1.333zM2.667 10.667c-0.736 0-1.333 0.597-1.333 1.333v16c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-16c0-0.736-0.597-1.333-1.333-1.333z"></path>
</svg>
`;

const sallaCommentsCss$1 = ":host{display:block}";

const SallaCommentItem = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        // Translations
        this.has_bought_trans = salla.lang.get('blocks.comments.has_bought');
        this.rated_trans = salla.lang.get('pages.rating.rated');
        this.waiting_approval_trans = salla.lang.get('blocks.comments.waiting_approval');
        this.has_order_trans = salla.lang.get('blocks.comments.has_order');
        this.allowLikes = salla.config.get('store.settings.rating.allow_likes');
        this.allowAttachImages = salla.config.get('store.settings.rating.allow_attach_images');
        this.helpfulLabel = salla.lang.getWithDefault('blocks.comments.helpful', 'مفيد');
        this.likesCount = 0;
        this.likedComments = [];
        salla.lang.onLoaded(() => {
            const setNestedAsync = (lang, key, value) => {
                return new Promise((resolve) => {
                    salla.helpers.setNested(salla.lang.messages[lang], key, value);
                    resolve(true);
                });
            };
            const setTranslations = async () => {
                await setNestedAsync('ar.trans', 'blocks.comments.helpful', 'مفيد');
                await setNestedAsync('en.trans', 'blocks.comments.helpful', 'Helpful');
                this.helpfulLabel = salla.lang.getWithDefault('blocks.comments.helpful', 'مفيد');
            };
            this.has_bought_trans = salla.lang.get('blocks.comments.has_bought');
            this.rated_trans = salla.lang.get('pages.rating.rated');
            this.waiting_approval_trans = salla.lang.get('blocks.comments.waiting_approval');
            this.has_order_trans = salla.lang.get('blocks.comments.has_order');
            setTranslations();
        });
    }
    componentDidLoad() {
        this.likesCount = this.comment.likes_count;
        try {
            this.likedComments = JSON.parse(localStorage.getItem('liked_comments') || '[]');
            if (this.likedComments.includes(this.comment.id)) {
                this.likeBtn.classList.add('liked');
                this.likeBtn.fill = "solid";
            }
        }
        catch {
            salla.log('Bad json for liked_comments');
        }
    }
    getReplies() {
        return Array.isArray(this.comment.replies) ? this.comment.replies : [this.comment.replies];
    }
    getDate(dateString) {
        const [datePart] = dateString.split(' ');
        const [year, month, day] = datePart.split('-');
        const formattedDate = `${parseInt(day, 10)}/${parseInt(month, 10)}/${parseInt(year, 10)}`;
        return formattedDate;
    }
    getTime(dateString) {
        const [, timePart] = dateString.split(' ');
        const [hours, minutes] = timePart.split(':');
        const formattedTime = `${parseInt(hours, 10)}:${parseInt(minutes, 10)}`;
        return formattedTime;
    }
    async toggleLike() {
        if (salla.config.isGuest()) {
            return salla.notify.error(salla.lang.get('common.messages.must_login'));
        }
        this.likedComments = JSON.parse(localStorage.getItem('liked_comments') || '[]');
        const isLiked = this.likedComments.includes(this.comment.id);
        try {
            const endpoint = isLiked ? `rating/${this.comment.id}/unlike` : `rating/${this.comment.id}/like`;
            const res = await salla.api.request(endpoint, '', 'put');
            salla.log(res.message);
            if (isLiked) {
                this.likeBtn.classList.remove('liked');
                this.likeBtn.fill = 'outline';
                this.updateLikedComments(this.comment.id, false);
                this.likesCount--;
            }
            else {
                this.likeBtn.classList.add('liked');
                this.likeBtn.fill = 'solid';
                this.updateLikedComments(this.comment.id, true);
                this.likesCount++;
            }
        }
        catch (e) {
            if (e.response.status == 409) {
                if (this.likeBtn.classList.contains('liked')) {
                    this.likeBtn.fill = 'outline';
                    this.likeBtn.classList.remove('liked');
                    this.updateLikedComments(this.comment.id, false);
                    this.likesCount--;
                }
                else {
                    this.likeBtn.fill = 'solid';
                    this.likeBtn.classList.add('liked');
                    salla.logger.warn('Like already exists');
                    this.updateLikedComments(this.comment.id, true);
                }
            }
        }
    }
    updateLikedComments(commentId, add) {
        this.likedComments = JSON.parse(localStorage.getItem('liked_comments') || '[]');
        if (add) {
            if (!this.likedComments.includes(commentId)) {
                this.likedComments.push(commentId);
            }
        }
        else {
            this.likedComments = this.likedComments.filter(id => id !== commentId);
        }
        localStorage.setItem('liked_comments', JSON.stringify(this.likedComments));
    }
    PinnedIcon() {
        return (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "16", height: "16", color: "#555555", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("path", { d: "M12 16V21" }), index.h("path", { d: "M8 5.2918C8 5.02079 8 4.88529 8.01312 4.77132C8.1194 3.84789 8.84789 3.1194 9.77133 3.01312C9.88529 3 10.0208 3 10.2918 3H13.7082C13.9792 3 14.1147 3 14.2287 3.01312C15.1521 3.1194 15.8806 3.84789 15.9869 4.77132C16 4.88529 16 5.02079 16 5.2918C16 5.37885 16 5.42237 15.9967 5.46264C15.9708 5.78281 15.7927 6.07104 15.5179 6.2374C15.4834 6.25832 15.4444 6.27779 15.3666 6.31672L15.1055 6.44726C14.7021 6.64897 14.5003 6.74983 14.3681 6.90564C14.26 7.03286 14.1856 7.18509 14.1515 7.34846C14.1097 7.54854 14.1539 7.76968 14.2424 8.21197L15 12H15.3333C15.9533 12 16.2633 12 16.5176 12.0681C17.2078 12.2531 17.7469 12.7922 17.9319 13.4824C18 13.7367 18 14.0467 18 14.6667C18 14.9767 18 15.1317 17.9659 15.2588C17.8735 15.6039 17.6039 15.8735 17.2588 15.9659C17.1317 16 16.9767 16 16.6667 16H7.33333C7.02334 16 6.86835 16 6.74118 15.9659C6.39609 15.8735 6.12654 15.6039 6.03407 15.2588C6 15.1317 6 14.9767 6 14.6667C6 14.0467 6 13.7367 6.06815 13.4824C6.25308 12.7922 6.79218 12.2531 7.48236 12.0681C7.73669 12 8.04669 12 8.66667 12H9L9.75761 8.21197C9.84606 7.76968 9.89029 7.54854 9.84852 7.34846C9.81441 7.18509 9.73995 7.03286 9.63194 6.90564C9.49965 6.74983 9.29794 6.64897 8.89452 6.44726L8.63344 6.31672C8.55558 6.27779 8.51665 6.25832 8.48208 6.2374C8.20731 6.07104 8.02917 5.78281 8.00326 5.46264C8 5.42237 8 5.37885 8 5.2918Z" })));
    }
    render() {
        let isAdmin = this.comment.type == 'admin';
        return (index.h(index.Host, { key: '05b9da17f0e07e1115c87c671998e8123b8b0bb4', class: isAdmin ? 's-comments-item-admin' : 's-comments-item' }, index.h("div", { key: '49552e9efab0aa751db6d7051318f626f9124e5a', class: { "s-comments-item-wrapper": !isAdmin, "s-comments-item-admin-wrapper": isAdmin }, id: `s-comments-item-${this.comment.id}` }, index.h("div", { key: 'e795f238ee0a562675843e6da0f495512abf550c', class: "s-comments-item-inner s-comments-flex-1" }, isAdmin && index.h("span", { key: '05270553da039c8cdf611d7a1a0ac1ff9d5d88f2', class: "s-comments-item-reply-icon", innerHTML: Reply }), index.h("div", { key: 'be2ca109e89c83691d3a0a7a9e03f6e1b94fb09e', class: "s-comments-item-avatar" }, index.h("img", { key: '402cff5a2003bf385ae8f9f7890555ef2886de87', "data-src": this.comment?.avatar, alt: this.comment?.name, src: this.comment?.avatar, class: "s-comments-item-avatar-img lazy" })), index.h("div", { key: 'af7992ad18ed3d756594cf678d01c1fdd2af6cca', class: "s-comments-flex-1" }, index.h("div", { key: 'b11dc77d96bf83c0dddd1edaa5fb57286b5b6f55', class: "s-comments-item-user-wrapper" }, index.h("div", { key: 'f899a929d3e67c7898d22cf7abc56891cdf0fa7c', class: "s-comments-item-user-info" }, index.h("h3", { key: '9968169cbd69eb6d1d7e0b0498db03a0431d2a16', class: this.comment.is_pinned ? "s-comments-item-user-info-name" : "s-comments-item-user-info-name-with-margin" }, this.comment?.name), this.comment.is_pinned ?
            index.h("div", { class: "s-comments-item-pinned-icon-with-margin" }, this.PinnedIcon())
            : null, (this.comment.has_order || !!this.comment.rating) && !this.comment.is_pending && !this.hideBought ?
            index.h("div", { class: "s-comments-flex" }, this.comment.has_order ?
                [index.h("span", { class: "s-comments-item-has-order-check-icon", innerHTML: check.SICheck }), index.h("span", { class: "s-comments-item-has-order-check-text" }, this.has_bought_trans, " ", this.comment.rating ? ', ' : '')] : null, !!this.comment.rating ?
                index.h("span", { class: "s-comments-item-rated-widget" }, this.rated_trans) : null)
            : null), index.h("p", { key: 'cafa0be66307c6b377f90033745b939da66344c8', class: "s-comments-item-timestamp s-ltr" }, this.getDate(this.comment.created_at?.date), index.h("span", { key: '608db7108242f10e4d649bb23d1382f49227aeb8', class: "s-comments-item-time" }, " - ", this.getTime(this.comment.created_at?.date))), !!this.comment.rating || !!this.comment.stars ?
            index.h("salla-rating-stars", { size: "mini", class: "s-comments-item-stars", value: this.comment.rating || this.comment.stars })
            : null), index.h("div", { key: '9b86497c3791f7e890b560207068de4ca38d6e60', class: "s-comments-item-content" }, index.h("p", { key: '82433f42c6b0ee29cdd42725ce1aba4dd62e67d8', innerHTML: this.comment.content }), this.allowAttachImages && index.h("div", { key: '9a1bd14eb18f637588f152b8842d4637b9a6e7c1', class: "s-comments-item-images" }, this.comment.images.map((image, index$1) => (index.h("img", { key: index$1, src: image, alt: "", onClick: () => this.modal.open() }))), index.h("salla-modal", { key: 'be260096b68a1a58889bed09c68b3a2c75adefa6', ref: modal => this.modal = modal, width: "sm" }, index.h("salla-slider", { key: '8f78ee0ab370e4f99eb68fe1afa4491c4a6a0b80', id: `s-comments-item-${this.comment.id}-images`, class: "s-comments-item-images-slider", type: "thumbs", "auto-height": true, showControls: this.comment.images.length > 1 ? true : false, "show-thumbs-controls": "false" }, index.h("div", { key: 'eea6149852a409f2e25b8f9ec4375087e1c9beb8', slot: 'items' }, this.comment.images.map((image, index$1) => (index.h("img", { key: index$1, src: image, alt: "" })))), index.h("div", { key: '9f693fcd5afc5e443e0ff590d6e7e386746e2a98', slot: "thumbs" }, this.comment.images.map((image, index$1) => (index.h("div", { class: "s-comments-item-images-slider-thumb" }, index.h("img", { key: index$1, src: image, alt: "" })))))))), this.allowLikes && !isAdmin && !!this.comment.id && salla.url.is_page('product.single') ? index.h("salla-button", { ref: el => this.likeBtn = el, class: `s-comments-item-like-btn ${this.likedComments.includes(this.comment.id) ? 'liked' : ''}`, loaderPosition: 'center', fill: 'outline', size: 'small', onClick: () => this.toggleLike() }, index.h("span", null, this.helpfulLabel, " ", this.likesCount > 0 ? `(${this.likesCount})` : ''), index.h("span", { innerHTML: ThumbsUp })) : '', this.comment.is_pending ?
            index.h("span", { class: "s-comments-item-pending-text" }, this.waiting_approval_trans) : null))), !!this.getReplies().length && !isAdmin ?
            this.getReplies().map((reply) => {
                return index.h("div", null, index.h("salla-comment-item", { comment: reply }));
            }) : null)));
    }
    get host() { return index.getElement(this); }
};
SallaCommentItem.style = sallaCommentsCss$1;

var CommentType;
(function (CommentType) {
    CommentType["PAGE"] = "page";
    CommentType["PRODUCT"] = "product";
    CommentType["BLOG"] = "blog";
})(CommentType || (CommentType = {}));

var ChatBubbles = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>chat-bubbles</title>
<path d="M15.333 17.333c4.779 0 8.667-3.888 8.667-8.667s-3.888-8.667-8.667-8.667h-6.667c-4.779 0-8.667 3.888-8.667 8.667 0 2.985 1.513 5.712 4 7.297v4.703c0 0.497 0.277 0.953 0.717 1.183 0.195 0.1 0.405 0.151 0.616 0.151 0.269 0 0.536-0.081 0.764-0.241l6.323-4.425zM11.236 14.908l-4.569 3.199v-2.913c0-0.5-0.28-0.959-0.725-1.187-2.020-1.035-3.275-3.080-3.275-5.34 0-3.308 2.692-6 6-6h6.667c3.308 0 6 2.692 6 6s-2.692 6-6 6h-3.333c-0.273 0-0.54 0.084-0.764 0.241zM29.196 12.964c-0.543-0.5-1.388-0.464-1.884 0.077-0.5 0.541-0.465 1.385 0.077 1.884 1.253 1.156 1.944 2.72 1.944 4.408 0 2.26-1.255 4.305-3.275 5.339-0.445 0.228-0.725 0.687-0.725 1.188v2.572l-5.441-2.939c-0.195-0.104-0.412-0.16-0.633-0.16h-2.592c-1.688 0-3.309-0.724-4.451-1.988-0.492-0.545-1.335-0.591-1.883-0.096-0.547 0.493-0.589 1.336-0.096 1.883 1.644 1.823 3.988 2.868 6.429 2.868h2.255l7.111 3.84c0.199 0.107 0.417 0.16 0.635 0.16 0.236 0 0.472-0.063 0.683-0.188 0.404-0.241 0.651-0.676 0.651-1.145v-4.036c2.487-1.585 4-4.311 4-7.297 0-2.407-1.023-4.727-2.804-6.369z"></path>
</svg>
`;

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

const SallaComments = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        /**
         * Comment Type
         */
        this.type = CommentType.PAGE;
        /**
         * Show or hide avatar
         */
        this.showFormAvatar = false;
        /**
       * Hide Bought
       */
        this.hideBought = false;
        /**
         * Determines if the comments are testimonials
         */
        this.testimonials = false;
        this.customerId = null;
        // Translations
        this.noComments = salla.lang.get('blocks.comments.no_comments');
        this.comment_title = salla.lang.get('blocks.comments.title');
        this.comment_name = salla.lang.get('blocks.comments.comment');
        this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
        this.allowLikes = salla.config.get('store.settings.rating.allow_likes');
        salla.onReady(() => {
            this.allowLikes = salla.config.get('store.settings.rating.allow_likes');
            this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
        });
        salla.lang.onLoaded(() => {
            this.comment_title = salla.lang.get('blocks.comments.title');
            this.comment_name = salla.lang.get('blocks.comments.comment');
            this.noComments = salla.lang.get('pages.rating.no_ratings');
            const setNestedAsync = (lang, key, value) => {
                return new Promise((resolve) => {
                    salla.helpers.setNested(salla.lang.messages[lang], key, value);
                    resolve(true);
                });
            };
            const setTranslations = async () => {
                await setNestedAsync('ar.trans', 'blocks.comments.most_helpful', 'الأكثر إفادة');
                await setNestedAsync('en.trans', 'blocks.comments.most_helpful', 'Most helpful');
                this.mostHelpfulLabel = salla.lang.get('blocks.comments.most_helpful');
                this.comment_title = salla.lang.get('blocks.comments.title');
                this.comment_name = salla.lang.get('blocks.comments.comment');
                this.noComments = salla.lang.get('pages.rating.no_ratings');
            };
            setTranslations();
        });
    }
    // TOOD: it's a good idea to move this into lang.js
    // Pluralize a string based on the count
    pluralize(phrases, count) {
        const options = phrases.split('|');
        const conditions = [
            { condition: count === 0, index: 0 },
            { condition: count === 1, index: 1 },
            { condition: count === 2, index: 2 },
            { condition: count > 2 && count <= 10, index: 3 },
            { condition: count >= 11, index: 4 }
        ];
        const { index } = conditions.find(({ condition }) => condition) || { index: options.length - 1 };
        const selectedOption = options[index];
        return selectedOption.replace(':count', salla.helpers.number(count.toString()))
            .replace(/\{[0-9]+\}/g, '')
            .replace(/\[\d+,\d+\]|\[11,\*\]/g, '');
    }
    wrapConsoleError() {
        if (Salla.infiniteScroll.errorWrapped) {
            return;
        }
        (() => {
            const orig = console.error.bind(console);
            console.error = (...args) => {
                const msg = args[0];
                // only rewrite the noisy one
                if (typeof msg === 'string' && msg.toLowerCase().replace(/\s/g, '').includes('infinitescroll')) {
                    return console.log(...args); // downgrade to log
                }
                return orig(...args); // keep real errors
            };
        })();
        Salla.infiniteScroll.errorWrapped = true;
    }
    // Preserve sort and private_comments params in next page URL for infinite scroll
    patchNextPageUrl() {
        if (!this.nextPage)
            return;
        try {
            const url = new URL(this.nextPage, window.location.origin);
            if (this.sort && !url.searchParams.get('sort')) {
                url.searchParams.set('sort', this.sort);
            }
            if (this.customerId && !url.searchParams.get('private_comments')) {
                url.searchParams.set('private_comments', this.customerId);
            }
            this.nextPage = url.toString();
        }
        catch (_e) {
            // fallback for relative next links
            const hasQuery = this.nextPage.includes('?');
            if (this.sort && !/[?&]sort=/.test(this.nextPage)) {
                this.nextPage = this.nextPage + (hasQuery ? '&' : '?') + `sort=${this.sort}`;
            }
            if (this.customerId && !/[?&]private_comments=/.test(this.nextPage)) {
                const sep = this.nextPage.includes('?') ? '&' : '?';
                this.nextPage = this.nextPage + sep + `private_comments=${this.customerId}`;
            }
        }
    }
    // Initiate infinite scroll
    initiateInfiniteScroll() {
        if (!this.wrapper) {
            console.error('Wrapper is undefined. Cannot initiate infinite scroll.');
            return;
        }
        this.wrapConsoleError();
        this.infiniteScroll = salla.infiniteScroll.initiate(this.wrapper, this.wrapper, {
            path: () => this.nextPage,
            history: false,
            nextPage: this.nextPage,
            scrollThreshold: false,
        }, true);
        this.infiniteScroll?.on('request', _response => {
            this.loading();
        });
        this.infiniteScroll?.on('load', response => {
            this.pagination = response.pagination;
            this.nextPage = typeof response.pagination.links === 'object' && !!response.pagination.links.next ? response.pagination.links.next : null;
            this.patchNextPageUrl();
            for (const card of this.handleResponse(response)) {
                this.wrapper.append(card);
            }
            const items = this.host.querySelectorAll('salla-comment-item:not(.animated):not(.s-comments-item-admin)');
            this.animateItems(items);
            this.loading(false);
        });
        this.infiniteScroll?.on('error', (e) => {
            salla.console.error('Error loading more comments:', e);
        });
    }
    // Show/hide loading
    loading(isLoading = true) {
        const btnText = this.status?.querySelector('.s-button-text');
        if (btnText) {
            Helper.Helper.toggleElementClassIf(btnText, 's-button-hide', 's-button-show', () => isLoading);
            this.btnLoader.style.display = isLoading ? 'inherit' : 'none';
        }
    }
    // Animate newly added items
    animateItems(items) {
        anime_es.anime({
            targets: items,
            opacity: [0, 1],
            duration: 1200,
            translateY: [20, 0],
            delay: (_el, i) => i * 100,
            easing: 'easeOutExpo',
            complete: (_anim) => {
                for (const item of items) {
                    item.classList.add('animated');
                }
            }
        });
    }
    /**
     * Reloads the comments data from the server
     */
    async reload() {
        this.showPlaceholder = false;
        if (this.wrapper) {
            this.wrapper.innerHTML = "";
            const loading = document.createElement('salla-loading');
            this.wrapper.append(loading);
        }
        this.nextPage = null;
        this.loadInitialData();
    }
    // Get comment item HTML
    getCommentHTML(comment) {
        const commentItem = document.createElement('salla-comment-item');
        commentItem.comment = comment;
        commentItem.hideBought = this.hideBought;
        return commentItem;
    }
    // Parse response and return an array of comment items to be appended to the wrapper
    handleResponse(response) {
        return response.data?.map(comment => this.getCommentHTML(comment)) || [];
    }
    componentWillLoad() {
        return salla.onReady()
            .then(() => {
            this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
        })
            .then(() => this.loading())
            .then(() => {
            this.hideTitle = this.hideTitle || this.testimonials;
            this.hideForm = this.hideForm || this.testimonials;
            return this.loadInitialData();
        });
    }
    /**
     * Catch the commentAdded event emitted by salla-comment-form and instantly render it
     */
    onCommentAdded(event) {
        const comment = event.detail;
        if (!comment)
            return;
        // If comments were empty, clear the placeholder and initialize the list
        if (this.showPlaceholder || !this.total) {
            this.showPlaceholder = false;
            this.total = (this.total || 0) + 1;
            this.comments = this.comments || [];
        }
        else {
            this.total = (this.total || 0) + 1;
        }
        // Wait for next render tick so wrapper is available if placeholder was just removed
        setTimeout(() => {
            if (!this.wrapper)
                return;
            const commentItem = this.getCommentHTML(comment);
            this.wrapper.prepend(commentItem);
            this.animateItems([commentItem]);
        }, 0);
    }
    // Load initial data
    async loadInitialData() {
        try {
            let resp = { data: [], pagination: {} };
            const searchParams = new URLSearchParams(window.location.search);
            if (searchParams.has('sort')) {
                this.sort = searchParams.get('sort');
            }
            if (this.testimonials) {
                const params = {
                    sort: this.sort,
                    type: "store"
                };
                resp = await salla.api.request('reviews', { params }, 'get');
            }
            else {
                const showPrivateComments = searchParams.get('private_comments');
                this.customerId = (showPrivateComments && Salla.config.get('user.type') === 'user' && Salla.config.get('user.id'))
                    ? Salla.config.get('user.id')
                    : null;
                resp = await salla.api.comment.getComments(this.type, this.itemId, 1, 5, this.sort, this.customerId);
            }
            if (!resp.data || !resp.data.length) {
                this.showPlaceholder = false;
                this.loading(false);
                return;
            }
            if (this.wrapper) {
                this.wrapper.innerHTML = "";
            }
            this.comments = resp.data;
            this.pagination = resp.pagination;
            this.total = resp.pagination.total;
            this.nextPage = typeof resp.pagination.links === 'object' && !!resp.pagination.links.next ? resp.pagination.links.next : null;
            this.patchNextPageUrl();
            setTimeout(() => {
                for (const card of this.handleResponse(resp)) {
                    this.wrapper.append(card);
                }
                this.initiateInfiniteScroll(); // Initiate infinite scroll after the initial data is loaded
                const items = this.wrapper.querySelectorAll('salla-comment-item:not(.animated)');
                this.animateItems(items);
            }, 100);
        }
        catch (error) {
            console.error('Error loading initial data:', error);
            this.showPlaceholder = true;
            this.loading(false);
        }
    }
    // Get next page
    async loadMore() {
        this.infiniteScroll?.loadNextPage();
    }
    render() {
        // We should show a different placeholder for pages and products (WIP)
        if (this.showPlaceholder) {
            return (index.h("div", null, !!this.total && !this.hideTitle ? index.h("h2", { class: "s-comments-title" }, this.blockTitle ? this.blockTitle : this.comment_title) : '', !this.hideForm && !this.testimonials ? index.h("salla-comment-form", { showAvatar: this.showFormAvatar, type: this.type, "item-id": this.itemId }) : '', index.h("div", { class: "s-comments-placeholder" }, index.h("span", { innerHTML: ChatBubbles }), index.h("p", null, this.noComments))));
        }
        return (index.h("div", { class: `s-comments s-comments-${this.testimonials ? 'testimonials' : this.type}` }, index.h("div", { class: `${this.type === CommentType.PAGE ? "s-comments-page-container" : "s-comments-container"}` }, !!this.total && !this.hideTitle ? index.h("h2", { class: "s-comments-title" }, this.blockTitle ? this.blockTitle : this.comment_title) : '', !this.hideForm && index.h("salla-comment-form", { showAvatar: this.showFormAvatar, type: this.type, "item-id": this.itemId }), salla.url.is_page('product.single') ? index.h("salla-reviews-summary", { itemId: this.itemId }) : '', index.h("div", { class: `s-comments-header ${this.total ? "has-total" : ""}` }, !!this.total && index.h("span", { class: "s-comments-count-label", innerHTML: this.pluralize(this.comment_name, this.total) }), !!this.total && !this.testimonials && this.type !== CommentType.BLOG ?
            index.h("div", { class: "s-comments-filter-wrapper" }, index.h("label", { class: "s-comments-filter-label", htmlFor: "comments-filter" }, salla.lang.get('pages.categories.sorting')), index.h("select", { id: "comments-filter", "aria-label": salla.lang.get('pages.categories.sorting'), class: "s-form-control s-comments-sort-input", onChange: (e) => {
                    this.sort = e.target.value;
                    this.reload();
                } }, index.h("option", { value: "latest", selected: true }, salla.lang.get("pages.testimonials.sort_by_date_desc")), index.h("option", { value: "oldest" }, salla.lang.get("pages.testimonials.sort_by_date_asc")), this.allowLikes && index.h("option", { value: "most_helpful" }, this.mostHelpfulLabel)))
            : ''), index.h("div", { ref: wrapper => {
                this.wrapper = wrapper;
            } }), this.nextPage && (index.h("div", { class: "s-infinite-scroll-wrapper", ref: status => {
                this.status = status;
            } }, index.h("button", { onClick: () => this.loadMore(), class: "s-infinite-scroll-btn s-button-btn s-button-primary", type: "button" }, index.h("span", { class: "s-button-text s-infinite-scroll-btn-text" }, this.loadMoreText ? this.loadMoreText : salla.lang.get('common.elements.load_more')), index.h("span", { class: "s-button-loader s-button-loader-center s-infinite-scroll-btn-loader", ref: btnLoader => {
                this.btnLoader = btnLoader;
            }, style: { "display": "none" } })))))));
    }
    get host() { return index.getElement(this); }
};
SallaComments.style = sallaCommentsCss;

const sallaRatingStarsCss = "";

const SallaRatingStars = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.translationsLoaded = false;
        this.labels = [];
        this.reviewLabel = '';
        this.selectedStar = 0;
        /**
       * Sets input name.
       */
        this.name = 'rating';
        /**
        * Sets the height and width of the component. Defaults to medium.
        */
        this.size = 'medium';
        /**
       * Number of reviews to display.
       */
        this.reviews = 0;
        /**
        * Allows the rating to be editable.
        */
        this.editable = false;
    }
    async componentWillLoad() {
        await new Promise(resolve => {
            salla.lang.onLoaded(() => {
                this.labels = [
                    salla.lang.get('pages.rating.poor'),
                    salla.lang.get('pages.rating.average'),
                    salla.lang.get('pages.rating.good'),
                    salla.lang.get('pages.rating.very_good'),
                    salla.lang.get('pages.rating.excellent')
                ];
                if (this.value && this.withLabel) {
                    this.reviewLabel = this.labels[this.value - 1];
                }
                if (this.reviewsElement) {
                    this.reviewsElement.innerText = `(${salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.reviews))})`;
                }
                this.translationsLoaded = true;
                resolve();
            });
        });
    }
    initiateRating() {
        this.host.addEventListener('click', this.handleRating.bind(this));
    }
    handleRating() {
        if (!this.starsElem)
            return;
        let activeStars = this.starsElem.querySelectorAll('.s-rating-stars-hovered');
        let selected = activeStars[activeStars.length - 1];
        if (!selected)
            return;
        let selectedIndex = parseInt(selected.getAttribute('data-star'));
        this.starsElem.querySelector('.rating_hidden_input').value = selectedIndex.toString();
        this.starsElem.querySelectorAll('.s-rating-stars-btn-star')
            .forEach((star, index) => Helper.Helper.toggleElementClassIf(star, 's-rating-stars-selected', 's-rating-stars-unselected', () => index < selectedIndex));
        this.starsElem.querySelectorAll('[aria-pressed]').forEach(star => star.removeAttribute('aria-pressed'));
        selected.setAttribute('aria-pressed', 'true');
        this.selectedStar = selectedIndex;
        this.withLabel && (this.reviewLabel = this.labels[selectedIndex - 1]);
    }
    triggerRatingProgrammatically(index) {
        if (!this.starsElem)
            return;
        const stars = this.starsElem.querySelectorAll('.s-rating-stars-btn-star');
        if (stars && index >= 0 && index <= stars.length) {
            // Simulate the hovering effect
            stars.forEach((s, i) => {
                s.classList.toggle('s-rating-stars-hovered', i <= index);
            });
            // Trigger the same logic as clicking
            this.handleRating();
        }
    }
    highlightSelectedStars() {
        let hoveredClass = 's-rating-stars-hovered', stars = this.starsElem?.querySelectorAll('.s-rating-stars-btn-star');
        stars?.forEach((star, index) => {
            star.addEventListener('mouseover', () => {
                for (let i = 0; i <= index; i++) {
                    stars[i].classList.add(hoveredClass);
                }
                this.withLabel && (this.reviewLabel = this.labels[index]);
            });
            star.addEventListener('mouseout', () => {
                star.classList.remove(hoveredClass);
                this.withLabel && (this.reviewLabel = this.selectedStar ? this.labels[this.selectedStar - 1] : '');
            });
        });
        this.starsElem?.addEventListener('mouseout', () => stars.forEach(star => star.classList.remove(hoveredClass)));
    }
    createStars(n) {
        let stars = [];
        for (let i = 0; i < 5; i++) {
            stars.push(index.h("span", { class: {
                    's-rating-stars-btn-star': true,
                    ['s-rating-stars-' + this.size]: true,
                    's-rating-stars-selected': i < n
                }, innerHTML: star2.Star }));
        }
        if (this.reviews > 0) {
            stars.push(index.h("span", { class: "s-rating-stars-reviews", ref: el => this.reviewsElement = el }, "(", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.reviews)), ")"));
        }
        return stars;
    }
    render() {
        return this.translationsLoaded ? (this.host.closest('.swiper-slide')?.classList.contains('swiper-slide-duplicate')
            ? ''
            : (index.h(index.Host, null, (this.value || this.value == 0) && !this.editable ?
                index.h("div", { class: "s-rating-stars-wrapper" }, this.createStars(this.value), this.withLabel && this.reviewLabel ? index.h("span", { class: "s-rating-stars-label" }, this.reviewLabel) : '')
                :
                    index.h("div", { class: "s-rating-stars-wrapper" }, index.h("div", { class: "s-rating-stars-element", ref: (el) => this.starsElem = el }, index.h("input", { type: "hidden", class: "rating_hidden_input", name: this.name, value: "" }), [1, 2, 3, 4, 5].map(star => index.h("button", { class: `s-rating-stars-btn-star s-rating-stars-` + this.size, "data-star": star }, index.h("span", { innerHTML: star2.Star })))), this.withLabel && this.reviewLabel ? index.h("span", { class: "s-rating-stars-label" }, this.reviewLabel) : '')))) : (index.h(index.Host, null));
    }
    componentDidLoad() {
        this.initiateRating();
        this.highlightSelectedStars();
        if (this.value && this.editable) {
            const stars = this.starsElem?.querySelectorAll('.s-rating-stars-btn-star');
            if (stars && this.value >= 0 && this.value <= stars.length) {
                this.triggerRatingProgrammatically(this.value - 1);
            }
        }
    }
    get host() { return index.getElement(this); }
};
SallaRatingStars.style = sallaRatingStarsCss;

var IconStar2 = ` <svg width="18" height="17" view-box="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M9.00045 13.6951L3.71036 16.6563L4.89186 10.71L0.440918 6.59397L6.4612 5.88017L9.00045 0.375122L11.5396 5.88017L17.5599 6.59397L13.109 10.71L14.2905 16.6563L9.00045 13.6951Z" fill="currentcolor" />
</svg>`;

var IconStar2Muted = ` <svg width="18" height="17" view-box="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M9.00045 13.6951L3.71036 16.6563L4.89186 10.71L0.440918 6.59397L6.4612 5.88017L9.00045 0.375122L11.5396 5.88017L17.5599 6.59397L13.109 10.71L14.2905 16.6563L9.00045 13.6951Z" fill="#DDDDDD" />
</svg>`;

var IconFire2 = `  <svg width="12" height="17" view-box="0 0 12 17" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M6 16.2501C9.10658 16.2501 11.625 13.7317 11.625 10.6251C11.625 9.976 11.4523 9.35252 11.25 8.77232C9.99998 10.0075 9.05002 10.6251 8.4 10.6251C11.3966 5.37512 9.75 3.12512 5.25 0.125122C5.625 3.87475 3.15302 5.58043 2.14634 6.52757C1.0559 7.5535 0.375 9.00977 0.375 10.6251C0.375 13.7317 2.89339 16.2501 6 16.2501ZM6.53205 2.92636C8.96333 4.98908 8.97495 6.59185 7.09725 9.88157C6.5265 10.8815 7.2486 12.1251 8.4 12.1251C8.9163 12.1251 9.43807 11.9745 9.98917 11.6789C9.52342 13.4466 7.91393 14.7501 6 14.7501C3.72182 14.7501 1.875 12.9033 1.875 10.6251C1.875 9.47072 2.34959 8.39582 3.17419 7.62002C3.2687 7.53115 3.74812 7.1062 3.76858 7.08782C4.08646 6.8017 4.34835 6.54985 4.60718 6.2727C5.52998 5.28461 6.19283 4.18735 6.53205 2.92636Z" fill="currentcolor" />
    </svg>`;

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

const SallaReviewCard = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.currentSlide = 0;
        this.showPurchaseCount = false;
        this.startPoint = { x: 0, y: 0 };
        this.isSwiping = false;
        this.isRTL = "rtl";
        this.handlePointerDown = (e) => {
            // Only handle primary pointer (first touch/mouse)
            if (!e.isPrimary)
                return;
            this.sliderElement?.setPointerCapture(e.pointerId);
            this.startSwipe(e.clientX, e.clientY);
            e.preventDefault();
        };
        this.handlePointerMove = (e) => {
            if (!this.isSwiping || !e.isPrimary)
                return;
            e.preventDefault();
        };
        this.handlePointerUp = (e) => {
            if (!this.isSwiping || !e.isPrimary)
                return;
            this.sliderElement?.releasePointerCapture(e.pointerId);
            this.endSwipe(e.clientX, e.clientY);
        };
        this.handlePointerCancel = (e) => {
            if (!this.isSwiping || !e.isPrimary)
                return;
            this.sliderElement?.releasePointerCapture(e.pointerId);
            this.isSwiping = false;
        };
        this.goToSlide = (index) => {
            this.currentSlide = Math.max(0, Math.min(index, this.images.length - 1));
        };
    }
    async componentDidLoad() {
        await salla.onReady();
        this.showPurchaseCount = !!salla.config.get('store.settings.product.total_sold_enabled', false);
        this.isRTL = salla.config.get('theme.is_rtl', true);
        this.purchasedCount = salla.lang.getWithDefault('blocks.home.reviews.purchased_count', this.isRTL ? ` تم شراءه ${this.review.product?.sold_quantity} مرة`
            : `Purchased ${this.review.product.sold_quantity} times`, { count: this.review.product?.sold_quantity });
        this.initializeSlider();
    }
    disconnectedCallback() {
        this.removeEventListeners();
    }
    get images() {
        const { review } = this;
        return review?.images?.length > 1
            ? review.images.map((image, idx) => ({ url: image, alt: '', id: idx }))
            : review?.product?.images || [];
    }
    get hasMultipleImages() {
        return this.images.length > 1;
    }
    get slideTransform() {
        const direction = this.isRTL ? 1 : -1;
        return `translateX(${this.currentSlide * 100 * direction}%)`;
    }
    initializeSlider() {
        if (!this.hasMultipleImages)
            return;
        this.sliderElement = this.el.querySelector(".s-review-card-slider-container");
        if (!this.sliderElement)
            return;
        // Enable pointer events and set touch-action
        this.sliderElement.style.touchAction = 'pan-y pinch-zoom';
        this.addEventListeners();
    }
    addEventListeners() {
        if (!this.sliderElement)
            return;
        this.sliderElement.addEventListener("pointerdown", this.handlePointerDown, { passive: false });
        this.sliderElement.addEventListener("pointermove", this.handlePointerMove, { passive: false });
        this.sliderElement.addEventListener("pointerup", this.handlePointerUp, { passive: true });
        this.sliderElement.addEventListener("pointercancel", this.handlePointerCancel, { passive: true });
    }
    removeEventListeners() {
        if (!this.sliderElement)
            return;
        this.sliderElement.removeEventListener("pointerdown", this.handlePointerDown);
        this.sliderElement.removeEventListener("pointermove", this.handlePointerMove);
        this.sliderElement.removeEventListener("pointerup", this.handlePointerUp);
        this.sliderElement.removeEventListener("pointercancel", this.handlePointerCancel);
    }
    startSwipe(x, y) {
        this.startPoint = { x, y };
        this.isSwiping = true;
    }
    componentDidRender() {
        this.removeEventListeners();
        this.addEventListeners();
    }
    endSwipe(x, y) {
        this.isSwiping = false;
        const dx = x - this.startPoint.x;
        const dy = y - this.startPoint.y;
        this.processSwipe(dx, dy);
    }
    processSwipe(dx, dy) {
        const MIN_SWIPE_DISTANCE = 10;
        if (Math.abs(dx) < MIN_SWIPE_DISTANCE || Math.abs(dy) > Math.abs(dx))
            return;
        const isLeftSwipe = dx < 0;
        const shouldGoNext = this.isRTL ? !isLeftSwipe : isLeftSwipe;
        if (shouldGoNext) {
            this.goToNextSlide();
        }
        else {
            this.goToPrevSlide();
        }
    }
    goToNextSlide() {
        if (this.currentSlide < this.images.length - 1) {
            this.currentSlide++;
        }
    }
    goToPrevSlide() {
        if (this.currentSlide > 0) {
            this.currentSlide--;
        }
    }
    renderStars() {
        return Array(5)
            .fill(null)
            .map((_, index$1) => index.h("span", { key: index$1, innerHTML: this.review.stars >= index$1 + 1 ? IconStar2 : IconStar2Muted }));
    }
    renderDots() {
        return this.images.map(({ url }, index$1) => (index.h("button", { key: url || index$1, type: "button", class: `s-review-card-slider-dot ${this.currentSlide === index$1 ? "active" : ""}`, onClick: () => this.goToSlide(index$1), "aria-label": `Go to slide ${index$1 + 1}`, onPointerDown: () => this.goToSlide(index$1) })));
    }
    renderSlider() {
        if (!this.hasMultipleImages)
            return null;
        return (index.h("div", { class: "s-review-card-slider-container" }, index.h("div", { class: "s-review-card-slides", style: { transform: this.slideTransform } }, this.images.map((image) => (index.h("div", { key: image?.id, class: "s-review-card-slider-slide" }, index.h("img", { src: image.url, alt: image.alt || "Product image", width: 275, height: 275, loading: "lazy", draggable: false }))))), index.h("div", { class: "s-review-card-slider-dots" }, this.renderDots())));
    }
    renderSingleImage() {
        const image = this.review?.product?.image;
        if (!image || this.hasMultipleImages)
            return null;
        return (index.h("img", { src: image.url, alt: image.alt || "Product image", class: "s-review-card-image", width: 275, height: 275, loading: "lazy", decoding: "async", draggable: false }));
    }
    renderHeader() {
        return (index.h("div", { class: "s-review-card-header" }, index.h("div", { class: "s-review-card-reviewer-name" }, index.h("p", null, this.review?.name), this.review?.has_order && index.h("span", { class: "s-review-card-verified-icon", innerHTML: check.SICheck })), index.h("div", { class: "s-review-card-stars" }, this.renderStars())));
    }
    renderProductInfo() {
        const product = this.review?.product;
        if (!product)
            return null;
        return (index.h("a", { href: this.review?.product?.url, class: "s-review-card-product-container" }, index.h("img", { alt: product.image?.alt || "Product", src: product.image?.url, class: "s-review-card-product-image", width: 60, height: 60, loading: "lazy", decoding: "async", draggable: false }), index.h("div", { class: "s-review-card-product-details" }, index.h("p", { class: "s-review-card-product-details-name" }, product.name), this.showPurchaseCount ? index.h("p", { class: "s-review-card-product-details-purchase-count" }, index.h("span", { innerHTML: IconFire2 }), this.purchasedCount) : null)));
    }
    render() {
        return index.h("div", { key: '47efb35fefb0c57657c2e8f6707d4821f6c1c1a0', class: "s-review-card-container" }, this.renderSlider(), this.renderSingleImage(), renderDivider(), index.h("div", { key: 'eb624b4a9aa51b9053a5824818490dcf91594489', class: "s-review-card-content" }, this.renderHeader(), index.h("p", { key: 'f7bc3da7f0ef59c08789942d76e309e0d07a161a', class: "s-review-card-review-content", innerHTML: this.review?.content }), renderDivider(), this.renderProductInfo()));
    }
    get el() { return index.getElement(this); }
};
const renderDivider = (className) => (index.h("div", { class: `s-review-card-divider ${""}` }));
SallaReviewCard.style = sallaReviewCardCss;

var IconQuoteOpen = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>quote-open</title>
<path d="M8 12v-5.333c0-0.737-0.596-1.333-1.333-1.333-3.676 0-6.667 2.991-6.667 6.667v8c0 3.676 2.991 6.667 6.667 6.667h1.333c3.676 0 6.667-2.991 6.667-6.667v-1.333c0-3.676-2.991-6.667-6.667-6.667zM12 20c0 2.205-1.795 4-4 4h-1.333c-2.205 0-4-1.795-4-4v-8c0-1.739 1.115-3.221 2.667-3.772v5.105c0 0.737 0.596 1.333 1.333 1.333h1.333c2.205 0 4 1.795 4 4zM25.333 12v-5.333c0-0.737-0.596-1.333-1.333-1.333-3.676 0-6.667 2.991-6.667 6.667v8c0 3.676 2.991 6.667 6.667 6.667h1.333c3.676 0 6.667-2.991 6.667-6.667v-1.333c0-3.676-2.991-6.667-6.667-6.667zM29.333 20c0 2.205-1.795 4-4 4h-1.333c-2.205 0-4-1.795-4-4v-8c0-1.739 1.115-3.221 2.667-3.772v5.105c0 0.737 0.596 1.333 1.333 1.333h1.333c2.205 0 4 1.795 4 4z"></path>
</svg>
`;

const sallaReviewsCss = "";

const SallaReviews = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        /**
         * Defines the maximum number of reviews to retrieve from the API.
         *
         * @type {number}
         * @default 5
         */
        this.limit = 5;
        /**
         * Specifies the type of reviews to fetch.
         * Available options:
         * - "all": Fetches reviews from all sources.
         * - "store": Fetches reviews specific to the store.
         * - "products": Fetches reviews specific to products.
         *
         * @type {ReviewType}
         * @default store
         */
        this.type = "store";
        /**
         * Specifies the sorting criteria for the fetched reviews.
         * Available options:
         * - "top_rating": Sorts reviews based on top ratings.
         * - "random": Sorts reviews randomly.
         * - "latest": Sorts reviews based on the latest ones (default).
         *
         * @type {SortingOption}
         * @default latest
         */
        this.sort = "latest";
        /**
         * Specifies whether to hide customer information in the component.
         * When set to true, customer information will be hidden.
         * Defaults to false, meaning customer information will be displayed.
         */
        this.hideCustomerInfo = false;
        this.reviews = [];
        this.showReviews = false;
        this.testimonialText = salla.lang.get('blocks.home.testimonials');
        this.displayAllLinkText = salla.lang.get('blocks.home.display_all');
        this.displayAllURL = null;
        this.source = this.source;
        salla.onReady(() => {
            this.displayAllURL = salla.url.get('testimonials');
            this.isRTL = salla.config.get('theme.is_rtl', true);
        });
        salla.lang.onLoaded(() => {
            this.testimonialText = salla.lang.get('blocks.home.testimonials');
            this.displayAllLinkText = salla.lang.get('blocks.home.display_all');
        });
    }
    fetchReviews() {
        if (this.source === 'json') {
            return Promise.resolve(JSON.parse(this.sourceValue));
        }
        const isJsonEncoded = ['products', 'categories'].includes(this.source);
        const params = {
            limit: this.limit,
            source: this.source,
            items: isJsonEncoded ? JSON.parse(this.sourceValue) : this.sourceValue,
            sort: this.sort,
            type: this.type,
            hide_customer_info: this.hideCustomerInfo ? 1 : 0
        };
        return salla.api.request('reviews', { params }, 'get');
    }
    componentWillLoad() {
        return (new Promise(resolve => salla.onReady(resolve)))
            .then(() => this.fetchReviews())
            .then((resp) => resp.data || [])
            .then(reviews => {
            if (reviews.length) {
                this.reviews = reviews;
                this.showReviews = true;
                Helper.Helper.generateReviewSchema(this.reviews);
            }
        });
    }
    render() {
        return (index.h("div", { key: 'a714c729b160349bb72976bc0b9910c2ddfee5bb', class: "s-reviews-container" }, index.h("div", { key: '5aadfe6203a6bfc70bd242914ad63de05b374a22', class: "s-reviews-header-wrapper" }, index.h("h1", { key: 'a7dcdfbb38a9eb069f8b3c46d065638b659fb891', class: "s-reviews-header" }, this.testimonialText), !!this.displayAllLink ? (index.h("a", { href: this.displayAllURL, class: "s-reviews-display-all" }, this.displayAllLinkText, index.h("span", { class: "s-reviews-display-all-icon", innerHTML: arrowLeft.arrowLeft }))) : null), index.h("salla-slider", { key: 'cbb4ae4e75bbef6d5716287d096863de9631a3e2', centered: true, "slides-per-view": 1, type: "testimonials", class: "s-reviews-testimonials-slider", "controls-outer": true, "auto-play": true, id: `testimonials-${this.source}-slider` }, index.h("div", { key: '78ca0d0848ccba77a926b3142954d1a5ffe99a9b', slot: "items" }, this.reviews.map((item, index$1) => (index.h("div", { key: index$1, class: "s-reviews-swiper-slide" }, index.h("div", { class: "s-reviews-testimonial" }, index.h("div", { class: "s-reviews-testimonial__inner" }, index.h("div", { class: "s-reviews-testimonial__avatar" }, index.h("img", { src: 'images/s-empty.png', "data-src": item.avatar, alt: item.name ? item.name : 'testimonial-' + index$1, class: "lazy" })), index.h("div", { class: "s-reviews-testimonial__text" }, index.h("p", { innerHTML: item.content }), index.h("div", { class: "s-reviews-testimonial__name_wrapper" }, index.h("div", { class: "s-reviews-testimonial__info" }, item.name && index.h("h2", null, `${item.name}`)), index.h("div", { class: "s-reviews-testimonial__rating" }, index.h("salla-rating-stars", { size: "small", value: item.stars })))), index.h("span", { class: "s-reviews-testimonial__icon", innerHTML: IconQuoteOpen }))))))))));
    }
};
SallaReviews.style = sallaReviewsCss;

var now_1;
var hasRequiredNow;

function requireNow () {
	if (hasRequiredNow) return now_1;
	hasRequiredNow = 1;
	var root = index.require_root();

	/**
	 * Gets the timestamp of the number of milliseconds that have elapsed since
	 * the Unix epoch (1 January 1970 00:00:00 UTC).
	 *
	 * @static
	 * @memberOf _
	 * @since 2.4.0
	 * @category Date
	 * @returns {number} Returns the timestamp.
	 * @example
	 *
	 * _.defer(function(stamp) {
	 *   console.log(_.now() - stamp);
	 * }, _.now());
	 * // => Logs the number of milliseconds it took for the deferred invocation.
	 */
	var now = function() {
	  return root.Date.now();
	};

	now_1 = now;
	return now_1;
}

/** Used to match a single whitespace character. */

var _trimmedEndIndex;
var hasRequired_trimmedEndIndex;

function require_trimmedEndIndex () {
	if (hasRequired_trimmedEndIndex) return _trimmedEndIndex;
	hasRequired_trimmedEndIndex = 1;
	var reWhitespace = /\s/;

	/**
	 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
	 * character of `string`.
	 *
	 * @private
	 * @param {string} string The string to inspect.
	 * @returns {number} Returns the index of the last non-whitespace character.
	 */
	function trimmedEndIndex(string) {
	  var index = string.length;

	  while (index-- && reWhitespace.test(string.charAt(index))) {}
	  return index;
	}

	_trimmedEndIndex = trimmedEndIndex;
	return _trimmedEndIndex;
}

var _baseTrim;
var hasRequired_baseTrim;

function require_baseTrim () {
	if (hasRequired_baseTrim) return _baseTrim;
	hasRequired_baseTrim = 1;
	var trimmedEndIndex = require_trimmedEndIndex();

	/** Used to match leading whitespace. */
	var reTrimStart = /^\s+/;

	/**
	 * The base implementation of `_.trim`.
	 *
	 * @private
	 * @param {string} string The string to trim.
	 * @returns {string} Returns the trimmed string.
	 */
	function baseTrim(string) {
	  return string
	    ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
	    : string;
	}

	_baseTrim = baseTrim;
	return _baseTrim;
}

var toNumber_1;
var hasRequiredToNumber;

function requireToNumber () {
	if (hasRequiredToNumber) return toNumber_1;
	hasRequiredToNumber = 1;
	var baseTrim = require_baseTrim(),
	    isObject = index.requireIsObject(),
	    isSymbol = index.requireIsSymbol();

	/** Used as references for various `Number` constants. */
	var NAN = 0 / 0;

	/** Used to detect bad signed hexadecimal string values. */
	var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

	/** Used to detect binary string values. */
	var reIsBinary = /^0b[01]+$/i;

	/** Used to detect octal string values. */
	var reIsOctal = /^0o[0-7]+$/i;

	/** Built-in method references without a dependency on `root`. */
	var freeParseInt = parseInt;

	/**
	 * Converts `value` to a number.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to process.
	 * @returns {number} Returns the number.
	 * @example
	 *
	 * _.toNumber(3.2);
	 * // => 3.2
	 *
	 * _.toNumber(Number.MIN_VALUE);
	 * // => 5e-324
	 *
	 * _.toNumber(Infinity);
	 * // => Infinity
	 *
	 * _.toNumber('3.2');
	 * // => 3.2
	 */
	function toNumber(value) {
	  if (typeof value == 'number') {
	    return value;
	  }
	  if (isSymbol(value)) {
	    return NAN;
	  }
	  if (isObject(value)) {
	    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
	    value = isObject(other) ? (other + '') : other;
	  }
	  if (typeof value != 'string') {
	    return value === 0 ? value : +value;
	  }
	  value = baseTrim(value);
	  var isBinary = reIsBinary.test(value);
	  return (isBinary || reIsOctal.test(value))
	    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
	    : (reIsBadHex.test(value) ? NAN : +value);
	}

	toNumber_1 = toNumber;
	return toNumber_1;
}

var debounce_1;
var hasRequiredDebounce;

function requireDebounce () {
	if (hasRequiredDebounce) return debounce_1;
	hasRequiredDebounce = 1;
	var isObject = index.requireIsObject(),
	    now = requireNow(),
	    toNumber = requireToNumber();

	/** Error message constants. */
	var FUNC_ERROR_TEXT = 'Expected a function';

	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeMax = Math.max,
	    nativeMin = Math.min;

	/**
	 * Creates a debounced function that delays invoking `func` until after `wait`
	 * milliseconds have elapsed since the last time the debounced function was
	 * invoked. The debounced function comes with a `cancel` method to cancel
	 * delayed `func` invocations and a `flush` method to immediately invoke them.
	 * Provide `options` to indicate whether `func` should be invoked on the
	 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
	 * with the last arguments provided to the debounced function. Subsequent
	 * calls to the debounced function return the result of the last `func`
	 * invocation.
	 *
	 * **Note:** If `leading` and `trailing` options are `true`, `func` is
	 * invoked on the trailing edge of the timeout only if the debounced function
	 * is invoked more than once during the `wait` timeout.
	 *
	 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	 *
	 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	 * for details over the differences between `_.debounce` and `_.throttle`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Function
	 * @param {Function} func The function to debounce.
	 * @param {number} [wait=0] The number of milliseconds to delay.
	 * @param {Object} [options={}] The options object.
	 * @param {boolean} [options.leading=false]
	 *  Specify invoking on the leading edge of the timeout.
	 * @param {number} [options.maxWait]
	 *  The maximum time `func` is allowed to be delayed before it's invoked.
	 * @param {boolean} [options.trailing=true]
	 *  Specify invoking on the trailing edge of the timeout.
	 * @returns {Function} Returns the new debounced function.
	 * @example
	 *
	 * // Avoid costly calculations while the window size is in flux.
	 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
	 *
	 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
	 * jQuery(element).on('click', _.debounce(sendMail, 300, {
	 *   'leading': true,
	 *   'trailing': false
	 * }));
	 *
	 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
	 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
	 * var source = new EventSource('/stream');
	 * jQuery(source).on('message', debounced);
	 *
	 * // Cancel the trailing debounced invocation.
	 * jQuery(window).on('popstate', debounced.cancel);
	 */
	function debounce(func, wait, options) {
	  var lastArgs,
	      lastThis,
	      maxWait,
	      result,
	      timerId,
	      lastCallTime,
	      lastInvokeTime = 0,
	      leading = false,
	      maxing = false,
	      trailing = true;

	  if (typeof func != 'function') {
	    throw new TypeError(FUNC_ERROR_TEXT);
	  }
	  wait = toNumber(wait) || 0;
	  if (isObject(options)) {
	    leading = !!options.leading;
	    maxing = 'maxWait' in options;
	    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
	    trailing = 'trailing' in options ? !!options.trailing : trailing;
	  }

	  function invokeFunc(time) {
	    var args = lastArgs,
	        thisArg = lastThis;

	    lastArgs = lastThis = undefined;
	    lastInvokeTime = time;
	    result = func.apply(thisArg, args);
	    return result;
	  }

	  function leadingEdge(time) {
	    // Reset any `maxWait` timer.
	    lastInvokeTime = time;
	    // Start the timer for the trailing edge.
	    timerId = setTimeout(timerExpired, wait);
	    // Invoke the leading edge.
	    return leading ? invokeFunc(time) : result;
	  }

	  function remainingWait(time) {
	    var timeSinceLastCall = time - lastCallTime,
	        timeSinceLastInvoke = time - lastInvokeTime,
	        timeWaiting = wait - timeSinceLastCall;

	    return maxing
	      ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
	      : timeWaiting;
	  }

	  function shouldInvoke(time) {
	    var timeSinceLastCall = time - lastCallTime,
	        timeSinceLastInvoke = time - lastInvokeTime;

	    // Either this is the first call, activity has stopped and we're at the
	    // trailing edge, the system time has gone backwards and we're treating
	    // it as the trailing edge, or we've hit the `maxWait` limit.
	    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
	      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
	  }

	  function timerExpired() {
	    var time = now();
	    if (shouldInvoke(time)) {
	      return trailingEdge(time);
	    }
	    // Restart the timer.
	    timerId = setTimeout(timerExpired, remainingWait(time));
	  }

	  function trailingEdge(time) {
	    timerId = undefined;

	    // Only invoke if we have `lastArgs` which means `func` has been
	    // debounced at least once.
	    if (trailing && lastArgs) {
	      return invokeFunc(time);
	    }
	    lastArgs = lastThis = undefined;
	    return result;
	  }

	  function cancel() {
	    if (timerId !== undefined) {
	      clearTimeout(timerId);
	    }
	    lastInvokeTime = 0;
	    lastArgs = lastCallTime = lastThis = timerId = undefined;
	  }

	  function flush() {
	    return timerId === undefined ? result : trailingEdge(now());
	  }

	  function debounced() {
	    var time = now(),
	        isInvoking = shouldInvoke(time);

	    lastArgs = arguments;
	    lastThis = this;
	    lastCallTime = time;

	    if (isInvoking) {
	      if (timerId === undefined) {
	        return leadingEdge(lastCallTime);
	      }
	      if (maxing) {
	        // Handle invocations in a tight loop.
	        clearTimeout(timerId);
	        timerId = setTimeout(timerExpired, wait);
	        return invokeFunc(lastCallTime);
	      }
	    }
	    if (timerId === undefined) {
	      timerId = setTimeout(timerExpired, wait);
	    }
	    return result;
	  }
	  debounced.cancel = cancel;
	  debounced.flush = flush;
	  return debounced;
	}

	debounce_1 = debounce;
	return debounce_1;
}

var throttle_1;
var hasRequiredThrottle;

function requireThrottle () {
	if (hasRequiredThrottle) return throttle_1;
	hasRequiredThrottle = 1;
	var debounce = requireDebounce(),
	    isObject = index.requireIsObject();

	/** Error message constants. */
	var FUNC_ERROR_TEXT = 'Expected a function';

	/**
	 * Creates a throttled function that only invokes `func` at most once per
	 * every `wait` milliseconds. The throttled function comes with a `cancel`
	 * method to cancel delayed `func` invocations and a `flush` method to
	 * immediately invoke them. Provide `options` to indicate whether `func`
	 * should be invoked on the leading and/or trailing edge of the `wait`
	 * timeout. The `func` is invoked with the last arguments provided to the
	 * throttled function. Subsequent calls to the throttled function return the
	 * result of the last `func` invocation.
	 *
	 * **Note:** If `leading` and `trailing` options are `true`, `func` is
	 * invoked on the trailing edge of the timeout only if the throttled function
	 * is invoked more than once during the `wait` timeout.
	 *
	 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	 *
	 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	 * for details over the differences between `_.throttle` and `_.debounce`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Function
	 * @param {Function} func The function to throttle.
	 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
	 * @param {Object} [options={}] The options object.
	 * @param {boolean} [options.leading=true]
	 *  Specify invoking on the leading edge of the timeout.
	 * @param {boolean} [options.trailing=true]
	 *  Specify invoking on the trailing edge of the timeout.
	 * @returns {Function} Returns the new throttled function.
	 * @example
	 *
	 * // Avoid excessively updating the position while scrolling.
	 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
	 *
	 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
	 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
	 * jQuery(element).on('click', throttled);
	 *
	 * // Cancel the trailing throttled invocation.
	 * jQuery(window).on('popstate', throttled.cancel);
	 */
	function throttle(func, wait, options) {
	  var leading = true,
	      trailing = true;

	  if (typeof func != 'function') {
	    throw new TypeError(FUNC_ERROR_TEXT);
	  }
	  if (isObject(options)) {
	    leading = 'leading' in options ? !!options.leading : leading;
	    trailing = 'trailing' in options ? !!options.trailing : trailing;
	  }
	  return debounce(func, wait, {
	    'leading': leading,
	    'maxWait': wait,
	    'trailing': trailing
	  });
	}

	throttle_1 = throttle;
	return throttle_1;
}

var throttleExports = requireThrottle();
var throttle = /*@__PURE__*/index.getDefaultExportFromCjs(throttleExports);

class MasonryLayout {
    constructor(grid) {
        this.grid = grid;
        this.create = () => {
            this.mutationObserver.observe(this.grid, {
                childList: true,
            });
            for (const item of Array.from(this.grid.children)) {
                this.resizeObserver.observe(item);
            }
        };
        this.onContainerMutation = (mutations) => {
            const removedNodes = mutations.flatMap((mutation) => Array.from(mutation.removedNodes));
            const addedNodes = mutations.flatMap((mutation) => Array.from(mutation.addedNodes));
            for (const node of removedNodes) {
                if (node instanceof Element) {
                    this.resizeObserver.unobserve(node);
                }
            }
            for (const node of addedNodes) {
                if (node instanceof Element) {
                    this.resizeObserver.observe(node);
                }
            }
            if (removedNodes.length > 0 && addedNodes.length === 0) {
                this.update();
            }
        };
        this.onChildrenResize = (entries) => {
            const entriesToUpdate = entries.filter((entry) => entry.target.parentElement !== null);
            if (entriesToUpdate.length > 0) {
                this.update();
            }
        };
        this.update = throttle(() => {
            const computedStyle = window.getComputedStyle(this.grid);
            if (computedStyle.getPropertyValue("display").includes("grid") === false) {
                this.clean();
                return;
            }
            const columns = parseGridTemplateColumns(this.grid);
            if (columns.length <= 1) {
                this.clean();
                return;
            }
            const rowGap = Number.parseFloat(computedStyle.getPropertyValue("row-gap").trim()) || 0;
            const items = Array.from(this.grid.children);
            for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
                const firstItemInColumn = items[columnIndex];
                firstItemInColumn?.style.removeProperty("margin-top");
            }
            for (let index = 0; index < items.length; index++) {
                const prevItem = items[index - columns.length];
                const nextItem = items[index];
                if (prevItem !== undefined && nextItem !== undefined) {
                    const prevBottom = prevItem.getBoundingClientRect().bottom;
                    nextItem.style.removeProperty("margin-top");
                    const nextTop = nextItem.getBoundingClientRect().top;
                    if (nextTop - rowGap !== prevBottom) {
                        const margin = Math.round((prevBottom - (nextTop - rowGap) + Number.EPSILON) * 100) / 100;
                        nextItem.style.setProperty("margin-top", `${margin}px`);
                    }
                }
            }
        }, 32);
        this.destroy = () => {
            this.resizeObserver.disconnect();
            this.mutationObserver.disconnect();
            this.clean();
        };
        this.clean = () => {
            for (const item of Array.from(this.grid.children)) {
                item.style.removeProperty("margin-top");
            }
        };
        this.mutationObserver = new MutationObserver(this.onContainerMutation);
        this.resizeObserver = new ResizeObserver(this.onChildrenResize);
        if (CSS.supports("grid-template-rows", "masonry") === false) {
            this.create();
        }
    }
    [Symbol.dispose]() {
        this.destroy();
    }
}
function parseGridTemplateColumns(grid) {
    const computedStyle = window.getComputedStyle(grid);
    const gridTemplateColumns = computedStyle.getPropertyValue("grid-template-columns");
    return gridTemplateColumns
        .trim()
        .split(/\s+(?=(?:[^()]*\([^()]*\))*[^()]*$)/);
}

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

const SallaReviewsPage = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.reviews = [];
        this.isLoading = false;
        this.pagination = null;
        this.sort = "latest";
    }
    getUrlParams() {
        const params = new URLSearchParams(window.location.search);
        return {
            sort: params.get('sort') || null,
            page: Number.parseInt(params.get('page')) || 1
        };
    }
    updateUrlParams(params) {
        const url = new URL(window.location.href);
        for (const [key, value] of Object.entries(params)) {
            if (value) {
                url.searchParams.set(key, value.toString());
            }
            else {
                url.searchParams.delete(key);
            }
        }
        window.history.replaceState({}, '', url.toString());
    }
    fetchReviews(sort, page) {
        const urlParams = this.getUrlParams();
        return salla.api.request('reviews', {
            params: {
                type: 'products',
                format: 'lite',
                per_page: 8,
                page: page || urlParams.page || 1,
                sort: sort || urlParams.sort || null
            }
        });
    }
    async initializeMasonry() {
        const grid = this.el.querySelector('.s-reviews-page-grid');
        if (!grid)
            return;
        try {
            new MasonryLayout(grid);
            salla.logger.info('Masonry initialized successfully');
        }
        catch (error) {
            salla.logger.error('Masonry initialization failed:', error);
        }
    }
    animateReviewCards() {
        const items = this.wrapper.querySelectorAll('salla-review-card:not(.animated)');
        Helper.Helper.animateItems(items);
    }
    initiateInfiniteScroll() {
        if (!this.wrapper) {
            salla.logger.error('Wrapper is undefined. Cannot initiate infinite scroll.');
            return;
        }
        this.infiniteScroll = salla.infiniteScroll.initiate(this.wrapper, this.wrapper, {
            path: () => this.pagination?.links?.next || null,
            history: false,
            scrollThreshold: false,
        }, true);
        this.infiniteScroll?.on('request', () => {
            this.isLoading = true;
        });
        this.infiniteScroll?.on('load', response => {
            this.pagination = response.pagination;
            this.reviews = [...this.reviews, ...response.data];
            this.isLoading = false;
            // Update URL with the current page
            this.updateUrlParams({ page: response.pagination.current_page });
        });
        this.infiniteScroll?.on('error', (e) => {
            salla.logger.error('Error loading more reviews:', e);
            this.isLoading = false;
        });
    }
    componentDidRender() {
        setTimeout(() => {
            requestAnimationFrame(this.animateReviewCards.bind(this));
        }, 176);
    }
    async componentWillLoad() {
        try {
            await salla.onReady();
            // Initialize language variables
            this.langTitlesReviews = salla.lang.get("common.titles.reviews");
            this.langSorting = salla.lang.get('pages.categories.sorting');
            this.placeholderText = salla.lang.choice("pages.rating.reviews", 0);
            this.langLoadMore = salla.lang.get('common.elements.load_more');
            this.langSortByTopRating = salla.lang.get('pages.testimonials.sort_by_rating_desc');
            this.langSortByMostRecent = salla.lang.get('pages.testimonials.sort_by_date_desc');
            this.langSortByLeastRated = salla.lang.get('pages.testimonials.sort_by_rating_asc');
            this.langSortByLeastRecent = salla.lang.get('pages.testimonials.sort_by_date_asc');
            const urlParams = this.getUrlParams();
            const response = await this.fetchReviews(urlParams.sort);
            this.sort = urlParams.sort;
            this.reviews = response.data;
            this.pagination = response.pagination;
            this.langRatingReviews = salla.lang.choice("pages.rating.reviews", this.pagination?.total);
        }
        catch (error) {
            salla.logger.error('Error loading reviews:', error);
        }
    }
    async handleSorting(e) {
        const value = e.target.value;
        this.sort = value;
        this.updateUrlParams({ sort: value, page: 1 }); // Reset to page 1 when changing sort
        const response = await this.fetchReviews(value, 1);
        this.reviews = response.data;
        this.pagination = response.pagination;
    }
    async componentDidLoad() {
        await this.initializeMasonry();
        this.initiateInfiniteScroll();
        this.sort = this.getUrlParams().sort || "latest";
        this.updateUrlParams({ sort: this.sort, page: 1 });
    }
    disconnectedCallback() {
        if (this.infiniteScroll) {
            this.infiniteScroll.destroy();
        }
    }
    renderSortingOptions() {
        const options = [
            { value: 'latest', label: this.langSortByMostRecent },
            { value: 'oldest', label: this.langSortByLeastRecent },
            { value: 'top_rating', label: this.langSortByTopRating },
            { value: 'bottom_rating', label: this.langSortByLeastRated },
        ];
        return options.map(option => (index.h("option", { key: option.value, value: option.value, selected: option.value === this.sort }, option.label)));
    }
    render() {
        return (index.h("host", { key: 'fcd0bc80f69825de03feab75422aef2dabcca93b' }, index.h("div", { key: '4d50dbde8eecf0a597717971dee990d01bae1f7c', class: "s-reviews-page-header-wrapper" }, index.h("h2", { key: 'ff2c3e971cb6c480ae6388308abaa40a90ccd1cd', class: "s-reviews-page-title" }, this.langTitlesReviews, index.h("span", { key: 'a8f550f07d5826d701036ca94c8535188cd29dc5', class: "s-reviews-page-count" }, "(", this.langRatingReviews, ")")), index.h("div", { key: 'a2e0465af025a4c695462a1ea223d7a554e582de', class: "s-reviews-page-filter-wrapper" }, index.h("label", { key: 'e333ae7128cb24e15d18dca25f6af3456f0648ec', class: "s-reviews-page-filter-label", htmlFor: "testimonials-filter" }, this.langSorting), index.h("select", { key: '7ed58196ce8319d3ff3d7f9f38f7ecdf371e4856', onChange: (e) => this.handleSorting(e), disabled: !this.reviews.length, class: "s-reviews-page-filter" }, this.renderSortingOptions()))), this.reviews.length ? index.h("main", { class: "s-reviews-page-grid", ref: el => {
                this.wrapper = el;
            } }, this.reviews.map(review => (index.h("salla-review-card", { key: review.id, review: review }))))
            : index.h("div", { class: "s-products-list-placeholder" }, index.h("span", { innerHTML: shoppingBag.ShoppingBag }), index.h("p", null, this.placeholderText)), this.pagination?.links?.next && this.reviews.length ? (index.h("div", { class: "s-reviews-page-load-more-container" }, index.h("salla-button", { class: "s-reviews-page-load-more-btn", loading: this.isLoading, onClick: () => this.infiniteScroll?.loadNextPage(), onKeyUp: () => this.infiniteScroll?.loadNextPage() }, this.langLoadMore))) : null));
    }
    get el() { return index.getElement(this); }
};
SallaReviewsPage.style = sallaReviewsPageCss;

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

const SallaReviewsSummary = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.canRender = false;
        this.showRatingSummary = false;
        this.recommendationOnly = false;
        this.showRecommendation = false;
    }
    async componentWillLoad() {
        try {
            await salla.onReady();
            this.initializeLanguages();
            this.loadConfig();
            // Only load data if component should be displayed
            if (this.showRatingSummary || this.showRecommendation) {
                await this.loadSummary();
            }
        }
        catch (error) {
            console.error('Failed to initialize reviews summary component:', error);
        }
    }
    async loadConfig() {
        this.showRatingSummary = salla.config.get('store.settings.rating.show_rating_summary');
        this.showRecommendation = salla.config.get('store.settings.rating.show_recommendation');
        this.recommendationOnly = this.showRecommendation && !this.showRatingSummary;
    }
    initializeLanguages() {
        return Salla.lang.onLoaded(() => {
            Salla.lang.addBulk({
                "blocks.comments.based_on": { ar: "بناءً على", en: "Based on" },
                "blocks.comments.recommended": { ar: "أوصوا بالمنتج", en: "Recommended" }
            });
            this.basedOnLabel = salla.lang.get('blocks.comments.based_on');
            this.recommendedLabel = salla.lang.get('blocks.comments.recommended');
        });
    }
    async loadSummary() {
        if (!this.itemId) {
            console.error('Error loading reviews summary: itemId is not defined');
            return this.canRender = false;
        }
        try {
            const response = (await salla.api.request(`rating/summary/${this.itemId}`));
            if (!response?.data || (Array.isArray(response.data.reviews) && !response.data.reviews.length)) {
                this.canRender = false;
                this.data = null;
                return;
            }
            this.data = response.data;
            this.canRender = true;
        }
        catch (error) {
            this.canRender = false;
            this.data = null;
            console.error('Error loading reviews summary:', error);
        }
    }
    renderRecommendation() {
        if (!this.showRecommendation || !this.data?.recommendation) {
            return null;
        }
        const classes = {
            base: 's-reviews-summary-header-section',
            standalone: this.recommendationOnly ? 's-reviews-summary-recommendation-only' : ''
        };
        return (index.h("div", { class: `${classes.base} ${classes.standalone}`.trim() }, index.h("h4", { class: "s-reviews-summary-recommendation-percentage" }, "%", this.data?.recommendation), index.h("p", { class: "s-reviews-summary-count" }, this.recommendedLabel)));
    }
    render() {
        if (!this.canRender)
            return null;
        if (this.recommendationOnly)
            return this.renderRecommendation();
        const ratings = {
            "1": 0,
            "2": 0,
            "3": 0,
            "4": 0,
            "5": 0,
            ...this.data.reviews
        };
        const reviewElements = Object.keys(ratings).reverse().map((rating) => {
            const percentage = ratings[rating];
            return (index.h("div", { key: rating, class: "s-reviews-summary-row" }, index.h("div", { class: "s-reviews-summary-row-rate" }, rating, " ", index.h("span", { innerHTML: star2.Star })), index.h("salla-progress-bar", { class: "s-reviews-summary-progress", value: percentage, target: 100, hideUnits: true, height: '16px' }), index.h("span", { class: "s-reviews-summary-percentage" }, percentage, "%")));
        });
        return (index.h(index.Host, { class: "s-reviews-summary-wrapper" }, index.h("div", { class: "s-reviews-summary-header" }, index.h("div", { class: "s-reviews-summary-header-section" }, index.h("h3", { class: "s-reviews-summary-average" }, this.data.rating), index.h("div", null, index.h("salla-rating-stars", { size: 'large', value: this.data.rating }), index.h("p", { class: "s-reviews-summary-count" }, this.basedOnLabel, " ", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.data.count))))), this.renderRecommendation()), index.h("div", { class: "s-reviews-summary-rows" }, reviewElements)));
    }
};
SallaReviewsSummary.style = sallaReviewsSummaryCss;

exports.salla_comment_form = SallaCommentForm;
exports.salla_comment_item = SallaCommentItem;
exports.salla_comments = SallaComments;
exports.salla_rating_stars = SallaRatingStars;
exports.salla_review_card = SallaReviewCard;
exports.salla_reviews = SallaReviews;
exports.salla_reviews_page = SallaReviewsPage;
exports.salla_reviews_summary = SallaReviewsSummary;
