/**
 * p11FloatingPanel.js
 * Part of the p11 UI Library.
 * Handles isolated drag-and-drop logic for Floating Panels.
 * All comments and documentation are in English.
 */

export const P11FloatingPanelFunctions = {
    _activePanels: new Map(),

    /**
     * Initializes the floating panel's drag-and-drop functionality.
     * Called via window.p11Js.FloatingPanel.initializeFloatingPanel
     */
    //initializeFloatingPanel: function (element, elementId, header, dotNetCompRef) {
    initializeFloatingPanel: function (element, elementId, header, dotNetCompRef, resizeHandle) {
        if (!element || !header) {
            console.error(`[p11][FloatingPanel] Initialization failed: Element or Header missing for ${elementId}`);
            return;
        }

        window.p11Js.log("FloatingPanel", `Initializing Panel: ${elementId}`);

        // 1. Z-Index Management using central Utility
        // Floating panels should stay above modals (e.g., as help overlays)
        const stackDepth = this._activePanels.size;
        const newZIndex = window.p11Js.Utility.getNextZIndex(stackDepth, 'P11FloatingPanel');
        element.style.zIndex = newZIndex;

        // 2. Drag Logic State
        let isDragging = false;
        let startX, startY;
        let initialX, initialY;
        let isResizing = false;
        let startWidth, startHeight; // <--- Sicherstellen, dass hier LET davor steht!

        // Localized event handlers for isolation
        const onStart = (e) => {
            if (e.type === 'mousedown' && e.button !== 0) return;

            const clientX = e.type.startsWith('touch') ? e.touches[0].clientX : e.clientX;
            const clientY = e.type.startsWith('touch') ? e.touches[0].clientY : e.clientY;

            const rect = element.getBoundingClientRect();
            const parent = element.offsetParent;

            // Coordinate calculation: Container-Relative vs Document-Absolute
            if (parent && parent.tagName !== 'BODY' && parent.tagName !== 'HTML') {
                const parentRect = parent.getBoundingClientRect();
                initialX = rect.left - parentRect.left;
                initialY = rect.top - parentRect.top;
            } else {
                initialX = rect.left + window.scrollX;
                initialY = rect.top + window.scrollY;
            }

            isDragging = true;
            startX = clientX;
            startY = clientY;

            //// Push to front on interaction
            //const currentStack = this._activePanels.size;
            //element.style.zIndex = window.p11Js.Utility.getNextZIndex(currentStack + 2, 'floating');

            if (dotNetCompRef) {
                dotNetCompRef.invokeMethodAsync('ActivatePanel').catch(() => { });
            }

            if (e.type === 'mousedown') {
                document.addEventListener('mousemove', onMove);
                document.addEventListener('mouseup', onEnd);
            } else {
                document.addEventListener('touchmove', onMove, { passive: false });
                document.addEventListener('touchend', onEnd);
            }

            if (e.cancelable) e.preventDefault();
        };

        const onMove = (e) => {
            if (!isDragging) return;

            const clientX = e.type.startsWith('touch') ? e.touches[0].clientX : e.clientX;
            const clientY = e.type.startsWith('touch') ? e.touches[0].clientY : e.clientY;

            const dx = clientX - startX;
            const dy = clientY - startY;

            element.style.left = `${initialX + dx}px`;
            element.style.top = `${initialY + dy}px`;
            element.style.right = 'auto';
            element.style.bottom = 'auto';
            element.style.margin = '0';

            // Prevent scroll only when dragging the panel
            if (e.type === 'touchmove' && e.cancelable) e.preventDefault();
        };

        const onEnd = async () => {
            if (!isDragging) return;
            isDragging = false;

            document.removeEventListener('mousemove', onMove);
            document.removeEventListener('mouseup', onEnd);
            document.removeEventListener('touchmove', onMove);
            document.removeEventListener('touchend', onEnd);

            const rect = element.getBoundingClientRect();
            const parent = element.offsetParent;
            let finalTop, finalLeft;

            if (parent && parent.tagName !== 'BODY' && parent.tagName !== 'HTML') {
                const parentRect = parent.getBoundingClientRect();
                finalTop = rect.top - parentRect.top;
                finalLeft = rect.left - parentRect.left;
            } else {
                finalTop = rect.top + window.scrollY;
                finalLeft = rect.left + window.scrollX;
            }

            if (dotNetCompRef) {
                try {
                    await dotNetCompRef.invokeMethodAsync('UpdatePosition', finalTop, finalLeft);
                    window.p11Js.log("FloatingPanel", `Position synced for ${elementId}`);
                } catch (err) {
                    console.error("[p11] UpdatePosition failed", err);
                }
            }
        };

        // --- Resize Logic (New Addition) ---
        const onResizeStart = (e) => {
            if (e.type === 'mousedown' && e.button !== 0) return;
            e.stopPropagation(); // Prevents dragging from starting simultaneously

            // Verhindert Textmarkierung während des Resizens
            document.body.style.userSelect = 'none';

            const clientX = e.type.startsWith('touch') ? e.touches[0].clientX : e.clientX;
            const clientY = e.type.startsWith('touch') ? e.touches[0].clientY : e.clientY;

            const rect = element.getBoundingClientRect();
            startWidth = rect.width;
            startHeight = rect.height;
            startX = clientX;
            startY = clientY;
            isResizing = true;

            if (e.type === 'mousedown') {
                document.addEventListener('mousemove', onResizeMove);
                document.addEventListener('mouseup', onResizeEnd);
            } else {
                document.addEventListener('touchmove', onResizeMove, { passive: false });
                document.addEventListener('touchend', onResizeEnd);
            }

            if (e.cancelable) e.preventDefault();
        };

        const onResizeMove = (e) => {
            if (!isResizing) return;

            const clientX = e.type.startsWith('touch') ? e.touches[0].clientX : e.clientX;
            const clientY = e.type.startsWith('touch') ? e.touches[0].clientY : e.clientY;

            const newWidth = startWidth + (clientX - startX);
            const newHeight = startHeight + (clientY - startY);

            // Minimum dimensions to prevent panel disappearance
            if (newWidth > 150) element.style.width = `${newWidth}px`;
            if (newHeight > 100) element.style.height = `${newHeight}px`;

            if (e.type === 'touchmove' && e.cancelable) e.preventDefault();
        };

        const onResizeEnd = async () => {
            if (!isResizing) return;
            isResizing = false;

            document.body.style.userSelect = ''; // Wieder erlauben

            document.removeEventListener('mousemove', onResizeMove);
            document.removeEventListener('mouseup', onResizeEnd);
            document.removeEventListener('touchmove', onResizeMove);
            document.removeEventListener('touchend', onResizeEnd);

            if (dotNetCompRef) {
                const rect = element.getBoundingClientRect();
                try {
                    await dotNetCompRef.invokeMethodAsync('UpdateSize', Math.round(rect.width), Math.round(rect.height));
                    window.p11Js.log("FloatingPanel", `Size synced for ${elementId}`);
                } catch (err) {
                    console.error("[p11] UpdateSize failed", err);
                }
            }
        };

        // 3. Attach listeners to the handle (header)
        header.addEventListener('mousedown', onStart);
        header.addEventListener('touchstart', onStart, { passive: false });

        if (resizeHandle) {
            resizeHandle.addEventListener('mousedown', onResizeStart);
            resizeHandle.addEventListener('touchstart', onResizeStart, { passive: false });
        }

        // 4. Register in local state for cleanup
        //this._activePanels.set(elementId, {
        //    element,
        //    header,
        //    onStart,
        //    dotNetCompRef
        //});
        this._activePanels.set(elementId, {
            element,
            header,
            resizeHandle, // Track handle for cleanup
            onStart,
            onResizeStart, // Track new start listener
            dotNetCompRef
        });

        window.p11Js.log("FloatingPanel", `Init complete: ${elementId}. Z-Index: ${element.style.zIndex}`);
    },

    /**
     * Releases all resources for a specific floating panel.
     */
    releaseFloatingPanel: function (elementId) {
        const state = this._activePanels.get(elementId);
        if (!state) {
            window.p11Js.log("FloatingPanel", `Release skipped: No state for ${elementId}`);
            return;
        }

        if (state.header && state.onStart) {
            state.header.removeEventListener('mousedown', state.onStart);
            state.header.removeEventListener('touchstart', state.onStart);
        }

        if (state.resizeHandle && state.onResizeStart) {
            state.resizeHandle.removeEventListener('mousedown', state.onResizeStart);
            state.resizeHandle.removeEventListener('touchstart', state.onResizeStart);
        }

        this._activePanels.delete(elementId);
        window.p11Js.log("FloatingPanel", `Resources released: ${elementId}`);
    }
};



