import { jsx } from "react/jsx-runtime";
import react, { Fragment, useLayoutEffect, useRef, useState } from "react";
import { FormProvider, Observer, applyMiddleware, createForm, isBool, isFn, isNum, isStr, observer, toJS } from "@tachybase/schema";
import { Modal } from "antd";
import { createPortal } from "react-dom";
import { createPortalProvider, createPortalRoot, loading, usePrefixCls, useToken } from "../__builtins__/index.mjs";
import { GlobalThemeProvider } from "../../../style/theme/index.mjs";
const isModalTitle = (props)=>isNum(props) || isStr(props) || isBool(props) || /*#__PURE__*/ react.isValidElement(props);
const getModelProps = (props)=>{
    if (isModalTitle(props)) return {
        title: props
    };
    return props;
};
function FormDialog(title, id, renderer, theme) {
    if (isFn(id) || /*#__PURE__*/ react.isValidElement(id)) {
        theme = renderer;
        renderer = id;
        id = 'form-dialog';
    }
    const env = {
        host: document.createElement('div'),
        form: null,
        promise: null,
        openMiddlewares: [],
        confirmMiddlewares: [],
        cancelMiddlewares: []
    };
    const root = createPortalRoot(env.host, id);
    const props = getModelProps(title);
    const modal = {
        ...props,
        afterClose: ()=>{
            var _props_afterClose;
            null == props || null == (_props_afterClose = props.afterClose) || _props_afterClose.call(props);
            root.unmount();
        }
    };
    const DialogContent = observer(()=>/*#__PURE__*/ jsx(Fragment, {
            children: isFn(renderer) ? renderer(env.form) : renderer
        }), {
        displayName: 'DialogContent'
    });
    const renderDialog = function() {
        let open = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : true, resolve = arguments.length > 1 ? arguments[1] : void 0, reject = arguments.length > 2 ? arguments[2] : void 0;
        const { form } = env;
        if (!form) return null;
        return /*#__PURE__*/ jsx(GlobalThemeProvider, {
            theme: theme,
            children: /*#__PURE__*/ jsx(Observer, {
                children: ()=>{
                    const { token } = useToken();
                    return /*#__PURE__*/ jsx(Modal, {
                        zIndex: token.zIndexPopupBase + 1000,
                        ...modal,
                        open: open,
                        confirmLoading: form.submitting,
                        onCancel: (e)=>{
                            var _modal_onCancel;
                            if ((null == modal ? void 0 : null == (_modal_onCancel = modal.onCancel) ? void 0 : _modal_onCancel.call(modal, e)) !== false) null == reject || reject();
                        },
                        onOk: async (e)=>{
                            var _modal_onOk;
                            if ((null == modal ? void 0 : null == (_modal_onOk = modal.onOk) ? void 0 : _modal_onOk.call(modal, e)) !== false) null == resolve || resolve();
                        },
                        children: /*#__PURE__*/ jsx(FormProvider, {
                            form: form,
                            children: /*#__PURE__*/ jsx(DialogContent, {})
                        })
                    });
                }
            })
        });
    };
    document.body.appendChild(env.host);
    const formDialog = {
        forOpen: (middleware)=>{
            if (isFn(middleware)) env.openMiddlewares.push(middleware);
            return formDialog;
        },
        forConfirm: (middleware)=>{
            if (isFn(middleware)) env.confirmMiddlewares.push(middleware);
            return formDialog;
        },
        forCancel: (middleware)=>{
            if (isFn(middleware)) env.cancelMiddlewares.push(middleware);
            return formDialog;
        },
        open: async (props)=>{
            if (env.promise) return env.promise;
            env.promise = new Promise(async (resolve, reject)=>{
                try {
                    props = await loading(modal.loadingText, ()=>applyMiddleware(props, env.openMiddlewares));
                    env.form = env.form || createForm(props);
                } catch (e) {
                    reject(e);
                }
                root.render(()=>renderDialog(true, ()=>{
                        var _env_form;
                        null == (_env_form = env.form) || _env_form.submit(async ()=>{
                            var _env_form;
                            await applyMiddleware(env.form, env.confirmMiddlewares);
                            resolve(toJS(null == (_env_form = env.form) ? void 0 : _env_form.values));
                            formDialog.close();
                        }).catch(()=>{});
                    }, async ()=>{
                        await loading(modal.loadingText, ()=>applyMiddleware(env.form, env.cancelMiddlewares));
                        formDialog.close();
                    }));
            });
            return env.promise;
        },
        close: ()=>{
            if (!env.host) return;
            root.render(()=>renderDialog(false));
        }
    };
    return formDialog;
}
const DialogFooter = (props)=>{
    const ref = useRef(null);
    const [footer, setFooter] = useState();
    const footerRef = useRef();
    const prefixCls = usePrefixCls('modal');
    useLayoutEffect(()=>{
        var _ref_current;
        const content = null == (_ref_current = ref.current) ? void 0 : _ref_current.closest(".".concat(prefixCls, "-content"));
        if (content) {
            if (!footerRef.current) {
                footerRef.current = content.querySelector(".".concat(prefixCls, "-footer"));
                if (!footerRef.current) {
                    footerRef.current = document.createElement('div');
                    footerRef.current.classList.add("".concat(prefixCls, "-footer"));
                    content.appendChild(footerRef.current);
                }
            }
            setFooter(footerRef.current);
        }
    }, [
        prefixCls
    ]);
    footerRef.current = footer;
    return /*#__PURE__*/ jsx("div", {
        ref: ref,
        style: {
            display: 'none'
        },
        children: footer && /*#__PURE__*/ createPortal(props.children, footer)
    });
};
FormDialog.Footer = DialogFooter;
FormDialog.Portal = createPortalProvider('form-dialog');
const form_dialog = FormDialog;
export { FormDialog, form_dialog as default };
