let resizeObservers = new Map();
let debounceTimers = new Map();
const DEBOUNCE_TIME = 150;

export function initializeResizeObserver(dotnetRef, contentContainer, parentContainer) {
    try {
        if (!dotnetRef || !contentContainer || !parentContainer) {
            console.warn('Invalid parameters for initializeResizeObserver');
            return;
        }

        cleanupExistingObserver(contentContainer);
        cleanupExistingObserver(parentContainer);

        const observer = new ResizeObserver(entries => {
            const timerId = debounceTimers.get(contentContainer);
            if (timerId) {
                clearTimeout(timerId);
            }

            const newTimerId = setTimeout(() => {
                if (!contentContainer.isConnected || !parentContainer.isConnected) {
                    return;
                }

                const contentHeight = contentContainer.getBoundingClientRect().height;
                const parentHeight = parentContainer.getBoundingClientRect().height;
                dotnetRef.invokeMethodAsync('OnResize', contentHeight, parentHeight);
            }, DEBOUNCE_TIME);

            debounceTimers.set(contentContainer, newTimerId);
        });

        observer.observe(contentContainer);
        observer.observe(parentContainer);
        resizeObservers.set(contentContainer, observer);

        return {
            dispose: () => {
                cleanupExistingObserver(contentContainer);
                cleanupExistingObserver(parentContainer);
            }
        };
    } catch (error) {
        console.error('Error in initializeResizeObserver:', error);
    }
}

export function initializeWidthObserver(dotnetRef, container) {
    try {
        if (!dotnetRef || !container) {
            console.warn('Invalid parameters for initializeWidthObserver');
            return;
        }

        cleanupExistingObserver(container);

        const observer = new ResizeObserver(entries => {
            const timerId = debounceTimers.get(container);
            if (timerId) {
                clearTimeout(timerId);
            }

            const newTimerId = setTimeout(() => {
                if (!container.isConnected) {
                    return;
                }

                const width = container.getBoundingClientRect().width;
                dotnetRef.invokeMethodAsync('OnWidthChange', width);
            }, DEBOUNCE_TIME);

            debounceTimers.set(container, newTimerId);
        });

        observer.observe(container);
        resizeObservers.set(container, observer);

        return {
            dispose: () => {
                cleanupExistingObserver(container);
            }
        };
    } catch (error) {
        console.error('Error in initializeWidthObserver:', error);
    }
}

export function disconnectResizeObserver(containerRefs) {
    try {
        if (!containerRefs?.length) {
            return;
        }

        containerRefs.forEach(container => {
            cleanupExistingObserver(container);
        });
    } catch (error) {
        console.error('Error in disconnectResizeObserver:', error);
    }
}

function cleanupExistingObserver(container) {
    const timerId = debounceTimers.get(container);
    if (timerId) {
        clearTimeout(timerId);
        debounceTimers.delete(container);
    }

    const observer = resizeObservers.get(container);
    if (observer) {
        observer.disconnect();
        resizeObservers.delete(container);
    }
}

export function getElementWidth(element) {
    try {
        if (!element?.getBoundingClientRect) {
            return 0;
        }
        return element.getBoundingClientRect().width;
    } catch (error) {
        console.error('Error in getElementWidth:', error);
        return 0;
    }
}