///**
// * p11FloatingPanel.js
// * Part of the p11 UI Library.
// * Handles the drag-and-drop logic and initialization for Floating Panels.
// * All comments and documentation are in English.
// */

//import { UtilityFunctions } from './p11utility.js';

///* ========================================================================
//   PUBLIC EXPORTED FUNCTIONS
//   ======================================================================== */

//export const P11FloatingPanelFunctions = {

//    /**
//     * Finds the highest z-index among all floating panels to ensure the new one is on top.
//     * Required by C# UiUtilities / getHighestZIndex call.
//     * @param {string} currentPanelId - The ID of the panel to exclude from the calculation.
//     * @returns {number} The highest found z-index.
//     */
//    //getHighestZIndex: function (currentPanelId) {
//    //    if (window.p11Js) window.p11Js.log("FloatingPanel", "Calculating highest z-index.");
//    //    let maxZIndex = 0;
//    //    document.querySelectorAll('.p11-floating-panel').forEach(panel => {
//    //        if (panel.id === currentPanelId) return;
//    //        const zIndex = parseInt(window.getComputedStyle(panel).zIndex || '0');
//    //        if (!isNaN(zIndex) && zIndex > maxZIndex) {
//    //            maxZIndex = zIndex;
//    //        }
//    //    });
//    //    return maxZIndex;
//    //},
//    getHighestZIndex: function (currentPanelId) {
//        // Wir starten bei 1100, damit wir IMMER über Modalen (1050+) liegen
//        let maxZIndex = 1100;

