import Vue from 'vue';
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 arrow from '@popperjs/core/lib/modifiers/arrow.js';
import offset from '@popperjs/core/lib/modifiers/offset.js';
import { isFunc } from 'qx-util';
import { AppServiceBase } from '@ibizstudio/runtime';
import './ibz-tooltip.less';
/**
 * tooltip工具类
 *
 * @export
 * @class IBzTooltipUtil
 */
export class IBzTooltipUtil {
    /**
     * Creates an instance of IBzTooltipUtil.
     * @param {*} c
     * @memberof IBzTooltipUtil
     */
    constructor(c) {
        /**
         * Prop承载容器
         *
         * @private
         * @type {HTMLDivElement}
         * @memberof IBzTooltipUtil
         */
        this.container = document.createElement('div');
        /**
         * 是否显示tooltip
         *
         * @private
         * @memberof IBzTooltipUtil
         */
        this.showTip = false;
        /**
         * 显示层级
         *
         * @private
         * @memberof IBzTooltipUtil
         */
        this.zIndex = 100;
        /**
         * 鼠标是否悬浮
         *
         * @memberof IBzTooltipUtil
         */
        this.isHover = false;
        /**
         * 定制器
         *
         * @type {*}
         * @memberof IBzTooltipUtil
         */
        this.timer = null;
        /**
         * Vue状态管理器
         *
         * @type {Store}
         * @memberof IBzTooltipUtil
         */
        this.store = null;
        this.c = c;
        const fn = offset.fn;
        offset.fn = (data) => {
            if (data) {
                Object.assign(data.options, { offset: [4, 4] });
            }
            fn(data);
        };
        this.initStore();
    }
    /**
     * 鼠标移入
     *
     * @memberof IBzTooltipUtil
     */
    mouseenter() {
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = null;
        }
        this.isHover = true;
    }
    /**
     * 鼠标移出
     *
     * @memberof IBzTooltipUtil
     */
    mouseleave() {
        this.isHover = false;
        this.timer = setTimeout(() => {
            if (!this.c.isHover) {
                this.popperDestroy();
            }
        }, 50);
    }
    /**
     * 初始化Vue状态管理器
     *
     * @memberof IBzTooltipUtil
     */
    initStore() {
        const appService = AppServiceBase.getInstance();
        this.store = appService.getAppStore();
    }
    /**
     * 初始化vue实例
     *
     * @private
     * @returns {void}
     * @memberof IBzTooltipUtil
     */
    initVueExample() {
        const self = this;
        if (!self.store) {
            self.initStore();
        }
        self.container.className = 'ibz-tooltip-wrapper';
        const div = document.createElement('div');
        self.container.appendChild(div);
        document.body.appendChild(self.container);
        this.vueExample = new Vue({
            el: div,
            data: {
                content: null,
                renderContent: null,
            },
            methods: {
                click(e) {
                    e.stopPropagation();
                },
            },
            render(h) {
                let content;
                if (this.renderContent) {
                    content = this.renderContent(h);
                }
                else if (this.content) {
                    content = <div class='content'>{this.content}</div>;
                }
                return (<div class='ibz-tooltip' style={{ 'z-index': self.zIndex }} on-click={this.click} on-mouseenter={() => self.mouseenter()} on-mouseleave={() => self.mouseleave()}>
            <div ref='arrow' class='ibz-tooltip-arrow' data-popper-arrow></div>
            {content}
          </div>);
            },
        });
    }
    /**
     * 打开提示框
     *
     * @param {Element} el
     * @param {((h: CreateElement) => any | string | VNode | VNode[])} [content]
     * @param {Placement} [position='auto']
     * @param {('local' | 'async')} [mode='local'] 提示框呈现模式，本地模式 | 异步模式。异步模式需要请求呈现
     * @param {*} [params]
     * @memberof IBzTooltipUtil
     */
    openPopover(el, content, position = 'auto', mode = 'local', params) {
        var _a, _b;
        if (!this.vueExample) {
            this.initVueExample();
            setTimeout(() => {
                this.openPopover(el, content, position, mode, params);
            }, 100);
            return;
        }
        this.popperDestroy();
        const zIndex = (_a = this.store) === null || _a === void 0 ? void 0 : _a.getters.getZIndex();
        if (zIndex) {
            this.zIndex = zIndex + 1;
            (_b = this.store) === null || _b === void 0 ? void 0 : _b.commit('upZIndex');
        }
        // 更新vue实例内容
        this.showTip = true;
        if (isFunc(content)) {
            Object.assign(this.vueExample.$data, { content: null, renderContent: content });
        }
        else {
            Object.assign(this.vueExample.$data, { content, renderContent: null });
        }
        const vueRef = this.vueExample.$el;
        this.popperExample = createPopper(el, vueRef, {
            placement: position,
            modifiers: [preventOverflow, flip, arrow, offset],
        });
        this.vueExample.$forceUpdate();
    }
    /**
     * 销毁提示框
     *
     * @memberof IBzTooltipUtil
     */
    popperDestroy() {
        if (this.popperExample) {
            this.popperExample.destroy();
            this.popperExample = undefined;
            this.showTip = false;
            this.vueExample.$forceUpdate();
        }
    }
    /**
     * tip重新计算位置
     *
     * @memberof IBzTooltipUtil
     */
    popperTick() {
        var _a;
        (_a = this.popperExample) === null || _a === void 0 ? void 0 : _a.forceUpdate();
    }
}
