/*!
 * Crafted with ❤ by Salla
 */
import { h, Host } from "@stencil/core";
export class SallaCartCoupons {
    constructor() {
        this.availableCoupons = [];
        this.cartTotal = 0;
        this.currentCoupon = '';
        this.couponInputValue = '';
        this.couponError = '';
        this.isApplying = false;
        this.isHandlingInternalError = false;
        // Store cart event listener references for cleanup
        this.cartUpdatedHandler = (cartData) => {
            this.cartTotal = cartData.sub_total ?? cartData.total ?? 0;
            // Update current coupon state
            const couponCode = cartData.coupon || '';
            // Only overwrite the user's typed value when the cart-level coupon itself changes
            if (couponCode !== this.currentCoupon) {
                this.currentCoupon = couponCode;
                this.couponInputValue = couponCode;
            }
            // Clear error when cart updates
            this.couponError = '';
        };
        this.couponAddedHandler = () => {
            // Coupon was successfully added - state is managed by cartUpdatedHandler
        };
        this.couponAdditionFailedHandler = (error) => {
            // Only handle external coupon failures when no internal operation is handling errors
            if (!this.isApplying && !this.isHandlingInternalError) {
                this.showCouponError(error?.message || salla.lang.get('pages.cart.coupon_application_error'));
            }
            // Internal operations handle their own errors to prevent double display
        };
        this.couponDeletedHandler = () => {
            // Coupon was removed - state is managed by cartUpdatedHandler
        };
        // Arrow functions to maintain context for event listeners
        this.onKeyUp = (event) => {
            if (event.key === 'Enter') {
                this.couponButtonRef?.click();
            }
            this.couponError = '';
        };
        this.onInput = (event) => {
            this.couponInputValue = event.target.value;
        };
    }
    async componentWillLoad() {
        await Salla.onReady();
        await Salla.lang.onLoaded();
        //then set your logic here to avoid any race condition
        this.loadCouponsData(); // Load async without blocking render - shows empty until loaded
        this.loadCartTotal();
        this.setupCartEventListeners();
        // Note: No store feature gate needed - coupon availability controlled by backend API response
    }
    componentDidLoad() {
        this.setupCouponInputEvents();
    }
    setupCartEventListeners() {
        // Listen for cart updates to refresh cart total
        salla.event.on('cart::updated', this.cartUpdatedHandler);
        // Listen for coupon events
        salla.event.on('cart::coupon.added', this.couponAddedHandler);
        salla.event.on('cart::coupon.addition.failed', this.couponAdditionFailedHandler);
        salla.event.on('cart::coupon.deleted', this.couponDeletedHandler);
    }
    disconnectedCallback() {
        // Clean up DOM event listeners
        this.couponInputRef?.removeEventListener('keyup', this.onKeyUp);
        this.couponInputRef?.removeEventListener('input', this.onInput);
        // Clean up cart event listeners using reliable global event system
        salla.event.off('cart::updated', this.cartUpdatedHandler);
        salla.event.off('cart::coupon.added', this.couponAddedHandler);
        salla.event.off('cart::coupon.addition.failed', this.couponAdditionFailedHandler);
        salla.event.off('cart::coupon.deleted', this.couponDeletedHandler);
    }
    /**
     * Business Decision: No visual selected state needed
     * UX Flow: Click coupon → populate input → auto-apply (streamlined experience)
     */
    async selectCoupon(couponCode) {
        const selectedCoupon = this.availableCoupons.find(coupon => coupon.code === couponCode);
        if (selectedCoupon) {
            if (!this.isEligible(selectedCoupon)) {
                throw new Error(`Coupon not eligible: minimum cart amount not met`);
            }
            try {
                // Actually apply the coupon to the cart first
                await this.applyCoupon(couponCode);
                // Only dispatch event after successful API call
                this.host.dispatchEvent(new CustomEvent('salla::cart-coupons.coupon.selected', {
                    detail: selectedCoupon,
                    bubbles: true
                }));
            }
            catch (error) {
                // Rethrow to let caller handle the error
                throw error;
            }
        }
        return selectedCoupon;
    }
    async loadCouponsData() {
        try {
            // Load coupons from API
            const response = await salla.api.request('coupons');
            const raw = response?.data;
            const coupons = Array.isArray(raw) ? raw : (Array.isArray(raw?.data) ? raw.data : []);
            this.availableCoupons = coupons;
        }
        catch (error) {
            console.warn('Failed to load coupons:', error);
            // No coupons available on error
            this.availableCoupons = [];
        }
    }
    loadCartTotal() {
        // Get cart total and current coupon from Salla storage
        const cart = salla.storage.get('cart');
        // Check summary first (more accurate), then cart level, fallback to 0
        this.cartTotal = cart?.summary?.sub_total ?? cart?.sub_total ?? 0;
        this.currentCoupon = cart?.coupon || '';
        this.couponInputValue = cart?.coupon || '';
    }
    setupCouponInputEvents() {
        if (!this.couponInputRef || !this.couponButtonRef) {
            return;
        }
        this.couponInputRef.addEventListener('keyup', this.onKeyUp);
        this.couponInputRef.addEventListener('input', this.onInput);
    }
    async handleCouponButtonClick() {
        if (this.isApplying) {
            return;
        }
        const hasCoupon = !!this.currentCoupon;
        if (!hasCoupon && !this.couponInputValue.trim()) {
            this.showCouponError(salla.lang.get('pages.cart.enter_coupon_code'));
            return;
        }
        this.isApplying = true;
        this.isHandlingInternalError = true;
        try {
            if (hasCoupon) {
                // Remove existing coupon
                await salla.cart.deleteCoupon();
            }
            else {
                // Apply new coupon
                await salla.cart.addCoupon(this.couponInputValue.trim());
            }
        }
        catch (error) {
            this.showCouponError(error.response?.data?.error?.message || salla.lang.get('pages.cart.coupon_application_error'));
        }
        finally {
            this.isApplying = false;
            // Keep internal error flag active briefly to prevent race condition with SDK event
            setTimeout(() => {
                this.isHandlingInternalError = false;
            }, 100);
        }
    }
    showCouponError(message) {
        this.couponError = message;
    }
    handleCouponClick(coupon) {
        this.applyCoupon(coupon.code, false).catch(() => {
            // Error already displayed by applyCoupon
        });
    }
    async applyCoupon(couponCode, shouldThrow = true) {
        if (this.isApplying) {
            if (shouldThrow) {
                throw new Error('Coupon application already in progress');
            }
            else {
                return; // Silent return for card clicks when operation is already in progress
            }
        }
        // Update the input field with the coupon code
        this.couponInputValue = couponCode;
        // Clear any existing errors
        this.couponError = '';
        this.isApplying = true;
        this.isHandlingInternalError = true;
        try {
            // Apply the coupon directly without checking for existing coupon
            await salla.cart.addCoupon(couponCode.trim());
        }
        catch (error) {
            this.showCouponError(error.response?.data?.error?.message || salla.lang.get('pages.cart.coupon_application_error'));
            // Re-throw error only if requested (for selectCoupon API)
            if (shouldThrow) {
                throw error;
            }
        }
        finally {
            this.isApplying = false;
            // Keep internal error flag active briefly to prevent race condition with SDK event
            setTimeout(() => {
                this.isHandlingInternalError = false;
            }, 100);
        }
    }
    formatMainAmount(coupon) {
        if (coupon.type === 'percentage') {
            // For percentage coupons, amount should be a string or number
            const percentageValue = typeof coupon.amount === 'object' ? coupon.amount.amount : coupon.amount;
            return `${salla.helpers.number(percentageValue)}%`;
        }
        else {
            // For fixed coupons, amount is an object with amount and currency
            const amountData = typeof coupon.amount === 'object' ? coupon.amount : {
                amount: coupon.amount,
                currency: coupon.minimum_amount?.currency || salla.config.get('store.currency.code', 'SAR')
            };
            return (h("span", { innerHTML: salla.money(amountData.amount, amountData.currency) }));
        }
    }
    isEligible(coupon) {
        if (coupon.minimum_amount && this.cartTotal < parseFloat(coupon.minimum_amount.amount)) {
            return false; // Coupon is not eligible due to minimum amount requirement
        }
        return true;
    }
    renderCouponCard(coupon) {
        const isEligible = this.isEligible(coupon);
        // Note: Card notches (ticket-style pseudo-elements) match card background, not page background - this is intentional design
        return (h("div", { class: "s-cart-coupons-slide-one-fourth swiper-slide" }, h("div", { class: `s-cart-coupons-card ${!isEligible || this.isApplying ? 's-cart-coupons-disabled' : ''}`, onClick: () => isEligible && !this.isApplying && this.handleCouponClick(coupon) }, h("div", { class: "s-cart-coupons-top-section" }, h("div", { class: "s-cart-coupons-discount-values" }, h("div", { class: "s-cart-coupons-main-amount" }, this.formatMainAmount(coupon)), coupon.free_shipping ? (h("div", { class: "s-cart-coupons-secondary-info" }, "+ ", salla.lang.get('pages.cart.free_shipping'))) : coupon.maximum_amount && (h("div", { class: "s-cart-coupons-secondary-info" }, salla.lang.get('pages.cart.up_to'), " ", h("span", { innerHTML: salla.money(coupon.maximum_amount.amount, coupon.maximum_amount.currency) })))), h("div", { class: "s-cart-coupons-code" }, coupon.code)), h("div", { class: "s-cart-coupons-divider" }), h("div", { class: "s-cart-coupons-bottom-section" }, h("div", { class: "s-cart-coupons-terms" }, coupon.remaining_days !== undefined && coupon.remaining_days !== null && (h("div", { class: `s-cart-coupons-expiry ${coupon.remaining_days <= 3 ? 's-cart-coupons-expiry-warning' : ''}` }, coupon.remaining_days === 0
            ? salla.lang.get('pages.cart.expires_today')
            : `${salla.lang.get('pages.cart.expires_after')} ${coupon.remaining_days} ${salla.lang.get('pages.cart.day')}`)), coupon.minimum_amount && parseFloat(coupon.minimum_amount.amount) > 0 && (h("div", { class: "s-cart-coupons-minimum" }, salla.lang.get('pages.cart.minimum'), " ", h("span", { innerHTML: salla.money(coupon.minimum_amount.amount, coupon.minimum_amount.currency) })))), h("div", { class: "s-cart-coupons-action" }, isEligible ? salla.lang.get('pages.cart.save_coupon') : salla.lang.get('pages.cart.coupon_not_compatible'))))));
    }
    render() {
        return (h(Host, { key: '95e65153874488ea19570a11d82eca2a054dd12f' }, h("div", { key: '1bbcebf392b3cbe9a771d2fead982c6d467920a2', class: "s-cart-coupons-wrapper" }, h("div", { key: 'f43ff91fbe2661f7c533d1ded01910bf9cdd04bc', class: "s-cart-coupons-input-section" }, h("label", { key: '47b768adf09859842a329174ed670e0ed6eb38e5', htmlFor: "coupon-input", class: "s-cart-coupons-coupon-label" }, salla.lang.get('pages.cart.have_coupon')), h("div", { key: '0119d436bd813f0aed13b15178644f393f23c448', class: "s-cart-coupons-coupon-input-container" }, h("input", { key: '48daad1665830075e676843c96f99af147a7272c', type: "text", id: "coupon-input", name: "coupon", class: `form-input ${this.couponError ? 's-coupon-input-error' : ''}`, placeholder: salla.lang.get('pages.cart.coupon_placeholder'), value: this.couponInputValue, disabled: !!this.currentCoupon || this.isApplying, ref: el => this.couponInputRef = el, "aria-label": salla.lang.get('pages.cart.apply_coupon') }), h("salla-button", { key: '9e01ec3c8bd3a28b5dd00d028fd8d0b29a1f0f63', ref: el => this.couponButtonRef = el, class: `s-cart-coupons-coupon-button ${this.currentCoupon ? 's-cart-coupons-coupon-button-remove' : 's-cart-coupons-coupon-button-apply'}`, color: this.currentCoupon ? 'danger' : 'primary', loading: this.isApplying, "loader-position": "center", onClick: () => this.handleCouponButtonClick() }, this.currentCoupon ? (h("i", { class: "sicon-cancel" })) : (h("span", null, salla.lang.get('pages.cart.save_coupon'))))), this.couponError && (h("span", { key: '0b46e12e0ece78bb96180004a30154cf5229c930', class: "s-cart-coupons-coupon-error" }, this.couponError))), this.availableCoupons && this.availableCoupons.length > 0 && (h("salla-slider", { key: '6df6dc30d63f8e158ce65392ae682f03d09ee014', type: "carousel", showControls: false, class: "s-cart-coupons-slider" }, h("div", { key: 'adc4343bc2f217bdcf03a769b19363a363ca1ccb', slot: "items" }, this.availableCoupons.map(coupon => this.renderCouponCard(coupon))))))));
    }
    static get is() { return "salla-cart-coupons"; }
    static get originalStyleUrls() {
        return {
            "$": ["salla-cart-coupons.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["salla-cart-coupons.css"]
        };
    }
    static get states() {
        return {
            "availableCoupons": {},
            "cartTotal": {},
            "currentCoupon": {},
            "couponInputValue": {},
            "couponError": {},
            "isApplying": {}
        };
    }
    static get methods() {
        return {
            "selectCoupon": {
                "complexType": {
                    "signature": "(couponCode: string) => Promise<Coupon>",
                    "parameters": [{
                            "name": "couponCode",
                            "type": "string",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Coupon": {
                            "location": "import",
                            "path": "./interfaces",
                            "id": "src/components/salla-cart-coupons/interfaces.ts::Coupon"
                        }
                    },
                    "return": "Promise<Coupon>"
                },
                "docs": {
                    "text": "Business Decision: No visual selected state needed\nUX Flow: Click coupon \u2192 populate input \u2192 auto-apply (streamlined experience)",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "host"; }
}