//        document.querySelectorAll('.p11-floating-panel').forEach(panel => {
//            if (panel.id === currentPanelId) return;

//            const style = window.getComputedStyle(panel);
//            const zIndex = parseInt(style.zIndex);

//            if (!isNaN(zIndex) && zIndex > maxZIndex) {
//                maxZIndex = zIndex;
//            }
//        });

//        // Logge den finalen Wert, bevor er zurückgegeben wird
//        if (window.p11Js) {
//            window.p11Js.log("FloatingPanel", `Highest z-index calculated: ${maxZIndex}`);
//        }

//        return maxZIndex;
//    },

//    /**
//     * Alias for initializeFloatingPanel to match the C# call 'initDrag'.
//     * Handles both HTMLElements and ID-Strings.
//     */
//    initDrag: function (panelId, headerId, dotNetHelper, top, left) {
//        if (window.p11Js) window.p11Js.log("FloatingPanel", `initDrag triggered for ID: ${panelId}`);

//        // Handle case where headerId is actually the dotNetHelper (Blazor often sends strings for IDs)
//        let actualPanel = document.getElementById(panelId);
//        let actualHeader = null;
//        let actualHelper = dotNetHelper;

//        // If headerId is a string, it's the ID. If not, it might be the Helper.
//        if (typeof headerId === 'string') {
//            actualHeader = document.getElementById(headerId);
//        } else {
//            // Fallback: If no header ID provided, assume panelId + "header"
//            actualHeader = document.getElementById(panelId + "header") || document.getElementById(panelId + "Header");
//            actualHelper = headerId; // Shift argument
//        }

//        if (!actualPanel) {
//            console.error(`[p11] FloatingPanel: Panel element not found for ID '${panelId}'`);
//            return;
//        }
//        if (!actualHeader) {
//            console.error(`[p11] FloatingPanel: Header element not found for ID '${panelId}header'`);
//            // We use the panel itself as handle if no header is found to prevent complete failure
//            actualHeader = actualPanel;
//        }

