/*!
 * Crafted with ❤ by Salla
 */
import { h } from "@stencil/core";
import { CommentType } from "./interfaces";
import anime from "animejs";
import Helper from "../../Helpers/Helper";
import ChatBubbles from "../../assets/svg/chat-bubbles.svg";
export class SallaComments {
    constructor() {
        /**
         * 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.toggleElementClassIf(btnText, 's-button-hide', 's-button-show', () => isLoading);
            this.btnLoader.style.display = isLoading ? 'inherit' : 'none';
        }
    }
    // Animate newly added items
    animateItems(items) {
        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 (h("div", null, !!this.total && !this.hideTitle ? h("h2", { class: "s-comments-title" }, this.blockTitle ? this.blockTitle : this.comment_title) : '', !this.hideForm && !this.testimonials ? h("salla-comment-form", { showAvatar: this.showFormAvatar, type: this.type, "item-id": this.itemId }) : '', h("div", { class: "s-comments-placeholder" }, h("span", { innerHTML: ChatBubbles }), h("p", null, this.noComments))));
        }
        return (h("div", { class: `s-comments s-comments-${this.testimonials ? 'testimonials' : this.type}` }, h("div", { class: `${this.type === CommentType.PAGE ? "s-comments-page-container" : "s-comments-container"}` }, !!this.total && !this.hideTitle ? h("h2", { class: "s-comments-title" }, this.blockTitle ? this.blockTitle : this.comment_title) : '', !this.hideForm && h("salla-comment-form", { showAvatar: this.showFormAvatar, type: this.type, "item-id": this.itemId }), salla.url.is_page('product.single') ? h("salla-reviews-summary", { itemId: this.itemId }) : '', h("div", { class: `s-comments-header ${this.total ? "has-total" : ""}` }, !!this.total && h("span", { class: "s-comments-count-label", innerHTML: this.pluralize(this.comment_name, this.total) }), !!this.total && !this.testimonials && this.type !== CommentType.BLOG ?
            h("div", { class: "s-comments-filter-wrapper" }, h("label", { class: "s-comments-filter-label", htmlFor: "comments-filter" }, salla.lang.get('pages.categories.sorting')), 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();
                } }, h("option", { value: "latest", selected: true }, salla.lang.get("pages.testimonials.sort_by_date_desc")), h("option", { value: "oldest" }, salla.lang.get("pages.testimonials.sort_by_date_asc")), this.allowLikes && h("option", { value: "most_helpful" }, this.mostHelpfulLabel)))
            : ''), h("div", { ref: wrapper => {
                this.wrapper = wrapper;
            } }), this.nextPage && (h("div", { class: "s-infinite-scroll-wrapper", ref: status => {
                this.status = status;
            } }, h("button", { onClick: () => this.loadMore(), class: "s-infinite-scroll-btn s-button-btn s-button-primary", type: "button" }, h("span", { class: "s-button-text s-infinite-scroll-btn-text" }, this.loadMoreText ? this.loadMoreText : salla.lang.get('common.elements.load_more')), h("span", { class: "s-button-loader s-button-loader-center s-infinite-scroll-btn-loader", ref: btnLoader => {
                this.btnLoader = btnLoader;
            }, style: { "display": "none" } })))))));
    }
    static get is() { return "salla-comments"; }
    static get originalStyleUrls() {
        return {
            "$": ["salla-comments.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["salla-comments.css"]
        };
    }
    static get properties() {
        return {
            "itemId": {
                "type": "number",
                "attribute": "item-id",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Page or product ID"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "loadMoreText": {
                "type": "string",
                "attribute": "load-more-text",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Load more text"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "hideForm": {
                "type": "boolean",
                "attribute": "hide-form",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Load more text"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "blockTitle": {
                "type": "string",
                "attribute": "block-title",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Block Title"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "hideTitle": {
                "type": "boolean",
                "attribute": "hide-title",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Hide Title"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "type": {
                "type": "string",
                "attribute": "type",
                "mutable": false,
                "complexType": {
                    "original": "CommentType.PAGE | CommentType.PRODUCT | CommentType.BLOG",
                    "resolved": "CommentType.BLOG | CommentType.PAGE | CommentType.PRODUCT",
                    "references": {
                        "CommentType": {
                            "location": "import",
                            "path": "./interfaces",
                            "id": "src/components/salla-comments/interfaces.ts::CommentType"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Comment Type"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "CommentType.PAGE"
            },
            "showFormAvatar": {
                "type": "boolean",
                "attribute": "show-form-avatar",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Show or hide avatar"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "hideBought": {
                "type": "boolean",
                "attribute": "hide-bought",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Hide Bought"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "sort": {
                "type": "string",
                "attribute": "sort",
                "mutable": false,
                "complexType": {
                    "original": "string | 'latest' | 'oldest' | 'bottom_rating' | 'top_rating'",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sort comments"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "testimonials": {
                "type": "boolean",
                "attribute": "testimonials",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Determines if the comments are testimonials"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "comments": {},
            "pagination": {},
            "total": {},
            "showPlaceholder": {},
            "nextPage": {},
            "mostHelpfulLabel": {},
            "noComments": {},
            "comment_title": {},
            "comment_name": {},
            "placeholder_text": {},
            "showRatingSummary": {},
            "allowLikes": {}
        };
    }
    static get methods() {
        return {
            "reload": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Reloads the comments data from the server",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "host"; }
    static get listeners() {
        return [{
                "name": "commentAdded",
                "method": "onCommentAdded",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
