import { Host, h } from "@stencil/core";
import { arrow_left, arrow_right } from "pn-design-assets/pn-assets/icons.js";
export class PnMarketwebCarousel {
    constructor() {
        this.previousButtonLabel = undefined;
        this.nextButtonLabel = undefined;
        this.ariaNavigationLabel = undefined;
        this.source = undefined;
        this.slidesToShow = 1;
        this.showCarouselButtons = true;
        this.showFirstSlidePrevButton = false;
        this.showLastSlideNextButton = false;
        this.slidesData = [];
        this.currentSlide = 0;
        this.isDragging = false;
        this.slideWidth = 0;
    }
    static DEFAULTS = {
        SWIPE_THRESHOLD_PX: 50,
        ANIMATION_DURATION_MS: 300,
        OVERSCROLL_LIMIT_PERCENT: 30,
    };
    hostElement;
    slides = null;
    slidesContainer = null;
    totalSlides = 0;
    prevButton = null;
    nextButton = null;
    dragStartX = 0;
    listeners = [];
    memoizedSlideWidth = null;
    componentWillLoad() {
        this.setInitialValues();
    }
    componentDidLoad() {
        this.setupCarousel();
        window.addEventListener('resize', this.handleResize);
    }
    disconnectedCallback() {
        this.cleanup();
        window.removeEventListener('resize', this.handleResize);
    }
    async goToSlide(index) {
        if (index >= 0 && index < this.totalSlides) {
            this.currentSlide = index;
            this.moveSlides();
            this.updateNavButtons();
        }
    }
    async getCurrentSlide() {
        return this.currentSlide;
    }
    handleSourceChange(newValue) {
        if (newValue) {
            this.setInitialValues();
        }
    }
    setInitialValues() {
        if (!this.source?.trim()) {
            console.warn('No source provided for carousel');
            return;
        }
        try {
            const parsedData = JSON.parse(this.source);
            if (!parsedData?.slides) {
                throw new Error('Invalid slides data structure');
            }
            if (Array.isArray(parsedData.slides)) {
                this.slidesData = parsedData.slides;
                this.showCarouselButtons = this.slidesData.length > 1;
            }
            else {
                throw new Error('Slides data is not an array');
            }
        }
        catch (error) {
            console.error('Error parsing carousel source:', error instanceof Error ? error.message : 'Unknown error');
            this.slidesData = [];
        }
    }
    setupCarousel() {
        this.initializeElements();
        this.attachEventListeners();
        this.updateNavButtons();
    }
    initializeElements() {
        this.slidesContainer = this.hostElement.querySelector('[data-slides-container]');
        this.slides = this.hostElement.querySelectorAll('[data-slide]');
        this.totalSlides = this.slides?.length ?? 0;
        if (this.showCarouselButtons) {
            this.prevButton = this.hostElement.querySelector('[data-nav-button-prev]');
            this.nextButton = this.hostElement.querySelector('[data-nav-button-next]');
        }
        this.slideWidth = 100 / this.slidesToShow;
    }
    attachEventListeners() {
        if (!this.slidesContainer)
            return;
        const addListener = (element, event, handler, options) => {
            element.addEventListener(event, handler, options);
            this.listeners.push({ element, event, handler });
        };
        // Touch events
        addListener(this.slidesContainer, 'touchstart', this.handleTouchStart, { passive: true });
        addListener(this.slidesContainer, 'touchmove', this.handleTouchMove, { passive: false });
        addListener(this.slidesContainer, 'touchend', this.handleTouchEnd, { passive: true });
        // Mouse events
        addListener(this.slidesContainer, 'mousedown', this.handleTouchStart);
        addListener(this.slidesContainer, 'mousemove', this.handleTouchMove);
        addListener(this.slidesContainer, 'mouseup', this.handleTouchEnd);
        addListener(this.slidesContainer, 'mouseleave', this.handleTouchEnd);
        if (this.showCarouselButtons) {
            this.nextButton && addListener(this.nextButton, 'click', this.handleNextClick);
            this.prevButton && addListener(this.prevButton, 'click', this.handlePrevClick);
        }
    }
    cleanup() {
        this.listeners.forEach(({ element, event, handler }) => {
            element.removeEventListener(event, handler);
        });
        this.listeners = [];
    }
    handleResize = () => {
        this.memoizedSlideWidth = null;
    };
    getSlideWidth() {
        if (!this.memoizedSlideWidth && this.slidesContainer) {
            this.memoizedSlideWidth = this.slidesContainer.offsetWidth;
        }
        return this.memoizedSlideWidth ?? 0;
    }
    handleNextClick = (e) => {
        e.stopPropagation();
        this.nextSlide();
    };
    handlePrevClick = (e) => {
        e.stopPropagation();
        this.prevSlide();
    };
    handleTouchStart = (e) => {
        if (e.target.classList.contains('nav-button'))
            return;
        this.isDragging = true;
        this.dragStartX = 'touches' in e ? e.touches[0].clientX : e.clientX;
    };
    handleTouchMove = (e) => {
        if (!this.isDragging)
            return;
        if ('touches' in e) {
            e.preventDefault();
        }
        const currentPosition = 'touches' in e ? e.touches[0].clientX : e.clientX;
        const diff = currentPosition - this.dragStartX;
        const percentMove = (diff / this.getSlideWidth()) * 100;
        this.moveSlides(percentMove);
    };
    handleTouchEnd = (e) => {
        if (!this.isDragging)
            return;
        this.isDragging = false;
        const currentPosition = 'changedTouches' in e ? e.changedTouches[0].clientX : e.clientX;
        const diff = currentPosition - this.dragStartX;
        if (Math.abs(diff) > PnMarketwebCarousel.DEFAULTS.SWIPE_THRESHOLD_PX) {
            if (diff > 0 && this.currentSlide > 0) {
                this.currentSlide--;
            }
            else if (diff < 0 && this.currentSlide < this.totalSlides - 1) {
                this.currentSlide++;
            }
        }
        this.moveSlides();
        this.updateNavButtons();
    };
    calculateProportionalTranslation() {
        // Calculate proportional translation based on slidesToShow
        return -200 + (this.slidesToShow - 1) * 100;
    }
    moveSlides(extraTranslate = 0) {
        if (!this.slides || !this.slidesContainer) {
            return;
        }
        try {
            this.slides.forEach((slide, index) => {
                if (slide) {
                    // Set each slide's width
                    slide.style.width = `${this.slideWidth}%`;
                    let translation = 0;
                    if (this.slidesToShow === 1) {
                        // Full slide view
                        translation = -100 * this.currentSlide;
                    }
                    else {
                        // Partial slide view
                        if (this.totalSlides === 2) {
                            // Special case for 2 slides
                            if (this.currentSlide === 1) {
                                translation = -50; // Both slides move by -50%
                            }
                        }
                        else {
                            // 3 or more slides
                            if (this.currentSlide === 1) {
                                // Second slide showing - all slides move -100%
                                translation = -100;
                            }
                            else if (this.currentSlide === 2) {
                                // Third slide showing
                                if (index === 0) {
                                    translation = -100; // First slide stays at -100%
                                }
                                else {
                                    // Calculate proportional translation
                                    translation = this.calculateProportionalTranslation();
                                }
                            }
                        }
                    }
                    // Add any extra translation from dragging
                    translation += extraTranslate;
                    slide.style.transform = `translateX(${translation}%)`;
                    slide.style.position = 'relative';
                    // Update visibility for screen readers
                    let isVisible;
                    if (this.slidesToShow === 1) {
                        isVisible = index === this.currentSlide;
                    }
                    else {
                        isVisible =
                            this.currentSlide === 0 || // First slide showing
                                this.totalSlides === 2 || // Two slides - both visible
                                (this.currentSlide === 1 && translation === -100) || // Second slide showing
                                (this.currentSlide === 2 &&
                                    ((index === 0 && translation === -100) || // First slide still visible
                                        index > 0)); // Second and third slides visible
                    }
                    slide.setAttribute('aria-hidden', (!isVisible).toString());
                }
            });
        }
        catch (error) {
            console.error('Error moving slides:', error);
        }
    }
    updateNavButtons() {
        if (!this.showCarouselButtons)
            return;
        const isFirstSlide = this.currentSlide === 0;
        const isLastSlide = this.currentSlide === this.totalSlides - 1;
        if (this.prevButton) {
            this.prevButton.classList.toggle('invisible', isFirstSlide && !this.showFirstSlidePrevButton);
            this.prevButton.dataset.show = isFirstSlide ? `${this.showFirstSlidePrevButton}` : 'true';
        }
        if (this.nextButton) {
            this.nextButton.classList.toggle('invisible', isLastSlide && !this.showLastSlideNextButton);
            this.nextButton.dataset.show = isLastSlide ? `${this.showLastSlideNextButton}` : 'true';
        }
    }
    nextSlide() {
        if (this.currentSlide >= this.totalSlides - 1) {
            this.currentSlide = 0;
        }
        else {
            this.currentSlide++;
        }
        this.moveSlides();
        this.updateNavButtons();
    }
    prevSlide() {
        if (this.currentSlide <= 0) {
            this.currentSlide = this.totalSlides - 1;
        }
        else {
            this.currentSlide--;
        }
        this.moveSlides();
        this.updateNavButtons();
    }
    render() {
        return (h(Host, { key: '8d489af98cf73ac43c552ac3ee316bd24bf5a2d0' }, h("div", { key: 'dc3d18f66f48af9cf2ed99d495c3626e95d1d8b3', class: "pn-marketweb-carousel" }, h("section", { key: '27dfb31b3648f26928645f1f713bafaedbb9f0fb', class: "slider-wrapper" }, this.showCarouselButtons && (h("div", { key: '5f88edaf3de10701c2632f592715f9bcefbd22d5', class: "nav-buttons", role: "group", "aria-label": this.ariaNavigationLabel }, h("pn-button", { key: '2df234b30539b17076a6db38da77e38b8b593ba0', appearance: "light", icon: arrow_left, "icon-only": "true", tooltip: this.previousButtonLabel, class: `nav-button ${this.currentSlide === 0 && !this.showFirstSlidePrevButton ? 'invisible' : ''}`, "data-nav-button-prev": true, "area-label": this.previousButtonLabel, "aria-disabled": this.currentSlide === 0 && !this.showFirstSlidePrevButton }), h("pn-button", { key: 'd9637df87e201c5667c164f65a7d486a2bdc12e8', appearance: "light", icon: arrow_right, "icon-only": "true", tooltip: this.nextButtonLabel, class: "nav-button", "data-nav-button-next": true, "area-label": this.nextButtonLabel, "aria-disabled": this.currentSlide === this.totalSlides - 1 && !this.showLastSlideNextButton }))), this.slidesData && (h("ul", { key: '61a176627f3a3c5df83b2498e8cfc3570ef1ec5e', class: "slides-container", "data-slides-container": true, "data-partial": this.slidesToShow === 1 ? 'false' : 'true', "aria-live": "polite", style: { display: 'flex', transform: 'none' } }, this.slidesData.map((slide, index) => (h("li", { class: "slide", "data-slide": true, innerHTML: slide, style: { width: this.slideWidth + '%' }, "aria-hidden": index !== this.currentSlide })))))))));
    }
    static get is() { return "pn-marketweb-carousel"; }
    static get originalStyleUrls() {
        return {
            "$": ["pn-marketweb-carousel.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["pn-marketweb-carousel.css"]
        };
    }
    static get properties() {
        return {
            "previousButtonLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "previous-button-label",
                "reflect": false
            },
            "nextButtonLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "next-button-label",
                "reflect": false
            },
            "ariaNavigationLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "aria-navigation-label",
                "reflect": false
            },
            "source": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "source",
                "reflect": false
            },
            "slidesToShow": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "slides-to-show",
                "reflect": false,
                "defaultValue": "1"
            },
            "showCarouselButtons": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "show-carousel-buttons",
                "reflect": false,
                "defaultValue": "true"
            },
            "showFirstSlidePrevButton": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "show-first-slide-prev-button",
                "reflect": false,
                "defaultValue": "false"
            },
            "showLastSlideNextButton": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "show-last-slide-next-button",
                "reflect": false,
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "slidesData": {},
            "currentSlide": {},
            "isDragging": {},
            "slideWidth": {}
        };
    }
    static get methods() {
        return {
            "goToSlide": {
                "complexType": {
                    "signature": "(index: number) => Promise<void>",
                    "parameters": [{
                            "name": "index",
                            "type": "number",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "getCurrentSlide": {
                "complexType": {
                    "signature": "() => Promise<number>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<number>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "hostElement"; }
    static get watchers() {
        return [{
                "propName": "source",
                "methodName": "handleSourceChange"
            }];
    }
}
//# sourceMappingURL=pn-marketweb-carousel.js.map