//        return this.initializeFloatingPanel(actualPanel, actualHeader, actualHelper);
//    },

//    /**
//     * Initializes the floating panel's drag-and-drop functionality.
//     * Supports Mouse and Touch input.
//     * @param {HTMLElement} panel - The main panel element.
//     * @param {HTMLElement} header - The handle used for dragging.
//     * @param {object} dotNetHelper - DotNetObjectReference for position callbacks.
//     */
//    initializeFloatingPanel: function (panel, header, dotNetHelper) {
//        if (!panel || !header) return;

//        let isDragging = false;
//        let startX, startY;
//        let initialX, initialY;

//        const onStart = (e) => {
//            // Support Mouse and Touch
//            const clientX = e.type.startsWith('touch') ? e.touches[0].clientX : e.clientX;
//            const clientY = e.type.startsWith('touch') ? e.touches[0].clientY : e.clientY;

//            if (e.type === 'mousedown' && e.button !== 0) return;

//            // --- UNIVERSELLE KORREKTUR: Container vs. Dokument ---
//            const rect = panel.getBoundingClientRect();
//            const parent = panel.offsetParent;

//            // Wenn ein offsetParent existiert (nicht body/html), rechnen wir relativ zum Container.
//            // Wenn kein Container da ist (null oder body), rechnen wir absolut zum Dokument (inkl. Scroll).
//            if (parent && parent.tagName !== 'BODY' && parent.tagName !== 'HTML') {
//                const parentRect = parent.getBoundingClientRect();
//                initialX = rect.left - parentRect.left;
//                initialY = rect.top - parentRect.top;
//            } else {
//                initialX = rect.left + window.scrollX;
//                initialY = rect.top + window.scrollY;
//            }

//            isDragging = true;

//            // SOFORT-EFFEKT: Panel direkt im JS nach vorne holen (über Modale 1050+)
//            const currentMax = this.getHighestZIndex(panel.id);
//            panel.style.zIndex = currentMax + 1;

//            startX = clientX;
//            startY = clientY;

//            if (dotNetHelper && typeof dotNetHelper.invokeMethodAsync === 'function') {
//                dotNetHelper.invokeMethodAsync('ActivatePanel').catch(() => { });
//            }

//            if (e.type === 'mousedown') {
//                document.addEventListener('mousemove', onMove);
//                document.addEventListener('mouseup', onEnd);
//            } else {
//                document.addEventListener('touchmove', onMove, { passive: false });
//                document.addEventListener('touchend', onEnd);
//            }

//            if (window.p11Js) {
//                const mode = (parent && parent.tagName !== 'BODY') ? "Container-Relative" : "Document-Absolute";
//                window.p11Js.log("FloatingPanel", `Dragging active (${mode}). Pos: ${initialX}, ${initialY}`);
//            }

//            if (e.cancelable) e.preventDefault();
//        };

//        const onMove = (e) => {
//            if (!isDragging) return;
//            const clientX = e.type.startsWith('touch') ? e.touches[0].clientX : e.clientX;
//            const clientY = e.type.startsWith('touch') ? e.touches[0].clientY : e.clientY;

//            const dx = clientX - startX;
//            const dy = clientY - startY;

//            panel.style.left = `${initialX + dx}px`;
//            panel.style.top = `${initialY + dy}px`;
//            panel.style.right = 'auto';
//            panel.style.bottom = 'auto';
//            panel.style.margin = '0';
//        };

//        const onEnd = async () => {
//            if (!isDragging) return;
//            isDragging = false;

//            document.removeEventListener('mousemove', onMove);
//            document.removeEventListener('mouseup', onEnd);
//            document.removeEventListener('touchmove', onMove);
//            document.removeEventListener('touchend', onEnd);

//            // --- UNIVERSELLE KORREKTUR: Container vs. Dokument ---
//            const rect = panel.getBoundingClientRect();
//            const parent = panel.offsetParent;

//            let finalTop, finalLeft;

