/**
 * p11Offcanvas.js
 * Part of the p11 UI Library.
 * Handles Bootstrap Offcanvas specific logic and Blazor integration.
 * All comments and documentation are in English.
 */

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

/* ========================================================================
   INTERNAL STATE
   ======================================================================== */

// Map to keep track of active offcanvas instances and their event handlers
const offcanvasInstances = new Map();

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

export const P11OffcanvasFunctions = {

    /**
     * Initializes a Bootstrap Offcanvas instance and sets up event listeners.
     * @param {HTMLElement} elementRef - Reference to the offcanvas DOM element.
     * @param {object} dotNetHelper - DotNetObjectReference for callbacks.
     */
    initializeOffcanvas: function (elementRef, dotNetHelper) {
        if (!elementRef) {
            UtilityFunctions.error("initializeOffcanvas: ElementRef is null or undefined.");
            return null;
        }

        if (!window.bootstrap?.Offcanvas) {
            UtilityFunctions.error("initializeOffcanvas: Bootstrap Offcanvas library not found.");
            return null;
        }

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

        if (!instance) {
            try {
                // Initializing with an empty options object to prevent 'backdrop' of undefined errors
                instance = new window.bootstrap.Offcanvas(elementRef, {});
                UtilityFunctions.log(`Created new Bootstrap Offcanvas instance for: ${elementRef.id}`);

                // Define the hidden event handler
                const hiddenHandler = () => {
                    UtilityFunctions.log(`Offcanvas ${elementRef.id || 'unknown'} hidden. Notifying Blazor via OnBootstrapHidden.`);
                    if (dotNetHelper && dotNetHelper.invokeMethodAsync) {
                        dotNetHelper.invokeMethodAsync('OnBootstrapHidden')
                            .catch(err => UtilityFunctions.error("Error in OnBootstrapHidden callback", err));
                    }
                };

                // Attach the listener
                elementRef.addEventListener('hidden.bs.offcanvas', hiddenHandler);

                // Store instance and handler for cleanup
                offcanvasInstances.set(elementRef.id || elementRef, {
                    instance,
                    dotNetHelper,
                    hiddenHandler,
                    element: elementRef
                });

                UtilityFunctions.log(`Offcanvas successfully initialized and tracked for element ID: ${elementRef.id}`);
            } catch (err) {
                UtilityFunctions.error(`Failed to create Offcanvas instance for ${elementRef.id}:`, err);
            }
        } else {
            UtilityFunctions.log(`Reusing existing Offcanvas instance for: ${elementRef.id}`);
            // Update the dotNetHelper in the map if the component re-rendered
            const entry = offcanvasInstances.get(elementRef.id || elementRef);
            if (entry) {
                entry.dotNetHelper = dotNetHelper;
            }
        }

        return instance;
    },

    /**
     * Disposes of an offcanvas instance and removes its event listeners.
     * @param {string|HTMLElement} elementIdOrRef - The ID or reference of the offcanvas.
     */
    disposeOffcanvas: function (elementIdOrRef) {
        // Find entry by ID or by the element itself
        const entry = offcanvasInstances.get(elementIdOrRef);

        if (entry) {
            const { instance, hiddenHandler, element } = entry;

            if (element && hiddenHandler) {
                element.removeEventListener('hidden.bs.offcanvas', hiddenHandler);
                UtilityFunctions.log(`Removed event listener for ${elementIdOrRef}.`);
            }

            if (instance) {
                instance.dispose();
                UtilityFunctions.log(`Bootstrap instance disposed for ${elementIdOrRef}.`);
            }

            offcanvasInstances.delete(elementIdOrRef);
            UtilityFunctions.log(`Offcanvas ${elementIdOrRef} removed from tracking map.`);
        } else {
            UtilityFunctions.log(`disposeOffcanvas: No active instance found for ${elementIdOrRef} in tracking map.`);
        }
    },

    /**
     * Explicitly shows an offcanvas.
     * @param {HTMLElement|Object} elementRef - Reference to the DOM element or the instance.
     */
    showOffcanvas: function (elementRef) {
        if (!elementRef) {
            UtilityFunctions.error("showOffcanvas: elementRef is null or undefined.");
            return;
        }

        let targetElement = elementRef;
        let instance = window.bootstrap.Offcanvas.getInstance(targetElement);

        if (!instance) {
            const id = targetElement.id || "unknown-id";
            UtilityFunctions.log(`showOffcanvas: No instance found for ${id}. Initializing now.`);
            try {
                instance = new window.bootstrap.Offcanvas(targetElement, {});
            } catch (e) {
                UtilityFunctions.error(`showOffcanvas: Failed to initialize Bootstrap Offcanvas for ${id}`, e);
                return;
            }
        }

        if (instance) {
            // --- DIESES LOG FEHLTE ---
            UtilityFunctions.log(`Calling .show() for Offcanvas: ${targetElement.id || 'unknown'}`);
            instance.show();
        }
    },

    /**
     * Explicitly hides an offcanvas.
     * @param {HTMLElement} elementRef - Reference to the offcanvas DOM element.
     */
    hideOffcanvas: function (elementRef) {
        if (!elementRef) return;
        const instance = window.bootstrap.Offcanvas.getInstance(elementRef);
        if (instance) {
            UtilityFunctions.log(`Calling .hide() for Offcanvas: ${elementRef.id}`);
            instance.hide();
        } else {
            UtilityFunctions.log(`hideOffcanvas: No active instance found for ${elementRef.id}`);
        }
    },

    /**
     * Legacy Bridge Registration for Offcanvas.
     * Maps these functions back to window.TpcModalJs for backward compatibility.
     */
    registerLegacyFunctions: function () {
        if (!window.TpcModalJs) window.TpcModalJs = {};

        window.TpcModalJs.initializeOffcanvas = (el, d) => this.initializeOffcanvas(el, d);
        window.TpcModalJs.disposeOffcanvas = (id) => this.disposeOffcanvas(id);
        window.TpcModalJs.showOffcanvas = (el) => this.showOffcanvas(el);
        window.TpcModalJs.hideOffcanvas = (el) => this.hideOffcanvas(el);

        UtilityFunctions.log("Legacy Offcanvas functions registered in p11Offcanvas.js.");
    }
};

// Initial registration of legacy support
P11OffcanvasFunctions.registerLegacyFunctions();