<template>
  <el-main class="layout-main flex column gaps" id="layout-main">
    <router-view v-slot="{ Component }">
      <transition :name="config.layout.mainAnimation" mode="out-in">
        <keep-alive :include="state.keepAliveComponentNameList">
          <component :is="Component" :key="state.componentKey" />
        </keep-alive>
      </transition>
    </router-view>
    <!-- <cfooter class="box bottom" :class="config.layout.layoutMode=='Default'?'footerClassic':''"></cfooter> -->
    <transition name="el-backtop-transition">
      <div class="el-backtop" title="回到顶部" style="right: 20px; bottom: 20px;" v-if="toTop" @click="onGoTop">
        <div>
          <Icon name="fa fa-arrow-up" size="20" color="#191A23"></Icon>
        </div>
      </div>
    </transition>
  </el-main>

</template>

<script setup lang="ts">
import { reactive, onMounted, watch, onBeforeMount, onUnmounted, nextTick, ref } from 'vue'
import { useRoute } from 'vue-router'
import { mainHeight as layoutMainScrollbarStyle, mainHeight } from '/@/utils/layout'
import useCurrentInstance from '/@/utils/useCurrentInstance'
import { viewMenu } from '/@/stores/interface'
import { useConfig } from '/@/stores/config'
import { useNavTabs } from '/@/stores/navTabs'

const { proxy } = useCurrentInstance()

const route = useRoute()
const config = useConfig()
const navTabs = useNavTabs()
const scrollTop = ref(0)
const scrollHeight = ref(0)
const toTop = ref(false)

const state: {
    componentKey: string
    keepAliveComponentNameList: string[]
} = reactive({
    componentKey: route.path,
    keepAliveComponentNameList: [],
})

const addKeepAliveComponentName = function (keepAliveName: string | undefined) {
    if (keepAliveName) {
        let exist = state.keepAliveComponentNameList.find((name: string) => {
            return name === keepAliveName
        })
        if (exist) return
        state.keepAliveComponentNameList.push(keepAliveName)
    }
}

const handleScroll = (event: any) => {
    let body = document.getElementsByClassName('layout-main')[0]!
    let windowHeight: number = body?.clientHeight!
    scrollHeight.value = body?.scrollHeight!
    scrollTop.value = body?.scrollTop!
    if (scrollTop.value + windowHeight > windowHeight + 200 && scrollHeight.value > windowHeight) {
        toTop.value = true
    } else {
        toTop.value = false
        body.onscroll = () => {
            if (scrollTop.value + windowHeight >= windowHeight + 200) {
                // 把距离顶部的距离加上可视区域的高度 等于或者大于滚动条的总高度就是到达底部
                toTop.value = true
            }
        }
    }
}

const onGoTop = () => {
    const body = document.getElementsByClassName('default-main')[0]!
    body.scrollIntoView({ behavior: 'smooth', block: 'start' })
}

onBeforeMount(() => {
    proxy.eventBus.on('onTabViewRefresh', (menu: viewMenu) => {
        state.keepAliveComponentNameList = state.keepAliveComponentNameList.filter((name: string) => menu.keepaliveName !== name)
        state.componentKey = ''
        nextTick(() => {
            state.componentKey = menu.path
            addKeepAliveComponentName(menu.keepaliveName)
        })
    })
    proxy.eventBus.on('onTabViewClose', (menu: viewMenu) => {
        state.keepAliveComponentNameList = state.keepAliveComponentNameList.filter((name: string) => menu.keepaliveName !== name)
    })
})

onUnmounted(() => {
    proxy.eventBus.off('onTabViewRefresh')
    proxy.eventBus.off('onTabViewClose')
    window.removeEventListener('scroll', handleScroll)
})

onMounted(() => {
    window.addEventListener('scroll', handleScroll, true)
    // 确保刷新页面时也能正确取得当前路由 keepAlive 参数
    addKeepAliveComponentName(navTabs.state.activeRoute?.keepaliveName)
})

watch(
    () => route.path,
    () => {
        scrollHeight.value = 0
        scrollTop.value = 0
        toTop.value = false
        state.componentKey = route.path
        addKeepAliveComponentName(navTabs.state.activeRoute?.keepaliveName)
    }
)
</script>

<script lang="ts">
import { defineComponent } from 'vue'
import cfooter from '/@/layouts/backend/components/footer.vue'
export default defineComponent({
    components: { cfooter },
    name: 'layout/main',
})
</script>

<style scoped lang="scss">
.layout-container .layout-main {
    padding: 0 !important;
    overflow: hidden;
    width: 100%;
    height: 100%;
    overflow-y: scroll; /*y轴滚动*/
}
.layout-main::-webkit-scrollbar {
    display: none; /*隐藏滚动条*/
}
.layout-main-scrollbar {
    width: 100%;
    position: relative;
    overflow: hidden;
}

.el-backtop {
    position: fixed;
    background-color: #ffffff;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: #409eff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.12);
    cursor: pointer;
    z-index: 5;
}
.el-backtop:hover {
    background-color: #ecf5ff;
}

.el-backtop-transition-leave-to,
.el-backtop-transition-enter {
  opacity: 0;
}

.el-backtop-transition-enter-active,
.el-backtop-transition-leave-active {
  transition: opacity 1s;
}


</style>
