import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';

const UIContext = createContext({ dark: false, dir: 'ltr', vars: {}, portalClassName: '' });

export function useUI() {
	return useContext(UIContext);
}

/**
 * Provides theme information to design-system components.
 *
 * @param {Object}  props
 * @param {boolean} [props.dark]          Dark theme.
 * @param {string}  [props.dir]           'ltr' | 'rtl' (defaults to the document direction).
 * @param {Object}  [props.vars]          CSS custom properties (see theme.js brandVars()).
 * @param {string}  [props.portalClassName] Extra class on portal containers.
 */
export function UIProvider({ dark = false, dir, vars = {}, portalClassName = '', children }) {
	const resolvedDir = dir || (typeof document !== 'undefined' && document.documentElement.dir === 'rtl' ? 'rtl' : 'ltr');
	const value = useMemo(
		() => ({ dark, dir: resolvedDir, vars, portalClassName }),
		[dark, resolvedDir, vars, portalClassName]
	);
	return <UIContext.Provider value={value}>{children}</UIContext.Provider>;
}

/**
 * Class name + style for a design-system root element.
 */
export function uiRootProps(ctx, extraClass = '') {
	return {
		className: ['bp-ui', ctx.dark ? 'bp-dark' : '', extraClass].filter(Boolean).join(' '),
		style: ctx.vars,
		dir: ctx.dir,
	};
}

/**
 * Renders children into a body-level container that carries the design-system
 * scope (.bp-ui + theme + brand variables), so overlays keep their styles even
 * though they live outside the widget/app root.
 */
export function Portal({ children }) {
	const ctx = useUI();
	const [node, setNode] = useState(null);

	useEffect(() => {
		const el = document.createElement('div');
		el.setAttribute('data-bp-portal', '');
		document.body.appendChild(el);
		setNode(el);
		return () => {
			document.body.removeChild(el);
		};
	}, []);

	useEffect(() => {
		if (!node) return;
		const root = uiRootProps(ctx, ['bp-portal', ctx.portalClassName].filter(Boolean).join(' '));
		node.className = root.className;
		node.setAttribute('dir', root.dir);
		node.removeAttribute('style');
		Object.entries(root.style || {}).forEach(([k, v]) => node.style.setProperty(k, String(v)));
	}, [node, ctx]);

	return node ? createPortal(children, node) : null;
}