//            // Dieselbe Logik wie in onStart:
//            // Wenn wir in einem Container sind (position:relative), berechnen wir die Differenz.
//            if (parent && parent.tagName !== 'BODY' && parent.tagName !== 'HTML') {
//                const parentRect = parent.getBoundingClientRect();
//                finalTop = rect.top - parentRect.top;
//                finalLeft = rect.left - parentRect.left;
//            } else {
//                // Wenn wir frei auf der Seite liegen, addieren wir den Scroll-Offset für Blazor.
//                finalTop = rect.top + window.scrollY;
//                finalLeft = rect.left + window.scrollX;
//            }

//            if (dotNetHelper && typeof dotNetHelper.invokeMethodAsync === 'function') {
//                try {
//                    // Wir senden die berechneten Koordinaten (passend zum Context) zurück
//                    await dotNetHelper.invokeMethodAsync('UpdatePosition', finalTop, finalLeft);

//                    if (window.p11Js) {
//                        const mode = (parent && parent.tagName !== 'BODY') ? "Container-Relative" : "Document-Absolute";
//                        window.p11Js.log("FloatingPanel", `UpdatePosition sent (${mode}): Top=${finalTop}, Left=${finalLeft}`);
//                    }
//                } catch (err) {
//                    console.error("[p11] UpdatePosition failed", err);
//                }
//            }
//        };

//        header.addEventListener('mousedown', onStart);
//        header.addEventListener('touchstart', onStart, { passive: false });

//        panel._p11_cleanup_drag = () => {
//            header.removeEventListener('mousedown', onStart);
//            header.removeEventListener('touchstart', onStart);
//        };

//        if (window.p11Js) window.p11Js.log("FloatingPanel", `Initialization successful for ${panel.id}`);
//    },

//    /**
//     * Disposes the floating panel logic and removes event listeners.
//     */
//    //disposeFloatingPanel: function (panel) {
//    //    const panelElement = typeof panel === 'string' ? document.getElementById(panel) : panel;

//    //    if (panelElement && typeof panelElement._p11_cleanup_drag === 'function') {
//    //        panelElement._p11_cleanup_drag();
//    //        delete panelElement._p11_cleanup_drag;
//    //        if (window.p11Js) window.p11Js.log("FloatingPanel", "Resources cleaned up.");
//    //    }
//    //},
//    /**
//     * Disposes the floating panel logic and removes event listeners.
//     * @param {string|HTMLElement} panel - The ID or the element itself.
//     */
//    disposeFloatingPanel: function (panel) {
//        const panelElement = typeof panel === 'string' ? document.getElementById(panel) : panel;

//        if (panelElement) {
//            // Falls gerade noch ein Drag-Vorgang läuft, brechen wir ihn ab
//            // (indem wir die globalen mousemove/mouseup entfernen, falls sie existieren)
//            // Diese werden in initializeFloatingPanel temporär an document gehängt!

//            if (typeof panelElement._p11_cleanup_drag === 'function') {
//                panelElement._p11_cleanup_drag();
//                delete panelElement._p11_cleanup_drag;
//            }

//            if (window.p11Js) {
//                window.p11Js.log("FloatingPanel", `Resources cleaned up for ${panelElement.id || 'unknown'}.`);
//            }
//        }
//    },

//    /**
//     * Legacy Bridge Registration for Floating Panels.
//     * Maps the old TpcModalJs calls to the new modular functions.
//     */
//    registerLegacyFunctions: function () {
//        window.TpcModalJs = window.TpcModalJs || {};

//        window.TpcModalJs.initDrag = (p, h, d) => this.initDrag(p, h, d);
//        window.TpcModalJs.initializeFloatingPanel = (p, h, d) => this.initializeFloatingPanel(p, h, d);
//        window.TpcModalJs.disposeFloatingPanel = (p) => this.disposeFloatingPanel(p);
//        window.TpcModalJs.getHighestZIndex = (p) => this.getHighestZIndex(p);

//        if (window.p11Js) window.p11Js.log("FloatingPanel", "Legacy bridge registered.");
//    }
//};

//// Auto-register legacy support for backward compatibility
//P11FloatingPanelFunctions.registerLegacyFunctions();