import { defineVxeComponent } from '../../ui/src/comp';
import XEUtils from 'xe-utils';
import { createEvent, getConfig, getIcon, globalEvents, globalMixins, permission, renderEmptyElement } from '../../ui';
import { getSlotVNs } from '../../ui/src/vn';
import { toCssUnit, addClass, removeClass } from '../../ui/src/dom';
import { isEnableConf } from '../../ui/src/utils';
import { createComponentLog } from '../../ui/src/log';
import VxeLoadingComponent from '../../loading/src/loading';
const { warnLog, errLog } = createComponentLog('tabs');
const scrollbarOffsetSize = 20;
export default {
    name: 'VxeTabs',
    mixins: [
        globalMixins.sizeMixin
    ],
    props: {
        value: [String, Number, Boolean],
        options: Array,
        width: [String, Number],
        height: [String, Number],
        destroyOnClose: {
            type: Boolean,
            default: () => getConfig().tabs.destroyOnClose
        },
        titleWidth: [String, Number],
        titleAlign: [String, Number],
        type: {
            type: String,
            default: () => getConfig().tabs.type
        },
        position: {
            type: String,
            default: () => getConfig().tabs.position
        },
        showClose: Boolean,
        showBody: {
            type: Boolean,
            default: true
        },
        padding: {
            type: Boolean,
            default: () => getConfig().tabs.padding
        },
        trigger: String,
        beforeChangeMethod: Function,
        closeConfig: Object,
        refreshConfig: Object,
        size: {
            type: String,
            default: () => getConfig().tabs.size || getConfig().size
        },
        // 已废弃
        beforeCloseMethod: Function
    },
    inject: {
        $xeParentTabs: {
            from: '$xeTabs',
            default: null
        }
    },
    provide() {
        const $xeTabs = this;
        return {
            $xeTabs
        };
    },
    data() {
        const xID = XEUtils.uniqueId();
        const reactData = {
            staticTabs: [],
            activeName: null,
            initNames: [],
            lintLeft: 0,
            lintTop: 0,
            lintWidth: 0,
            lintHeight: 0,
            scrollbarWidth: 0,
            scrollbarHeight: 0,
            isTabOver: false,
            resizeFlag: 1,
            cacheTabMaps: {}
        };
        const internalData = {
            slTimeout: undefined
        };
        return {
            xID,
            reactData,
            internalData
        };
    },
    computed: Object.assign(Object.assign({}, {}), { computeParentTabsResizeFlag() {
            const $xeTabs = this;
            const $xeParentTabs = $xeTabs.$xeParentTabs;
            return $xeParentTabs ? $xeParentTabs.reactData.resizeFlag : null;
        },
        computeTabType() {
            const $xeTabs = this;
            const props = $xeTabs;
            const { type } = props;
            return type || 'default';
        },
        computeTabPosition() {
            const $xeTabs = this;
            const props = $xeTabs;
            const { position } = props;
            return position || 'top';
        },
        computeLrPosition() {
            const $xeTabs = this;
            const tabPosition = $xeTabs.computeTabPosition;
            return tabPosition === 'left' || tabPosition === 'right';
        },
        computeLineStyle() {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            const { lintLeft, lintTop, lintWidth, lintHeight } = reactData;
            const lrPosition = $xeTabs.computeLrPosition;
            return lrPosition
                ? {
                    top: `${lintTop}px`,
                    height: `${lintHeight}px`
                }
                : {
                    left: `${lintLeft}px`,
                    width: `${lintWidth}px`
                };
        },
        computeWrapperStyle() {
            const $xeTabs = this;
            const props = $xeTabs;
            const { width, height } = props;
            const stys = {};
            if (width) {
                stys.width = toCssUnit(width);
            }
            if (height) {
                stys.height = height === 'auto' ? '100%' : toCssUnit(height);
            }
            return stys;
        },
        computeCloseOpts() {
            const $xeTabs = this;
            const props = $xeTabs;
            return Object.assign({}, getConfig().tabs.closeConfig, props.closeConfig);
        },
        computeRefreshOpts() {
            const $xeTabs = this;
            const props = $xeTabs;
            return Object.assign({}, getConfig().tabs.refreshConfig, props.refreshConfig);
        },
        computeTabOptions() {
            const $xeTabs = this;
            const props = $xeTabs;
            const options = props.options;
            return (options || []).filter((item) => $xeTabs.handleFilterTab(item));
        },
        computeTabStaticOptions() {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            const staticTabs = reactData.staticTabs;
            return staticTabs.filter((item) => $xeTabs.handleFilterTab(item));
        } }),
    methods: {
        //
        // Method
        //
        dispatchEvent(type, params, evnt) {
            const $xeTabs = this;
            $xeTabs.$emit(type, createEvent(evnt, { $tabs: $xeTabs }, params));
        },
        emitModel(value) {
            const $xeTabs = this;
            const { _events } = $xeTabs;
            $xeTabs.$emit('input', value);
            if (_events && _events.modelValue) {
                $xeTabs.$emit('modelValue', value);
            }
            else {
                $xeTabs.$emit('model-value', value);
            }
        },
        prev() {
            const $xeTabs = this;
            return $xeTabs.handlePrevNext(false);
        },
        next() {
            const $xeTabs = this;
            return $xeTabs.handlePrevNext(true);
        },
        prevTab() {
            const $xeTabs = this;
            warnLog('vxe.error.delFunc', ['prevTab', 'prev']);
            return $xeTabs.prev();
        },
        nextTab() {
            const $xeTabs = this;
            warnLog('vxe.error.delFunc', ['nextTab', 'next']);
            return $xeTabs.next();
        },
        handleFilterTab(item) {
            const { permissionCode } = item;
            if (permissionCode) {
                if (!permission.checkVisible(permissionCode)) {
                    return false;
                }
            }
            return true;
        },
        callSlot(slotFunc, params, h) {
            const $xeTabs = this;
            const slots = $xeTabs.$scopedSlots;
            if (slotFunc) {
                if (XEUtils.isString(slotFunc)) {
                    slotFunc = slots[slotFunc] || null;
                }
                if (XEUtils.isFunction(slotFunc)) {
                    return getSlotVNs(slotFunc.call($xeTabs, params, h));
                }
            }
            return [];
        },
        checkScrolling() {
            const $xeTabs = this;
            const lrPosition = $xeTabs.computeLrPosition;
            const headerWrapperEl = $xeTabs.$refs.refHeadWrapperElem;
            const headPrevEl = $xeTabs.$refs.refHeadPrevElem;
            const headNextEl = $xeTabs.$refs.refHeadNextElem;
            if (headerWrapperEl) {
                const { scrollLeft, scrollTop, clientWidth, clientHeight, scrollWidth, scrollHeight } = headerWrapperEl;
                if (headPrevEl) {
                    if ((lrPosition ? scrollTop : scrollLeft) > 0) {
                        addClass(headPrevEl, 'scrolling--middle');
                    }
                    else {
                        removeClass(headPrevEl, 'scrolling--middle');
                    }
                }
                if (headNextEl) {
                    if (lrPosition ? (clientHeight < scrollHeight - Math.ceil(scrollTop)) : (clientWidth < scrollWidth - Math.ceil(scrollLeft))) {
                        addClass(headNextEl, 'scrolling--middle');
                    }
                    else {
                        removeClass(headNextEl, 'scrolling--middle');
                    }
                }
            }
        },
        updateTabStyle() {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            const handleStyle = () => {
                const { activeName } = reactData;
                const tabType = $xeTabs.computeTabType;
                const tabOptions = $xeTabs.computeTabOptions;
                const tabStaticOptions = $xeTabs.computeTabStaticOptions;
                const headerWrapperEl = $xeTabs.$refs.refHeadWrapperElem;
                const lrPosition = $xeTabs.computeLrPosition;
                let lintWidth = 0;
                let lintHeight = 0;
                let lintLeft = 0;
                let lintTop = 0;
                let sBarWidth = 0;
                let sBarHeight = 0;
                let isOver = false;
                if (headerWrapperEl) {
                    const index = XEUtils.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === activeName);
                    const { children, offsetWidth, scrollWidth, offsetHeight, scrollHeight, clientWidth, clientHeight } = headerWrapperEl;
                    sBarWidth = offsetWidth - clientWidth;
                    sBarHeight = offsetHeight - clientHeight;
                    if (lrPosition) {
                        isOver = scrollHeight !== clientHeight;
                        if (index > -1) {
                            const tabEl = children[index];
                            if (tabEl) {
                                const tabHeight = tabEl.clientHeight;
                                const tabWidth = tabEl.clientWidth;
                                if (tabType === 'card') {
                                    lintWidth = tabWidth;
                                    lintHeight = tabHeight;
                                    lintTop = tabEl.offsetTop;
                                }
                                else if (tabType === 'border-card') {
                                    lintWidth = tabWidth;
                                    lintHeight = tabHeight;
                                    lintTop = tabEl.offsetTop - 1;
                                }
                                else {
                                    lintHeight = Math.max(4, Math.floor(tabHeight * 0.6));
                                    lintTop = tabEl.offsetTop + Math.floor((tabHeight - lintHeight) / 2);
                                }
                            }
                        }
                    }
                    else {
                        isOver = scrollWidth !== clientWidth;
                        if (index > -1) {
                            const tabEl = children[index];
                            if (tabEl) {
                                const tabWidth = tabEl.clientWidth;
                                if (tabType === 'card') {
                                    lintWidth = tabWidth + 1;
                                    lintLeft = tabEl.offsetLeft;
                                }
                                else if (tabType === 'border-card') {
                                    lintWidth = tabWidth;
                                    lintLeft = tabEl.offsetLeft - 1;
                                }
                                else {
                                    lintWidth = Math.max(4, Math.floor(tabWidth * 0.6));
                                    lintLeft = tabEl.offsetLeft + Math.floor((tabWidth - lintWidth) / 2);
                                }
                            }
                        }
                    }
                }
                reactData.scrollbarWidth = sBarWidth;
                reactData.scrollbarHeight = sBarHeight;
                reactData.lintLeft = lintLeft;
                reactData.lintTop = lintTop;
                reactData.lintWidth = lintWidth;
                reactData.lintHeight = lintHeight;
                reactData.isTabOver = isOver;
                $xeTabs.checkScrolling();
            };
            handleStyle();
            $xeTabs.$nextTick(handleStyle);
        },
        addInitName(name, evnt) {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            const { initNames } = reactData;
            if (name && !initNames.includes(name)) {
                $xeTabs.dispatchEvent('tab-load', { name }, evnt);
                initNames.push(name);
                return true;
            }
            return false;
        },
        initDefaultName(list) {
            const $xeTabs = this;
            const props = $xeTabs;
            const reactData = $xeTabs.reactData;
            let activeName = null;
            const nameMaps = {};
            if (list && list.length) {
                let validVal = false;
                activeName = props.value;
                list.forEach((item) => {
                    const { name, preload } = item || {};
                    if (name) {
                        nameMaps[`${name}`] = {
                            loading: false
                        };
                        if (activeName === name) {
                            validVal = true;
                        }
                        if (preload) {
                            $xeTabs.addInitName(name, null);
                        }
                    }
                });
                if (!validVal) {
                    activeName = list[0].name;
                    $xeTabs.addInitName(activeName, null);
                    $xeTabs.emitModel(activeName);
                }
            }
            reactData.activeName = activeName;
            reactData.cacheTabMaps = nameMaps;
        },
        clickEvent(evnt, item) {
            const $xeTabs = this;
            const props = $xeTabs;
            const reactData = $xeTabs.reactData;
            const { trigger } = props;
            const beforeMethod = props.beforeChangeMethod || getConfig().tabs.beforeChangeMethod;
            const { activeName } = reactData;
            const { name } = item;
            const value = name;
            $xeTabs.dispatchEvent('tab-click', { name }, evnt);
            if (trigger === 'manual') {
                return;
            }
            if (name !== activeName) {
                Promise.resolve(!beforeMethod || beforeMethod({ $tabs: $xeTabs, name, oldName: activeName, newName: name, option: item })).then((status) => {
                    if (status) {
                        reactData.activeName = name;
                        $xeTabs.emitModel(value);
                        $xeTabs.addInitName(name, evnt);
                        $xeTabs.dispatchEvent('change', { value, name, oldName: activeName, newName: name, option: item }, evnt);
                        $xeTabs.dispatchEvent('tab-change', { value, name, oldName: activeName, newName: name, option: item }, evnt);
                    }
                    else {
                        $xeTabs.dispatchEvent('tab-change-fail', { value, name, oldName: activeName, newName: name, option: item }, evnt);
                    }
                }).catch(() => {
                    $xeTabs.dispatchEvent('tab-change-fail', { value, name, oldName: activeName, newName: name, option: item }, evnt);
                });
            }
        },
        handleRefreshTabEvent(evnt, item) {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            evnt.stopPropagation();
            const { activeName, cacheTabMaps } = reactData;
            const { name } = item;
            const refreshOpts = $xeTabs.computeRefreshOpts;
            const { queryMethod } = refreshOpts;
            const cacheItem = name ? cacheTabMaps[`${name}`] : null;
            if (cacheItem) {
                if (cacheItem.loading) {
                    return;
                }
                if (queryMethod) {
                    cacheItem.loading = true;
                    Promise.resolve(queryMethod({ $tabs: $xeTabs, value: activeName, name, option: item })).finally(() => {
                        cacheItem.loading = false;
                    });
                }
                else {
                    errLog('vxe.error.notFunc', ['refresh-config.queryMethod']);
                }
            }
        },
        handleCloseTabEvent(evnt, item, index, list) {
            const $xeTabs = this;
            const props = $xeTabs;
            const reactData = $xeTabs.reactData;
            evnt.stopPropagation();
            const { activeName } = reactData;
            const closeOpts = $xeTabs.computeCloseOpts;
            const beforeMethod = closeOpts.beforeMethod || props.beforeCloseMethod || getConfig().tabs.beforeCloseMethod;
            const { name } = item;
            const value = activeName;
            let nextName = value;
            if (activeName === name) {
                const nextItem = index < list.length - 1 ? list[index + 1] : list[index - 1];
                nextName = nextItem ? nextItem.name : null;
            }
            Promise.resolve(!beforeMethod || beforeMethod({ $tabs: $xeTabs, value, name, nextName, option: item })).then(status => {
                if (status) {
                    $xeTabs.dispatchEvent('tab-close', { value, name, nextName }, evnt);
                }
                else {
                    $xeTabs.dispatchEvent('tab-close-fail', { value, name, nextName }, evnt);
                }
            }).catch(() => {
                $xeTabs.dispatchEvent('tab-close-fail', { value, name, nextName }, evnt);
            });
        },
        startScrollAnimation(offsetPos, offsetSize) {
            const $xeTabs = this;
            const internalData = $xeTabs.internalData;
            const { slTimeout } = internalData;
            const lrPosition = $xeTabs.computeLrPosition;
            let offsetLeft = lrPosition ? 0 : offsetSize;
            let offsetTop = lrPosition ? offsetSize : 0;
            let scrollCount = 6;
            let delayNum = 35;
            if (slTimeout) {
                clearTimeout(slTimeout);
                internalData.slTimeout = undefined;
            }
            const scrollAnimate = () => {
                const headerWrapperEl = $xeTabs.$refs.refHeadWrapperElem;
                if (scrollCount > 0) {
                    scrollCount--;
                    if (headerWrapperEl) {
                        const { clientWidth, clientHeight, scrollWidth, scrollHeight, scrollLeft, scrollTop } = headerWrapperEl;
                        if (lrPosition) {
                            offsetTop = Math.floor(offsetTop / 2);
                            if (offsetPos > 0) {
                                if (clientHeight + scrollTop < scrollHeight) {
                                    headerWrapperEl.scrollTop += offsetTop;
                                    delayNum -= 4;
                                    internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
                                }
                            }
                            else {
                                if (scrollTop > 0) {
                                    headerWrapperEl.scrollTop -= offsetTop;
                                    delayNum -= 4;
                                    internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
                                }
                            }
                        }
                        else {
                            offsetLeft = Math.floor(offsetLeft / 2);
                            if (offsetPos > 0) {
                                if (clientWidth + scrollLeft < scrollWidth) {
                                    headerWrapperEl.scrollLeft += offsetLeft;
                                    delayNum -= 4;
                                    internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
                                }
                            }
                            else {
                                if (scrollLeft > 0) {
                                    headerWrapperEl.scrollLeft -= offsetLeft;
                                    delayNum -= 4;
                                    internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
                                }
                            }
                        }
                        $xeTabs.updateTabStyle();
                    }
                }
            };
            scrollAnimate();
        },
        handleScrollToLeft(offsetPos) {
            const $xeTabs = this;
            const lrPosition = $xeTabs.computeLrPosition;
            const headerWrapperEl = $xeTabs.$refs.refHeadWrapperElem;
            if (headerWrapperEl) {
                const { clientWidth, clientHeight } = headerWrapperEl;
                const offsetSize = Math.floor((lrPosition ? clientHeight : clientWidth) * 0.75);
                $xeTabs.startScrollAnimation(offsetPos, offsetSize);
            }
        },
        scrollLeftEvent() {
            const $xeTabs = this;
            $xeTabs.handleScrollToLeft(-1);
        },
        scrollRightEvent() {
            const $xeTabs = this;
            $xeTabs.handleScrollToLeft(1);
        },
        scrollToTab(name) {
            const $xeTabs = this;
            const tabOptions = $xeTabs.computeTabOptions;
            const tabStaticOptions = $xeTabs.computeTabStaticOptions;
            const lrPosition = $xeTabs.computeLrPosition;
            return $xeTabs.$nextTick().then(() => {
                const headerWrapperEl = $xeTabs.$refs.refHeadWrapperElem;
                if (headerWrapperEl) {
                    const index = XEUtils.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === name);
                    if (index > -1) {
                        const { scrollLeft, scrollTop, clientWidth, clientHeight, children } = headerWrapperEl;
                        const tabEl = children[index];
                        if (tabEl) {
                            if (lrPosition) {
                                const tabOffsetTop = tabEl.offsetTop;
                                const tabClientHeight = tabEl.clientHeight;
                                // 如果顶部被挡
                                const overSize = (tabOffsetTop + tabClientHeight) - (scrollTop + clientHeight);
                                if (overSize > 0) {
                                    headerWrapperEl.scrollTop += overSize;
                                }
                                // 如果底部被挡，优先
                                if (tabOffsetTop < scrollTop) {
                                    headerWrapperEl.scrollTop = tabOffsetTop;
                                }
                            }
                            else {
                                const tabOffsetLeft = tabEl.offsetLeft;
                                const tabClientWidth = tabEl.clientWidth;
                                // 如果右侧被挡
                                const overSize = (tabOffsetLeft + tabClientWidth) - (scrollLeft + clientWidth);
                                if (overSize > 0) {
                                    headerWrapperEl.scrollLeft += overSize;
                                }
                                // 如果左侧被挡，优先
                                if (tabOffsetLeft < scrollLeft) {
                                    headerWrapperEl.scrollLeft = tabOffsetLeft;
                                }
                            }
                        }
                    }
                    $xeTabs.updateTabStyle();
                }
            });
        },
        handlePrevNext(isNext) {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            const { activeName } = reactData;
            const tabOptions = $xeTabs.computeTabOptions;
            const tabStaticOptions = $xeTabs.computeTabStaticOptions;
            const list = tabStaticOptions.length ? tabStaticOptions : tabOptions;
            const index = XEUtils.findIndexOf(list, item => item.name === activeName);
            if (index > -1) {
                let item = null;
                if (isNext) {
                    if (index < list.length - 1) {
                        item = list[index + 1];
                    }
                }
                else {
                    if (index > 0) {
                        item = list[index - 1];
                    }
                }
                if (item) {
                    const name = item.name;
                    const value = name;
                    reactData.activeName = name;
                    $xeTabs.emitModel(value);
                    $xeTabs.addInitName(name, null);
                }
            }
            return $xeTabs.$nextTick();
        },
        //
        // Render
        //
        renderTabHeader(h, tabList) {
            const $xeTabs = this;
            const props = $xeTabs;
            const slots = $xeTabs.$scopedSlots;
            const reactData = $xeTabs.reactData;
            const { titleWidth: allTitleWidth, titleAlign: allTitleAlign, showClose, closeConfig, refreshConfig } = props;
            const { activeName, scrollbarWidth, scrollbarHeight, isTabOver, cacheTabMaps } = reactData;
            const tabType = $xeTabs.computeTabType;
            const tabPosition = $xeTabs.computeTabPosition;
            const lrPosition = $xeTabs.computeLrPosition;
            const lineStyle = $xeTabs.computeLineStyle;
            const tabPrefixSlot = slots.tabPrefix || slots['tab-prefix'] || slots.prefix;
            const tabSuffixSlot = slots.tabSuffix || slots['tab-suffix'] || slots.suffix || slots.extra;
            const closeOpts = $xeTabs.computeCloseOpts;
            const closeVisibleMethod = closeOpts.visibleMethod;
            const refreshOpts = $xeTabs.computeRefreshOpts;
            const refreshVisibleMethod = refreshOpts.visibleMethod;
            return h('div', {
                key: 'th',
                class: ['vxe-tabs-header', `type--${tabType}`, `pos--${tabPosition}`]
            }, [
                tabPrefixSlot
                    ? h('div', {
                        class: ['vxe-tabs-header--prefix', `type--${tabType}`, `pos--${tabPosition}`]
                    }, $xeTabs.callSlot(tabPrefixSlot, { name: activeName }, h))
                    : renderEmptyElement($xeTabs),
                isTabOver
                    ? h('div', {
                        ref: 'refHeadPrevElem',
                        class: ['vxe-tabs-header--bar vxe-tabs-header--prev-bar', `type--${tabType}`, `pos--${tabPosition}`],
                        on: {
                            click: $xeTabs.scrollLeftEvent
                        }
                    }, [
                        h('span', {
                            class: lrPosition ? getIcon().TABS_TAB_BUTTON_TOP : getIcon().TABS_TAB_BUTTON_LEFT
                        })
                    ])
                    : renderEmptyElement($xeTabs),
                h('div', {
                    class: ['vxe-tabs-header--wrapper', `type--${tabType}`, `pos--${tabPosition}`]
                }, [
                    h('div', {
                        ref: 'refHeadWrapperElem',
                        class: 'vxe-tabs-header--item-wrapper',
                        style: lrPosition
                            ? {
                                marginRight: `-${scrollbarWidth + scrollbarOffsetSize}px`,
                                paddingRight: `${scrollbarOffsetSize}px`
                            }
                            : {
                                marginBottom: `-${scrollbarHeight + scrollbarOffsetSize}px`,
                                paddingBottom: `${scrollbarOffsetSize}px`
                            },
                        on: {
                            scroll: $xeTabs.checkScrolling
                        }
                    }, tabList.map((item, index) => {
                        const { title, titleWidth, titleAlign, icon, name } = item;
                        const itemSlots = item.slots || {};
                        const titleSlot = itemSlots.title || itemSlots.tab;
                        const titlePrefixSlot = itemSlots.titlePrefix || itemSlots['title-prefix'];
                        const titleSuffixSlot = itemSlots.titleSuffix || itemSlots['title-suffix'];
                        const itemWidth = titleWidth || allTitleWidth;
                        const itemAlign = titleAlign || allTitleAlign;
                        const params = { $tabs: $xeTabs, value: activeName, name, option: item };
                        const isActive = activeName === name;
                        const cacheItem = name ? cacheTabMaps[`${name}`] : null;
                        const isLoading = cacheItem ? cacheItem.loading : false;
                        return h('div', {
                            key: `${name}`,
                            class: ['vxe-tabs-header--item', `type--${tabType}`, `pos--${tabPosition}`, itemAlign ? `align--${itemAlign}` : '', {
                                    'is--active': isActive
                                }],
                            style: itemWidth
                                ? {
                                    width: toCssUnit(itemWidth)
                                }
                                : undefined,
                            on: {
                                click(evnt) {
                                    $xeTabs.clickEvent(evnt, item);
                                }
                            }
                        }, [
                            h('div', {
                                class: 'vxe-tabs-header--item-inner'
                            }, [
                                h('div', {
                                    class: 'vxe-tabs-header--item-content'
                                }, [
                                    icon
                                        ? h('span', {
                                            class: 'vxe-tabs-header--item-icon'
                                        }, [
                                            h('i', {
                                                class: icon
                                            })
                                        ])
                                        : renderEmptyElement($xeTabs),
                                    titlePrefixSlot
                                        ? h('span', {
                                            class: 'vxe-tabs-header--item-prefix'
                                        }, $xeTabs.callSlot(titlePrefixSlot, { name, title }, h))
                                        : renderEmptyElement($xeTabs),
                                    h('span', {
                                        class: 'vxe-tabs-header--item-name'
                                    }, titleSlot ? $xeTabs.callSlot(titleSlot, { name, title }, h) : `${title}`),
                                    titleSuffixSlot
                                        ? h('span', {
                                            class: 'vxe-tabs-header--item-suffix'
                                        }, $xeTabs.callSlot(titleSuffixSlot, { name, title }, h))
                                        : renderEmptyElement($xeTabs)
                                ]),
                                (isEnableConf(refreshConfig) || refreshOpts.enabled) && (refreshVisibleMethod ? refreshVisibleMethod(params) : true)
                                    ? h('div', {
                                        class: ['vxe-tabs-header--refresh-btn', {
                                                'is--active': isActive,
                                                'is--loading': isLoading,
                                                'is--disabled': isLoading
                                            }],
                                        on: {
                                            click(evnt) {
                                                $xeTabs.handleRefreshTabEvent(evnt, item);
                                            }
                                        }
                                    }, [
                                        h('i', {
                                            class: isLoading ? getIcon().TABS_TAB_REFRESH_LOADING : getIcon().TABS_TAB_REFRESH
                                        })
                                    ])
                                    : renderEmptyElement($xeTabs),
                                (showClose || (isEnableConf(closeConfig) || closeOpts.enabled)) && (!closeVisibleMethod || closeVisibleMethod(params))
                                    ? h('div', {
                                        class: ['vxe-tabs-header--close-btn', {
                                                'is--active': isActive
                                            }],
                                        on: {
                                            click(evnt) {
                                                $xeTabs.handleCloseTabEvent(evnt, item, index, tabList);
                                            }
                                        }
                                    }, [
                                        h('i', {
                                            class: getIcon().TABS_TAB_CLOSE
                                        })
                                    ])
                                    : renderEmptyElement($xeTabs)
                            ])
                        ]);
                    }).concat([
                        h('span', {
                            key: 'line',
                            class: ['vxe-tabs-header--active-line', `type--${tabType}`, `pos--${tabPosition}`],
                            style: lineStyle
                        })
                    ]))
                ]),
                isTabOver
                    ? h('div', {
                        ref: 'refHeadNextElem',
                        class: ['vxe-tabs-header--bar vxe-tabs-header--next-bar', `type--${tabType}`, `pos--${tabPosition}`],
                        on: {
                            click: $xeTabs.scrollRightEvent
                        }
                    }, [
                        h('span', {
                            class: lrPosition ? getIcon().TABS_TAB_BUTTON_BOTTOM : getIcon().TABS_TAB_BUTTON_RIGHT
                        })
                    ])
                    : renderEmptyElement($xeTabs),
                tabSuffixSlot
                    ? h('div', {
                        class: ['vxe-tabs-header--suffix', `type--${tabType}`, `pos--${tabPosition}`]
                    }, $xeTabs.callSlot(tabSuffixSlot, { name: activeName }, h))
                    : renderEmptyElement($xeTabs)
            ]);
        },
        renderTabPane(h, item) {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            const { initNames, activeName } = reactData;
            const { name, slots } = item;
            const defaultSlot = slots ? slots.default : null;
            return name && initNames.includes(name)
                ? h('div', {
                    key: `${name}`,
                    class: ['vxe-tabs-pane--item', {
                            'is--visible': activeName === name
                        }]
                }, defaultSlot ? $xeTabs.callSlot(defaultSlot, { name }, h) : [])
                : renderEmptyElement($xeTabs);
        },
        renderTabContent(h, tabList) {
            const $xeTabs = this;
            const props = $xeTabs;
            const reactData = $xeTabs.reactData;
            const { destroyOnClose } = props;
            const { activeName } = reactData;
            if (destroyOnClose) {
                const activeTab = tabList.find(item => item.name === activeName);
                return [activeTab ? $xeTabs.renderTabPane(h, activeTab) : renderEmptyElement($xeTabs)];
            }
            return tabList.map((item) => $xeTabs.renderTabPane(h, item));
        },
        rendetTabBody(h, tabList) {
            const $xeTabs = this;
            const props = $xeTabs;
            const slots = $xeTabs.$scopedSlots;
            const reactData = $xeTabs.reactData;
            const { height, padding, showBody } = props;
            const { activeName, cacheTabMaps } = reactData;
            const vSize = $xeTabs.computeSize;
            const tabType = $xeTabs.computeTabType;
            const tabPosition = $xeTabs.computeTabPosition;
            const refreshOpts = $xeTabs.computeRefreshOpts;
            const { showLoading } = refreshOpts;
            const headerpSlot = slots.header;
            const footerSlot = slots.footer;
            if (!showBody) {
                return renderEmptyElement($xeTabs);
            }
            const cacheItem = activeName ? cacheTabMaps[`${activeName}`] : null;
            const isLoading = cacheItem ? cacheItem.loading : false;
            const defParams = { name: activeName };
            return h('div', {
                key: 'tb',
                class: ['vxe-tabs-pane--wrapper', `type--${tabType}`, `pos--${tabPosition}`, {
                        'is--content': showBody
                    }]
            }, [
                headerpSlot
                    ? h('div', {
                        class: 'vxe-tabs-pane--header'
                    }, $xeTabs.callSlot(headerpSlot, defParams, h))
                    : renderEmptyElement($xeTabs),
                h('div', {
                    class: ['vxe-tabs-pane--body', `type--${tabType}`, `pos--${tabPosition}`, {
                            [`size--${vSize}`]: vSize,
                            'is--padding': padding,
                            'is--height': height
                        }]
                }, $xeTabs.renderTabContent(h, tabList)),
                footerSlot
                    ? h('div', {
                        class: 'vxe-tabs-pane--footer'
                    }, $xeTabs.callSlot(footerSlot, defParams, h))
                    : renderEmptyElement($xeTabs),
                showLoading && isLoading
                    ? renderEmptyElement($xeTabs)
                    : h(VxeLoadingComponent, {
                        class: 'vxe-tabs--loading',
                        props: {
                            value: isLoading
                        }
                    })
            ]);
        },
        renderVN(h) {
            const $xeTabs = this;
            const props = $xeTabs;
            const slots = $xeTabs.$scopedSlots;
            const reactData = $xeTabs.reactData;
            const { height, padding, trigger } = props;
            const { activeName } = reactData;
            const vSize = $xeTabs.computeSize;
            const tabOptions = $xeTabs.computeTabOptions;
            const tabStaticOptions = $xeTabs.computeTabStaticOptions;
            const tabType = $xeTabs.computeTabType;
            const tabPosition = $xeTabs.computeTabPosition;
            const wrapperStyle = $xeTabs.computeWrapperStyle;
            const defaultSlot = slots.default;
            const tabList = defaultSlot ? tabStaticOptions : tabOptions;
            const vns = [
                h('div', {
                    key: 'ts',
                    class: 'vxe-tabs-slots'
                }, defaultSlot ? defaultSlot({ name: activeName }) : [])
            ];
            if (tabPosition === 'right' || tabPosition === 'bottom') {
                vns.push($xeTabs.rendetTabBody(h, tabList), $xeTabs.renderTabHeader(h, tabList));
            }
            else {
                vns.push($xeTabs.renderTabHeader(h, tabList), $xeTabs.rendetTabBody(h, tabList));
            }
            return h('div', {
                ref: 'refElem',
                class: ['vxe-tabs', `pos--${tabPosition}`, `vxe-tabs--${tabType}`, `trigger--${trigger === 'manual' ? 'trigger' : 'default'}`, {
                        [`size--${vSize}`]: vSize,
                        'is--padding': padding,
                        'is--height': height
                    }],
                style: wrapperStyle
            }, vns);
        }
    },
    watch: {
        position() {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            reactData.resizeFlag++;
        },
        value(val) {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            $xeTabs.addInitName(val, null);
            reactData.activeName = val;
        },
        'reactData.activeName'(val) {
            const $xeTabs = this;
            $xeTabs.scrollToTab(val);
        },
        options() {
            const $xeTabs = this;
            const props = $xeTabs;
            const reactData = $xeTabs.reactData;
            $xeTabs.initDefaultName(props.options);
            reactData.resizeFlag++;
        },
        'reactData.staticTabs'() {
            const $xeTabs = this;
            const reactData = $xeTabs.reactData;
            $xeTabs.initDefaultName(reactData.staticTabs);
            reactData.resizeFlag++;
        },
        computeParentTabsResizeFlag() {
            const $xeTabs = this;
            $xeTabs.$nextTick(() => {
                $xeTabs.updateTabStyle();
            });
        }
    },
    created() {
        const $xeTabs = this;
        const props = $xeTabs;
        const reactData = $xeTabs.reactData;
        $xeTabs.addInitName(props.value, null);
        $xeTabs.initDefaultName(reactData.staticTabs.length ? reactData.staticTabs : props.options);
    },
    mounted() {
        const $xeTabs = this;
        $xeTabs.updateTabStyle();
        globalEvents.on($xeTabs, 'resize', $xeTabs.updateTabStyle);
    },
    beforeDestroy() {
        const $xeTabs = this;
        globalEvents.off($xeTabs, 'resize');
    },
    render(h) {
        return this.renderVN(h);
    }
};
