import * as React from 'react';
import { createPortal } from 'react-dom';
import { useDispatch, useSelector } from 'react-redux';
import Dialog from '../../../../components/Dialog';
import { PopupHideWindow } from '../../../../Redux/ActionsReducers/PopupRedux';
import { resolveContainerElement } from '../../../../Utilities/resolveContainerElement';
import { useAdaptable } from '../../../AdaptableContext';
import { ExternalRenderer } from '../../ExternalRenderer';
import { PanelWithImage } from '../../Panels/PanelWithImage';
import { getMiddlePosition, getWindowPopupSize } from '../Utilities';
import { WINDOW_SHOW_TRANSPOSED_VIEW, windowFactory } from './windowFactory';
const NoopComponent = () => {
    return React.createElement(React.Fragment, null);
};
export const CUSTOM_WINDOW_FACTORY_ID = 'CUSTOM_WINDOW_FACTORY_ID';
/**
 * Portals children into a target container element.
 * Monitors the container with a MutationObserver — if the container is removed
 * from the DOM, `onContainerRemoved` is called so callers can clean up React/Redux state.
 */
const ContainerPortal = ({ container, onContainerRemoved, children }) => {
    React.useEffect(() => {
        // If the container is already detached, clean up immediately
        if (!document.contains(container)) {
            onContainerRemoved();
            return;
        }
        const observer = new MutationObserver(() => {
            if (!document.contains(container)) {
                onContainerRemoved();
                observer.disconnect();
            }
        });
        // Observe the entire document body for subtree removals
        observer.observe(document.body, { childList: true, subtree: true });
        return () => {
            observer.disconnect();
        };
    }, [container, onContainerRemoved]);
    return createPortal(children, container);
};
export const WindowPopups = () => {
    const [windowModalSettings, setWindowModalSettings] = React.useState({});
    const adaptable = useAdaptable();
    const dispatch = useDispatch();
    const windowItems = useSelector((state) => state.Popup.WindowPopup.PopupList);
    return (React.createElement(React.Fragment, null, windowItems?.map((windowItem) => {
        let Component = windowFactory[windowItem.FactoryId] ?? null;
        const { windowModalProps, ...restPopupProps } = windowItem?.PopupProps ?? {};
        const handleDismiss = () => {
            dispatch(PopupHideWindow(windowItem.Id));
        };
        const size = windowModalSettings?.[windowItem.Id]?.size ??
            windowItem?.PopupProps?.size ??
            getWindowPopupSize();
        const position = windowModalSettings?.[windowItem.Id]?.position ??
            windowItem?.PopupProps?.position ??
            getMiddlePosition(size);
        let componentNode = null;
        if (!Component &&
            (windowItem.PopupProps.render || windowItem.PopupProps.frameworkComponent)) {
            componentNode = (React.createElement(ExternalRenderer, { style: { height: '100%' }, render: windowItem.PopupProps.render, frameworkComponent: windowItem.PopupProps.frameworkComponent, onDestroy: windowItem.PopupProps.onFrameworkComponentDestroyed }));
        }
        else {
            Component = Component ?? NoopComponent;
            componentNode = (React.createElement(Component, { api: adaptable.api, onDismiss: handleDismiss, popupProps: restPopupProps }));
        }
        // Transposed View: portal into custom container if configured
        if (windowItem.FactoryId === WINDOW_SHOW_TRANSPOSED_VIEW) {
            const transposedContainer = resolveContainerElement(adaptable.adaptableOptions?.containerOptions?.transposedViewContainer, adaptable.api.internalApi.buildBaseContext());
            if (transposedContainer) {
                return (React.createElement(ContainerPortal, { key: windowItem.Id, container: transposedContainer, onContainerRemoved: handleDismiss }, componentNode));
            }
        }
        return (React.createElement(Dialog, { "data-name": windowItem.Id, className: "ab-Window-Modal twa:h-full twa:p-0", key: windowItem.Id, windowModal: true, windowModalProps: {
                ...windowModalProps,
                onChange: (settings) => {
                    setWindowModalSettings((settingsMap) => ({
                        ...settingsMap,
                        [windowItem.Id]: settings,
                    }));
                },
                handleSelector: '.ab-Window-Modal .ab-Panel__header',
                size: size,
                position: position,
            }, fixed: false, onDismiss: handleDismiss, isOpen: true, showCloseButton: true },
            React.createElement(PanelWithImage, { className: "twa:h-full", bodyProps: { className: 'twa:h-full twa:p-0' }, header: windowItem.Title, glyphicon: windowItem.Icon, variant: "primary" }, componentNode)));
    })));
};
