/**
 * p11Toast.js
 * Handles Bootstrap Toast logic with integrated native swipe-to-dismiss.
 * All comments are in English.
 */

export const P11ToastFunctions = {
    _activeToasts: new Map(),

    /**
     * Initializes a Bootstrap Toast and sets up swipe gestures.
     */
    initializeToast: function (elementRef, dotNetRef, toastId, options) {
        if (!elementRef || !window.bootstrap?.Toast) {
            console.error("[p11][Toast] initializeToast: Bootstrap Toast or ElementRef not found.");
            return;
        }

        // --- Z-Index Berechnung ---
        const stackDepth = this._activeToasts.size;
        const zIndex = window.p11Js.Utility.getNextZIndex(stackDepth, 'P11Toast');
        elementRef.style.setProperty('z-index', zIndex.toString(), 'important');
        // -------------------------------

        let instance = window.bootstrap.Toast.getInstance(elementRef);

        if (!instance) {
            instance = new window.bootstrap.Toast(elementRef, options || {});

            // Bootstrap Event: Notify Blazor when closed via auto-hide or close button
            const hiddenHandler = () => {
                if (dotNetRef) {
                    dotNetRef.invokeMethodAsync('JsToastHidden', toastId)
                        .catch(err => console.error("[p11][Toast] Error in JsToastHidden callback", err));
                }
            };
            elementRef.addEventListener('hidden.bs.toast', hiddenHandler);

            // Store state for swipe and cleanup
            const toastState = {
                instance,
                dotNetRef,
                hiddenHandler,
                cleanupSwipe: null
            };

            this._activeToasts.set(toastId, toastState);

            // Setup Swipe-to-dismiss
            const position = options.position || 'top';
            this._setupToastSwipe(elementRef, toastId, position);

            if (window.p11Js) window.p11Js.log("Toast", `Initialized: ${toastId}`);
        }
    },

    /**
     * Internal: Sets up the swipe-to-dismiss logic using the global Utility.
     */
    _setupToastSwipe: function (element, toastId, position) {
        let startX = 0, startY = 0, isMoving = false;
        let lastY = 0;

        const handleStart = (e) => {
            // Stop event from bubbling up to prevent background interaction
            e.stopPropagation();

            if (!e.touches || e.touches.length !== 1) return;

            startX = e.touches[0].clientX;
            startY = e.touches[0].clientY;
            lastY = startY;
            isMoving = true;

            // Visual feedback: disable transitions and set touch-action
            element.style.setProperty('transition', 'none', 'important');
            element.style.touchAction = 'none';
        };

        const handleMove = (e) => {
            if (!isMoving) return;

            // PREVENT BACKGROUND SCROLLING: Essential for Capacitor/Mobile
            if (e.cancelable) {
                e.preventDefault();
            }
            e.stopPropagation();

            // Use global p11Js.Utility for metrics
            const metrics = window.p11Js.Utility.getSwipeMetrics(e, startX, startY);
            if (!metrics) return;

            lastY = e.touches[0].clientY;
            let moveAmount = 0;

            // Filter direction based on toast position
            if (position.includes('bottom') && metrics.diffY > 0) {
                moveAmount = metrics.diffY;
            } else if (!position.includes('bottom') && metrics.diffY < 0) {
                moveAmount = metrics.diffY;
            }

            // Apply the visual transform and fade effect
            if (Math.abs(moveAmount) > 0) {
                element.style.setProperty('transform', `translateY(${moveAmount}px)`, 'important');
                element.style.setProperty('opacity', (1 - Math.abs(moveAmount / 150)).toString(), 'important');
            }
        };

        const handleEnd = (e) => {
            if (!isMoving) return;
            isMoving = false;

            const diffY = lastY - startY;
            const threshold = 60;
            let shouldClose = false;

            // Evaluate if swipe was long enough to trigger dismiss
            if (position.includes('bottom') && diffY > threshold) shouldClose = true;
            else if (!position.includes('bottom') && diffY < -threshold) shouldClose = true;

            element.style.removeProperty('transition');

            if (shouldClose) {
                this.hideToast(element);
            } else {
                // Snap back to original position
                element.style.setProperty('transform', '', 'important');
                element.style.setProperty('opacity', '1', 'important');
            }

            // Restore touch-action after a short delay
            setTimeout(() => { if (element) element.style.touchAction = ''; }, 300);
        };

        // Event listeners with passive: false to allow preventDefault()
        element.addEventListener('touchstart', handleStart, { passive: false });
        element.addEventListener('touchmove', handleMove, { passive: false });
        element.addEventListener('touchend', handleEnd, { passive: true });

        const state = this._activeToasts.get(toastId);
        if (state) {
            state.cleanupSwipe = () => {
                element.removeEventListener('touchstart', handleStart);
                element.removeEventListener('touchmove', handleMove);
                element.removeEventListener('touchend', handleEnd);
            };
        }
    },

    /**
     * Shows the toast instance.
     */
    showToast: function (elementRef) {
        const instance = window.bootstrap.Toast.getInstance(elementRef);
        if (instance) instance.show();
    },

    /**
     * Programmatically hides the toast instance.
     */
    hideToast: function (elementRef) {
        const instance = window.bootstrap.Toast.getInstance(elementRef);
        if (instance) instance.hide();
    },

    /**
     * Full cleanup of the toast resources.
     */
    disposeToast: function (elementRef, toastId) {
        const state = this._activeToasts.get(toastId);
        if (state) {
            if (state.cleanupSwipe) state.cleanupSwipe();
            if (state.hiddenHandler && elementRef) elementRef.removeEventListener('hidden.bs.toast', state.hiddenHandler);
            if (state.instance) state.instance.dispose();
            this._activeToasts.delete(toastId);
            if (window.p11Js) window.p11Js.log("Toast", `Disposed: ${toastId}`);
        }
    }
};