import React from "react";

export const PortalContainerContext = React.createContext<HTMLElement | undefined>(undefined);

function findOrCreatePortalContainer(root: ShadowRoot | Document, id = "plugin-portal-container") {
    // Determine the actual parent element to search and append to
    const parentElement = root instanceof Document ? root.body : root;

    // look only at direct children
    for (const child of Array.from(parentElement.children)) {
        if (child instanceof HTMLElement && child.id === id) {
            return child;
        }
    }
    // not found → create
    const container = document.createElement("div");
    container.id = id;
    parentElement.appendChild(container);
    return container;
}

export function PortalContainerProvider({
    children,
    id = "plugin-portal-container",
}: {
    children: React.ReactNode;
    id?: string;
}) {
    const inherited = React.useContext(PortalContainerContext);
    const ref = React.useRef<HTMLDivElement>(null);
    const [container, setContainer] = React.useState<HTMLElement | null | undefined>(
        inherited || undefined
    );

    React.useEffect(() => {
        // If a parent already provides a portal container, inherit it
        if (inherited) {
            setContainer(inherited);
            return;
        }
        if (ref.current) {
            const root = ref.current.getRootNode();
            if (root instanceof ShadowRoot || root instanceof Document) {
                const container = findOrCreatePortalContainer(root, id);
                setContainer(container);
            } else {
                setContainer(null);
            }
        }
    }, [id, inherited]);

    // If container not discovered yet → render hidden marker only
    if (container === undefined) {
        return <div ref={ref} style={{ display: "none" }} />;
    }

    // Once container is resolved (null or HTMLElement) → provide it
    return (
        <PortalContainerContext.Provider value={container || undefined}>
            {children}
        </PortalContainerContext.Provider>
    );
}

export function usePortalContainer() {
    return React.useContext(PortalContainerContext);
}