/**
 * p11PageNative.js
 * Version 2.2 (Zwillings-Version zu ModalNative)
 * Spezialisiert auf Edge-Swipe Handling für Page-Wrapper, um die globale Navigation zu triggern.
 */

export const PageNativeFunctions = {
    _activePages: new Map(), // Speicherung via Guid/ID (analog zu _activeModals)
    _dotNetHelper: null,    // Zentrale Referenz zum EventStateService
    _isEnabled: true,       // Globaler Schalter für das Modul
    _config: null,          // Lokale Kopie der C#-Konfiguration

    /* ========================================================================
       C# INTERFACE (Bridge-Funktionen identisch zu ModalNative)
       ======================================================================== */

    /**
     * Registriert die Referenz zum EventStateService (C#).
     */
    registerEventStateService: function (dotNetRef) {
        this._dotNetHelper = dotNetRef;
        p11Js.log("PageNative", "EventStateService-Ref registriert.");
    },

    /**
     * Aktiviert oder deaktiviert die Swipe-Logik.
     */
    setSwipeEnabled: function (enabled) {
        this._isEnabled = enabled;
        p11Js.log("PageNative", `Modul-Status: ${enabled ? 'AKTIVIERT' : 'DEAKTIVIERT'}`);
    },

    /**
     * Synchronisiert Konfigurationswerte aus C# (EdgeSize, Threshold etc.).
     */
    updateConfiguration: function (config) {
        if (!config) return;
        this._config = {
            edgeSize: p11Js.Utility.getPlatform() === 'ios' ? (config.iosEdgeSize ?? 45) : (config.androidEdgeSize ?? 30),
            threshold: config.threshold ?? 70,
            velocityLimit: 0.3
        };
        p11Js.log("PageNative", "Konfiguration aktualisiert", this._config);
    },

    /* ========================================================================
       PAGE CORE LOGIC (Initialisierung & Release)
       ======================================================================== */

    /**
     * Initialisiert den Swipe-Wrapper für eine Blazor-Page.
     */
    initPageSwipe: function (element, elementId, dotNetHelper) {
        if (!element || !elementId) {
            console.error("[p11][PageNative] Init fehlgeschlagen: Element oder ID fehlt.");
            return;
        }

        // FORCE LOG für die Diagnose
        console.warn(`[p11][PageNative] >>> initPageSwipe aufgerufen für: ${elementId}`);

        // Wir suchen den tatsächlichen Content-Layer (tpc- Präfix beachten falls vorhanden!)
        const contentLayer = element.querySelector('.p11-shadow-layer') ||
            element.querySelector('.tpc-p11-shadow-layer') ||
            element;

        p11Js.log("PageNative", `Initializing Page Layer: ${contentLayer.className}`);

        // Styles auf den Layer anwenden
        contentLayer.style.zIndex = "10";
        if (contentLayer.style.position === "" || contentLayer.style.position === "static") {
            contentLayer.style.position = "relative";
        }

        // Wir übergeben den dotNetHelper an das Setup, falls dort die Listener direkt gebunden werden
        const swipeCleanup = this._setupLocalSwipe(element, contentLayer, elementId);

        // WICHTIG: Den dotNetHelper in der Map speichern!
        this._activePages.set(elementId, {
            element: contentLayer,
            dotNetHelper: dotNetHelper, // <--- Hier wird die Brücke zu C# gespeichert
            cleanup: () => {
                swipeCleanup();
            }
        });
    },

    /**
     * Entfernt die Listener und löscht die Page aus der Map.
     */
    releasePageSwipe: function (elementId) {
        const state = this._activePages.get(elementId);
        if (!state) return;

        p11Js.log("PageNative", `Release Page: ${elementId}`);

        if (state.cleanup) state.cleanup();
        this._resetElementStyles(state.element);
        this._activePages.delete(elementId);
    },

    /* ========================================================================
       INTERNAL HELPERS (Swipe & Communication)
       ======================================================================== */

    _setupLocalSwipe: function (container, target, elementId) {
        let startX = 0, startY = 0, startTime = 0, isSwiping = false;

        // Fallback Config für Tests
        const cfg = this._config || {
            edgeSize: 50, 
            threshold: 70,
            velocityLimit: 0.2
        };

        const onStart = (e) => {
            if (!this._isEnabled || (!e.touches && !e.pageX)) return;

            const touch = e.touches ? e.touches[0] : e;

            // Logge den Startversuch
            if (touch.clientX > cfg.edgeSize) {
                return;
            }

            console.log("[p11][PageNative] Swipe-Zone berührt.");

            if (e.target.closest('button, a, input, textarea, select, .no-swipe, .p11-scroll-container-horizontal')) return;

            startX = touch.clientX;
            startY = touch.clientY;
            startTime = Date.now();
            isSwiping = false;

            target.style.transition = 'none';
        };

        const onMove = (e) => {
            if (startX === 0) return;

            const touch = e.touches ? e.touches[0] : e;
            const diffX = touch.clientX - startX;
            const diffY = Math.abs(touch.clientY - startY);

            if (!isSwiping) {
                // Horizontale Bewegung muss dominieren
                if (diffX > 10 && diffX > diffY) {
                    isSwiping = true;
                    console.log("[p11][PageNative] Swipe aktiv...");
                } else if (diffY > 30) {
                    startX = 0;
                    return;
                }
            }

            if (isSwiping) {
                if (e.cancelable) e.preventDefault();
                const moveX = Math.max(0, diffX);
                target.style.transform = `translateX(${moveX}px)`;
            }
        };

        const onEnd = (e) => {
            if (startX === 0) return;

            const duration = Date.now() - startTime;
            const finalTouch = e.changedTouches ? e.changedTouches[0] : (e.touches ? e.touches[0] : e);
            const diffX = finalTouch ? finalTouch.clientX - startX : 0;
            const velocity = diffX / duration;

            if (isSwiping && (diffX > cfg.threshold || velocity > cfg.velocityLimit)) {
                console.warn("[p11][PageNative] SWIPE-BACK TRIGGER!");
                this._executeFlyOut(target, elementId);
            } else {
                this._executeSnapBack(target);
            }

            startX = 0;
            isSwiping = false;
        };

        // Event Listener registrieren (Mouse-Support für Browser-Testing inkludiert)
        container.addEventListener('touchstart', onStart, { passive: true });
        container.addEventListener('touchmove', onMove, { passive: false });
        container.addEventListener('touchend', onEnd, { passive: true });

        // Optional für Desktop-Sim: mousedown/mousemove/mouseup
        // container.addEventListener('mousedown', onStart); 

        return () => {
            container.removeEventListener('touchstart', onStart);
            container.removeEventListener('touchmove', onMove);
            container.removeEventListener('touchend', onEnd);
        };
    },

    _executeFlyOut: function (element, elementId) {
        element.style.transition = 'transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
        element.style.transform = 'translateX(100%)';

        setTimeout(() => this._triggerBackNavigation(elementId), 180);
    },

    _executeSnapBack: function (element) {
        element.style.transition = 'transform 0.3s ease-out';
        element.style.transform = 'translateX(0)';
    },

    _resetElementStyles: function (element) {
        if (element) {
            element.style.transform = '';
            element.style.transition = '';
        }
    },

    _triggerBackNavigation: function (elementId) {
        // 1. Hol dir die Daten der spezifischen Seite aus der Map
        const pageData = this._activePages.get(elementId);

        // 2. Priorität: Instanz-Helper -> Globaler Fallback
        const helper = (pageData && pageData.dotNetHelper)
            || this._dotNetHelper
            || (window.p11Js ? window.p11Js.eventStateRef : null);

        if (helper) {
            p11Js.log("PageNative", `Triggering Back-Navigation for Page: ${elementId}`);

            // WICHTIG: Wir rufen 'CloseFromJS' auf, da dies die [JSInvokable] Methode 
            // in deiner P11PageNative.razor.cs ist!
            helper.invokeMethodAsync('CloseFromJS')
                .catch(err => console.error("[p11][PageNative] Callback failed:", err));

        } else {
            console.error("[p11][PageNative] Kritischer Fehler: Kein DotNet-Helper gefunden für ID: " + elementId);
        }
    }
};