import Vue from 'vue';
import { Subject } from 'rxjs';
import { createPopper } from '@popperjs/core/lib/popper-lite.js';
import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow.js';
import flip from '@popperjs/core/lib/modifiers/flip.js';
import { AppServiceBase, on, Util } from '@ibizstudio/runtime';
import './app-popover.less';
/**
 * 悬浮窗控制器实例
 *
 * @export
 * @class AppPopover
 */
export class AppPopover {
    /**
     * Creates an instance of AppPopover.
     * @memberof AppPopover
     */
    constructor() {
        /**
         * 是否显示悬浮窗
         *
         * @private
         * @type {boolean}
         * @memberof AppPopover
         */
        this.showPopper = false;
        /**
         * 是否在点击空白区域时自动关闭
         *
         * @private
         * @type {boolean}
         * @memberof AppPopover
         */
        this.isAutoClose = true;
        /**
         * 是否在点击空白区域时自动关闭
         *
         * @private
         * @type {boolean}
         * @memberof AppPopover
         */
        this.isMoveOutClose = false;
        /**
         * 当前显示层级
         *
         * @private
         * @type {number}
         * @memberof AppPopover
         */
        this.zIndex = 0;
        this.initBasicData();
        if (AppPopover.$popover) {
            return AppPopover.$popover;
        }
    }
    /**
     * 初始化基础数据
     *
     * @memberof AppPopover
     */
    initBasicData() {
        const appService = AppServiceBase.getInstance();
        this.store = appService.getAppStore();
        this.i18n = appService.getI18n();
        this.router = appService.getRouter();
    }
    /**
     * 初始化vue实例
     *
     * @private
     * @returns {void}
     * @memberof AppPopover
     */
    initVueExample(customClass, method) {
        const self = this;
        if (!self.store || !self.i18n) {
            self.initBasicData();
        }
        const container = document.createElement('div');
        container.className = 'app-popover-wrapper';
        on(container, 'click', () => {
            if (!this.showPopper || !this.isAutoClose) {
                return;
            }
            this.popperDestroy();
        });
        const div = document.createElement('div');
        container.appendChild(div);
        document.body.appendChild(container);
        this.vueExample = new Vue({
            el: div,
            store: this.store,
            router: this.router,
            i18n: this.i18n,
            data: { content: null, width: 300, height: 300 },
            methods: {
                click(e) {
                    e.stopPropagation();
                },
                mouseout(e) {
                    if (method == 'openPopover2') {
                        this.$apppopover.mouseOutDestory2();
                    }
                    else {
                        this.$apppopover.mouseOutDestory();
                    }
                },
            },
            render(h) {
                const content = this.content;
                container.style.zIndex = (self.zIndex - 1).toString();
                let customStyle = { 'z-index': self.zIndex };
                if (Util.isNumber(this.width)) {
                    customStyle.width = this.width + 'px';
                }
                if (Util.isNumber(this.height)) {
                    customStyle.height = this.height + 'px';
                }
                return (<div v-show='self.showPopper' style={customStyle} class={`app-popover app-popper${customClass ? ' ' + customClass : ''}`} on-click={this.click} on-mouseleave={this.mouseout}>
            {self.showPopper && content ? content(h) : null}
          </div>);
            },
        });
    }
    /**
     * 打开悬浮窗
     *
     * @param {MouseEvent} event 事件
     * @param {*} view 视图
     * @param {*} [context={}] 应用上下文参数
     * @param {*} data 行为参数
     * @param {Placement} position 显示位置
     * @param {boolean} isAutoClose 是否可自动关闭
     * @returns {Observable<any>}
     * @memberof AppPopover
     */
    openPop(event, view, context = {}, data, position, isAutoClose, navdatas = []) {
        const subject = new Subject();
        if (!event) {
            console.error(view.$t('components.appmessagepopover.errorreturn'));
            return subject.asObservable();
        }
        if (!view.width)
            view.width = 300;
        if (!view.height)
            view.height = 300;
        this.openPopover(event, (h) => {
            return h(view.viewname, {
                props: {
                    staticProps: { viewDefaultUsage: false, noViewCaption: true },
                    dynamicProps: { viewdata: JSON.stringify(context), viewparam: JSON.stringify(data), navdatas: navdatas },
                },
                on: {
                    close: (result) => {
                        subject.next({ ret: 'OK', datas: result });
                        subject.complete();
                        subject.unsubscribe();
                        this.popperDestroy();
                    },
                },
            });
        }, position, isAutoClose, view.width, view.height);
        return subject.asObservable();
    }
    /**
     * 打开悬浮窗
     *
     * @param {*} event
     * @param {(h: CreateElement) => any} [content]
     * @param {Placement} [position='left']
     * @param {boolean} [isAutoClose=true]
     * @param {number} [width=300]
     * @param {number} [height=300]
     * @memberof AppPopover
     */
    openPopover(event, content, position = 'left-end', isAutoClose = true, width = 300, height = 300, customClass) {
        // 阻止事件冒泡
        event.stopPropagation();
        const element = event.toElement || event.srcElement;
        if (!this.vueExample) {
            this.initVueExample(customClass);
        }
        this.popperDestroy();
        const zIndex = this.vueExample.$store.getters.getZIndex();
        if (zIndex) {
            this.zIndex = zIndex + 100;
            this.vueExample.$store.commit('updateZIndex', this.zIndex);
        }
        // 是否可自动关闭
        this.isAutoClose = isAutoClose;
        // 更新vue实例内容
        this.showPopper = true;
        Object.assign(this.vueExample.$data, { content, width, height, zIndex: this.zIndex });
        const el = this.vueExample.$el;
        this.popperExample = createPopper(element, el, {
            placement: position,
            strategy: 'absolute',
            modifiers: [preventOverflow, flip],
        });
        this.vueExample.$forceUpdate();
    }
    /**
     * 打开悬浮窗(自定义modefiers)
     *
     * @param {*} event
     * @param {(h: CreateElement) => any} [content]
     * @param {Placement} [position='left-end']
     * @param {boolean} [isAutoClose=true]
     * @param {number} [width]
     * @param {number} [height]
     * @param {*} [customClass]
     * @param {any[]} [modifiers=[]]
     * @memberof AppPopover
     */
    openPopover2(event, content, position = 'left-end', isAutoClose = true, isMoveOutClose = false, width, height, customClass, modifiers = []) {
        // 阻止事件冒泡
        event.stopPropagation();
        const element = event.toElement || event.srcElement;
        if (!this.vueExample) {
            this.initVueExample(customClass, 'openPopover2');
        }
        this.popperDestroy();
        const zIndex = this.vueExample.$store.getters.getZIndex();
        if (zIndex) {
            this.zIndex = zIndex + 100;
        }
        // 是否可自动关闭
        this.isAutoClose = isAutoClose;
        this.isMoveOutClose = isMoveOutClose;
        // 更新vue实例内容
        this.showPopper = true;
        Object.assign(this.vueExample.$data, { content, width: width, height: height, zIndex: this.zIndex });
        const el = this.vueExample.$el;
        this.popperExample = createPopper(element, el, {
            placement: position,
            strategy: 'absolute',
            modifiers: [...modifiers],
        });
        this.vueExample.$forceUpdate();
    }
    /**
     * 销毁popper(带回填数据)
     *
     * @memberof AppPopover
     */
    popperDestroy() {
        if (this.popperExample) {
            this.popperExample.destroy();
            if (this.zIndex !== 0) {
                const zIndex = this.zIndex;
                this.vueExample.$store.commit('updateZIndex', zIndex - 100);
                this.zIndex = 0;
            }
            this.showPopper = false;
            this.vueExample.$forceUpdate();
        }
    }
    /**
     * 销毁popper2(带回填数据)
     *
     * @memberof AppPopover
     */
    popperDestroy2() {
        if (this.popperExample) {
            this.popperExample.destroy();
            if (this.zIndex !== 0) {
                this.zIndex = 0;
            }
            this.showPopper = false;
            this.vueExample.$forceUpdate();
        }
    }
    /**
     * 销毁popper(当鼠标移出时)
     *
     * @memberof AppPopover
     */
    mouseOutDestory() {
        if (this.showPopper && this.isMoveOutClose) {
            this.popperDestroy();
        }
    }
    /**
     * 销毁popper2(当鼠标移出时)
     *
     * @memberof AppPopover
     */
    mouseOutDestory2() {
        if (this.showPopper && this.isMoveOutClose) {
            this.popperDestroy2();
        }
    }
    /**
     * 获取实例
     *
     * @static
     * @memberof AppPopover
     */
    static getInstance() {
        return AppPopover.$popover;
    }
}
/**
 * 实例
 *
 * @private
 * @static
 * @memberof AppPopover
 */
AppPopover.$popover = new AppPopover();
