"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.messageProviderInjectionKey = exports.messageApiInjectionKey = void 0;
const vue_1 = require("vue");
const seemly_1 = require("seemly");
const _utils_1 = require("../../_utils");
const _mixins_1 = require("../../_mixins");
const MessageEnvironment_1 = require("./MessageEnvironment");
exports.messageApiInjectionKey = Symbol('messageApi');
const messageProviderProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { to: [String, Object], duration: {
        type: Number,
        default: 3000
    }, max: Number });
exports.messageProviderInjectionKey = Symbol('messageProvider');
exports.default = vue_1.defineComponent({
    name: 'MessageProvider',
    props: messageProviderProps,
    setup(props) {
        const { mergedClsPrefixRef } = _mixins_1.useConfig(props);
        const messageListRef = vue_1.ref([]);
        const messageRefs = vue_1.ref({});
        const api = {
            info(content, options) {
                return create(content, Object.assign(Object.assign({}, options), { type: 'info' }));
            },
            success(content, options) {
                return create(content, Object.assign(Object.assign({}, options), { type: 'success' }));
            },
            warning(content, options) {
                return create(content, Object.assign(Object.assign({}, options), { type: 'warning' }));
            },
            error(content, options) {
                return create(content, Object.assign(Object.assign({}, options), { type: 'error' }));
            },
            loading(content, options) {
                return create(content, Object.assign(Object.assign({}, options), { type: 'loading' }));
            },
            destroyAll
        };
        vue_1.provide(exports.messageProviderInjectionKey, {
            props,
            mergedClsPrefixRef
        });
        vue_1.provide(exports.messageApiInjectionKey, api);
        function create(content, options = {}) {
            const key = seemly_1.createId();
            const messageReactive = vue_1.reactive(Object.assign(Object.assign({}, options), { content,
                key, destroy: () => {
                    messageRefs.value[key].hide();
                } }));
            const { max } = props;
            if (max && messageListRef.value.length >= max) {
                messageListRef.value.shift();
            }
            messageListRef.value.push(messageReactive);
            return messageReactive;
        }
        function handleAfterLeave(key) {
            messageListRef.value.splice(messageListRef.value.findIndex((message) => message.key === key), 1);
            // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
            delete messageRefs.value[key];
        }
        function destroyAll() {
            Object.values(messageRefs.value).forEach((messageInstRef) => {
                messageInstRef.hide();
            });
        }
        return Object.assign({
            mergedClsPrefix: mergedClsPrefixRef,
            messageRefs,
            messageList: messageListRef,
            handleAfterLeave
        }, api);
    },
    render() {
        var _a;
        return (vue_1.h(vue_1.Fragment, null,
            vue_1.renderSlot(this.$slots, 'default'),
            this.messageList.length ? (vue_1.h(vue_1.Teleport, { to: (_a = this.to) !== null && _a !== void 0 ? _a : 'body' },
                vue_1.h("div", { class: `${this.mergedClsPrefix}-message-container`, key: "message-container" }, this.messageList.map((message) => {
                    return (vue_1.h(MessageEnvironment_1.default, Object.assign({ ref: ((inst) => {
                            if (inst) {
                                this.messageRefs[message.key] = inst;
                            }
                        }), internalKey: message.key, onInternalAfterLeave: this.handleAfterLeave }, _utils_1.omit(message, ['destroy'], undefined), { duration: message.duration === undefined
                            ? this.duration
                            : message.duration })));
                })))) : null));
    }
});
