/*!
 * Crafted with ❤ by Salla
 */
import { Host, h } from "@stencil/core";
import Helper from "../../Helpers/Helper";
import { FilterOptionTypes } from "../salla-filters/interfaces";
export class SallaFiltersWidget {
    constructor() {
        this.initialItemCount = 10; // Show 10 items initially
        this.expandedItemCount = 15; // Show 15 items when expanded
        this.calculatedInitialHeight = 0; // Calculated based on actual content
        this.calculatedExpandedHeight = 0; // Calculated based on actual content
        this.isOpen = true;
        this.isShowMore = false;
        this.showMoreLabel = "عرض المزيد";
        this.showLessLabel = "عرض أقل";
        this.page = salla.config.get('page');
        this.searchQuery = '';
        this.filteredCount = 0; // Track filtered results count
    }
    connectedCallback() {
        // Show "Show More" button if there are more than 10 items
        this.withLoadMore = this.option.key != 'price' && Array.isArray(this.option.values) && this.option.values.length > this.initialItemCount;
        salla.onReady(() => {
            this.page = salla.config.get('page');
        });
        salla.lang.onLoaded(() => {
            this.showMoreLabel = salla.lang.getWithDefault('common.titles.more', this.showMoreLabel);
            this.showLessLabel = salla.lang.getWithDefault('common.elements.show_less', this.showLessLabel);
        });
    }
    componentDidLoad() {
        // Use fixed height per item for predictable calculations
        // Each item is approximately 20px, so we calculate based on item count
        const itemHeight = 20; // Fixed height per item
        const paddingPerItem = 15; // Additional padding per item for margins/spacing
        const allItems = this.widgetValues.querySelectorAll('.s-filters-label');
        if (allItems.length > 0) {
            const itemsToMeasure = Math.min(this.initialItemCount, allItems.length);
            // Calculate initial height: (items × height) + (items × padding)
            this.calculatedInitialHeight = this.initialItemCount * (itemHeight + paddingPerItem);
            // Calculate expanded height based on first 15 items
            if (allItems.length > this.initialItemCount) {
                this.calculatedExpandedHeight = this.expandedItemCount * (itemHeight + paddingPerItem);
            }
            else {
                this.calculatedExpandedHeight = itemsToMeasure * (itemHeight + paddingPerItem);
            }
        }
        this.widgetValues.scrollHeight < this.calculatedInitialHeight && (this.withLoadMore = false);
        (this.withLoadMore && this.widgetValues) && (this.widgetValues.style.maxHeight = `${this.calculatedInitialHeight}px`);
        this.widgetContent.style.height = `${this.widgetContent.scrollHeight}px`;
    }
    /**
   * Asynchronously sets the height of a widget element to its current height, allowing for smooth transitions.
   * This function is often used in scenarios where the widget's content changes dynamically, and animating
   * the height adjustment is desired for a smoother user experience.
   *
   * @param {number} [delay=250] - Optional. The delay (in milliseconds) before updating the widget height.
   *                               Defaults to 250 milliseconds.
   *
   * @returns {Promise<void>} - A Promise that resolves once the widget height is set after the specified delay.
   *
   * @example
   * // Set widget height with the default delay (250 milliseconds)
   * await setWidgetHeight();
   *
   * // Set widget height with a custom delay (e.g., 500 milliseconds)
   * await setWidgetHeight(500);
   */
    async setWidgetHeight(delay = 250) {
        this.widgetContent.removeAttribute('style');
        setTimeout(() => {
            let currentWidgetHeight = this.widgetContent.scrollHeight;
            this.widgetContent.style.height = currentWidgetHeight + 'px';
        }, delay);
    }
    /**
     * Reset selected filter options.
     */
    async reset() {
        if (this.option.type === FilterOptionTypes.RANGE) {
            this.priceRange.reset();
        }
        Array.from(this.host.querySelectorAll('input')).forEach(input => input.checked = false);
    }
    /**
     * Action to show more or less filter options.
     */
    async showMore() {
        this.isShowMore = !this.isShowMore;
        this.widgetContent.style.height = 'auto';
        // Reset scroll position to top when collapsing to prevent content cutting
        if (!this.isShowMore) {
            this.widgetValues.scrollTop = 0;
        }
        // Use calculated heights based on actual content
        const maxHeight = this.isShowMore ? this.calculatedExpandedHeight : this.calculatedInitialHeight;
        // Calculate actual item count
        const actualCount = this.searchQuery ? this.filteredCount : (Array.isArray(this.option.values) ? this.option.values.length : 0);
        // When showing more: expand to 15 items height with scrollbar for items beyond 15
        // When showing less: collapse to 10 items height
        this.widgetValues.style.maxHeight = `${maxHeight}px`;
        this.widgetValues.style.overflowY = this.isShowMore && actualCount > this.expandedItemCount ? 'auto' : 'hidden';
        setTimeout(() => {
            this.widgetContent.style.height = `${this.widgetContent.scrollHeight}px`;
        }, 400); // get height after time of collapse animation (duration-300)
    }
    /**
     * Action to toggle widget open or closed (expand/ collapse).
     */
    async toggleWidget() {
        this.isOpen = !this.isOpen;
        Helper.toggleElementClassIf(this.widgetContent, 's-filters-widget-opened', 's-filters-widget-closed', () => this.isOpen);
    }
    renderFilterOption(option) {
        if (![FilterOptionTypes.VALUES, FilterOptionTypes.MINIMUM, FilterOptionTypes.VARIANTS].includes(option.type)) {
            return '';
        }
        //@ts-ignore
        const filteredValues = option.values.filter((filterOption) => {
            if (!this.searchQuery)
                return true;
            const label = typeof filterOption === 'number'
                ? String(filterOption)
                : (filterOption?.value || filterOption?.key || '');
            return String(label).toLowerCase().includes(this.searchQuery.toLowerCase());
        });
        // Update filtered count for show more button logic
        this.filteredCount = filteredValues.length;
        // Show empty state if no results
        if (filteredValues.length === 0) {
            return (h("div", { class: "s-filters-widget-empty-state" }, salla.lang.get('common.elements.no_options') || 'لا توجد نتائج'));
        }
        //@ts-ignore
        return filteredValues.map((filterOption, index) => {
            let value = typeof filterOption == 'number' ? filterOption : (filterOption.key || filterOption.value);
            return h("label", { class: "s-filters-label", htmlFor: `${option.key}-option-${value}`, key: `${option.key}-option-${value}` }, h("input", { id: `${option.key}-option-${value}`, name: option.key, type: "radio", checked: this.isSelectedOption(option, value), class: `s-filters-radio`, onChange: event => this.changed.emit({ event, option, value }) }), this.getOptionLabel(option, filterOption));
        });
    }
    isSelectedOption(option, value) {
        if (option.type === FilterOptionTypes.MINIMUM) {
            return this.filtersData[option.key] == value;
        }
        if (option.type === FilterOptionTypes.VARIANTS) {
            return this.filtersData[option.type] && this.filtersData[option.type][Object.keys(this.filtersData[option.type])[0]] == value;
        }
        if (option.type === FilterOptionTypes.RANGE) {
            return this.filtersData[option.key] && this.filtersData[option.key].min == value.min && this.filtersData[option.key].max == value.max;
        }
        if (option.type === FilterOptionTypes.VALUES) {
            return this.filtersData[option.key] && Number(this.filtersData[option.key]) == Number(value);
        }
        return false;
    }
    getOptionLabel(option, filterOption) {
        if (option.key == 'rating') {
            //in amazon has stars & up, should we add it, to avoid those people who will come to say I selected 4 why I see 5 sars products
            return h("salla-rating-stars", { size: "small", value: filterOption });
        }
        let label = filterOption.value || 'null';
        //label+=filterOption.count ? ` (${salla.helpers.number(filterOption.count)})` : '';
        return h("span", { class: "s-filters-option-name" }, label);
    }
    render() {
        return (h(Host, { key: '033902f6f4ac283b8b501a175b6fdec7c585d68a', class: "s-filters-widget-container" }, h("h3", { key: '3f50c5d20c5563d291979dea0db9f69c72750d3f', class: "s-filters-widget-title", onClick: () => this.toggleWidget() }, h("span", { key: '4e7f263fc35260f641fb9d0291b26c09f9743a36' }, this.option.label), h("span", { key: '6658e86d8a637ac537f285a210d3d8f0e9279f9f', class: `s-filters-widget-plusminus ${this.isOpen ? 's-filters-widget-plusminus-active' : ''}` })), h("div", { key: '3a172b737bb88d2db6b43391cce2b02198fce61e', class: "s-filters-widget-content", ref: (el) => this.widgetContent = el }, Array.isArray(this.option.values) && this.option.values.length > 5 && (h("div", { key: '91f8f4a00dfd05086ed8a385117dfc1d8eabea4c', class: "s-filters-widget-search-wrapper", style: { padding: '8px 0', marginBottom: '8px' } }, h("input", { key: '87a25343561917b823b3b258aa9b8c8a1cb2a71a', type: "text", class: "s-filters-widget-search-input", placeholder: salla.lang.get('blocks.header.search_placeholder') || 'بحث...', value: this.searchQuery, onInput: (e) => this.searchQuery = e.target.value }))), h("div", { key: '282b6b78bd7659134151aad4ec94c4cc2838c01c', class: "s-filters-widget-values", ref: (el) => this.widgetValues = el }, h("slot", { key: 'fae3cf9b337d658bb6a9bee553cb487ecbd1be5f' }), this.option.type !== FilterOptionTypes.RANGE
            ? this.renderFilterOption(this.option)
            : h("salla-price-range", { onChanged: (event) => {
                    this.changed.emit(event.detail);
                }, ref: price => this.priceRange = price, filtersData: this.filtersData, option: this.option })), this.withLoadMore && (!this.searchQuery || this.filteredCount > this.initialItemCount) &&
            h("a", { key: '005eedbbf498d86eb735231b754a8abf0aca77b5', class: "s-filters-widget-more", onClick: () => this.showMore() }, !this.isShowMore ? this.showMoreLabel : this.showLessLabel))));
    }
    static get is() { return "salla-filters-widget"; }
    static get originalStyleUrls() {
        return {
            "$": ["salla-filters-widget.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["salla-filters-widget.css"]
        };
    }
    static get properties() {
        return {
            "withLoadMore": {
                "type": "boolean",
                "attribute": "with-load-more",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Show more or less filter options."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "filtersData": {
                "type": "unknown",
                "attribute": "filters-data",
                "mutable": false,
                "complexType": {
                    "original": "object",
                    "resolved": "object",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Selected filter options value."
                },
                "getter": false,
                "setter": false
            },
            "option": {
                "type": "unknown",
                "attribute": "option",
                "mutable": false,
                "complexType": {
                    "original": "Filter",
                    "resolved": "Filter",
                    "references": {
                        "Filter": {
                            "location": "import",
                            "path": "../salla-filters/interfaces",
                            "id": "src/components/salla-filters/interfaces.ts::Filter"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Filter option along with possible values."
                },
                "getter": false,
                "setter": false
            }
        };
    }
    static get states() {
        return {
            "isOpen": {},
            "isShowMore": {},
            "showMoreLabel": {},
            "showLessLabel": {},
            "page": {},
            "searchQuery": {},
            "filteredCount": {}
        };
    }
    static get events() {
        return [{
                "method": "changed",
                "name": "changed",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Custom event emitted up on filter option selection changes."
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "setWidgetHeight": {
                "complexType": {
                    "signature": "(delay?: number) => Promise<void>",
                    "parameters": [{
                            "name": "delay",
                            "type": "number",
                            "docs": "- Optional. The delay (in milliseconds) before updating the widget height.\n   Defaults to 250 milliseconds."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Asynchronously sets the height of a widget element to its current height, allowing for smooth transitions.\nThis function is often used in scenarios where the widget's content changes dynamically, and animating\nthe height adjustment is desired for a smoother user experience.",
                    "tags": [{
                            "name": "param",
                            "text": "delay - Optional. The delay (in milliseconds) before updating the widget height.\n   Defaults to 250 milliseconds."
                        }, {
                            "name": "returns",
                            "text": "- A Promise that resolves once the widget height is set after the specified delay."
                        }, {
                            "name": "example",
                            "text": "// Set widget height with the default delay (250 milliseconds)\nawait setWidgetHeight();\n\n// Set widget height with a custom delay (e.g., 500 milliseconds)\nawait setWidgetHeight(500);"
                        }]
                }
            },
            "reset": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Reset selected filter options.",
                    "tags": []
                }
            },
            "showMore": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Action to show more or less filter options.",
                    "tags": []
                }
            },
            "toggleWidget": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Action to toggle widget open or closed (expand/ collapse).",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "host"; }
}
