import { PureComponent, Fragment, JSX } from 'react';
import { makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';

type ModalElement = {
	id: string;
	element: JSX.Element;
};

export class ModalsStore {
	@observable.shallow globalElements: ModalElement[] = [];

	constructor() {
		makeObservable(this);
	}

	showGlobalElement<T = void>(_element: JSX.Element | ((close: (result: T) => void) => JSX.Element)): Promise<T> {
		return new Promise<T>(resolve => {
			let onClose: (result: T) => void = () => {};
			const closeWrapper = (result: T) => {
				onClose(result);
			};
			const element = typeof _element === 'function' ? _element(closeWrapper) : _element;
			const id = Math.random().toString(36).substring(2, 15);
			this.globalElements.push({ id, element });
			const doClose = (result: T) => {
				this.globalElements = this.globalElements.filter(el => el.id !== id);
				resolve(result);
			};
			onClose = doClose;
			return doClose;
		});
	}
}

@observer
export class Modals extends PureComponent<{ store: ModalsStore }> {
	render() {
		return (
			<>
				{this.props.store.globalElements.map(el => (
					<Fragment key={el.id}>{el.element}</Fragment>
				))}
			</>
		);
	}
}

export const modalsStore = new ModalsStore();
