<template>
  <div class="tabs-view" :class="{'tabs-view-fix': tagsMenuSetting.fixed,}" :style="getChangeStyle">
    <div class="tabs-view-main">
      <div ref="navWrap" class="tabs-card" :class="{ 'tabs-card-scrollable': state.scrollable }">
        <span class="tabs-card-prev" :class="{ 'tabs-card-prev-hide': !state.scrollable }" @click="scrollPrev">
          <n-icon size="16" color="#515a6e">
            <LeftOutlined />
          </n-icon>
        </span>
        <span class="tabs-card-next" :class="{ 'tabs-card-next-hide': !state.scrollable }" @click="scrollNext">
          <n-icon size="16" color="#515a6e">
            <RightOutlined />
          </n-icon>
        </span>
        <div ref="navScroll" class="tabs-card-scroll">
          <Draggable :list="tabsList" animation="300" item-key="fullPath" class="flex">
            <template #item="{ element }">
              <div
                :id="`tag${element.fullPath.split('/').join('\/')}`"
                class="tabs-card-scroll-item"
                :class="{ 'active-item': state.activeKey === element.path }"
                @click.stop="goPage(element)"
                @contextmenu="handleContextMenu($event, element)"
              >
                <span>{{ element.meta.title }}</span>
                <n-icon v-if="!element.meta.affix" size="14" @click.stop="closeTabItem(element)">
                  <CloseOutlined />
                </n-icon>
              </div>
            </template>
          </Draggable>
        </div>
      </div>

      <div class="tabs-close">
        <n-dropdown
          trigger="hover"
          placement="bottom-end"
          :options="tagsMemuOptions"
          @select="closeHandleSelect"
        >
          <div class="tabs-close-btn">
            <n-icon size="16" color="#515a6e">
              <DownOutlined />
            </n-icon>
          </div>
        </n-dropdown>
      </div>

      <n-dropdown
        :show="state.showDropdown"
        :x="state.dropdownX"
        :y="state.dropdownY"
        placement="bottom-start"
        :options="tagsMemuOptions"
        @clickoutside="onClickOutside"
        @select="closeHandleSelect"
      />
    </div>
  </div>
</template>

<script setup>
import {
  LeftOutlined,
  RightOutlined,
  CloseOutlined,
  DownOutlined,
  ReloadOutlined,
  ColumnWidthOutlined,
  MinusOutlined
} from '@vicons/antd'
import Draggable from 'vuedraggable'
import { reactive, computed, watch, defineProps, ref, unref, provide, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useTagsMenuStore } from '@/store/modules/tagsMenu.js'
import { useSettingStore } from '@/store/modules/setting.js'
import { getTags, setTags } from '@/utils/tags.js'
import { isString } from '@/utils/is.js'
import { renderIcon } from '@/utils'

const props = defineProps({
  collapsed: {
    type: Boolean
  },
  menuMode: {
    type: String,
    default: 'sidebar'
  }
})

/* 白名单 */
const whiteList = ['Login', 'Redirect', 'NOT_FOUND']
/* 基础页面 */
const baseMenu = '/home'

/* 获取路由器 */
const route = useRoute()
const router = useRouter()
const { push, replace } = router
/* 使用store数据 */
const tagsMenuStore = useTagsMenuStore()
const settingStore = useSettingStore()

const tabsList = computed(() => tagsMenuStore.tabsList)
const tagsMenuSetting = computed(() => settingStore.getTagsMenuSetting)

/* 组装样式 */
const getChangeStyle = computed(() => {
  const { collapsed, menuMode } = props
  const { cWidth, width } = unref(settingStore.getSidebarSetting)
  const { fixed } = unref(settingStore.getTagsMenuSetting)
  const lenNum = menuMode === 'header' ? '0px' : collapsed ? `${cWidth}px` : `${width}px`
  return {
    left: lenNum,
    width: `calc(100% - ${!fixed ? '0px' : lenNum})`
  }
})

let cacheRoutes = []
const simpleRoute = getSimpleRoute(route)
try {
  const routesStr = getTags()
  cacheRoutes = routesStr ? JSON.parse(routesStr) : [simpleRoute]
} catch (e) {
  cacheRoutes = [simpleRoute]
}

/* 同步路由信息 */
const routes = router.getRoutes()
cacheRoutes.forEach((cacheRoute) => {
  const findRoute = routes.find((route) => route.path === cacheRoute.path)
  if (route) {
    cacheRoute.meta = findRoute.meta || cacheRoute.meta
    cacheRoute.name = (findRoute.name || cacheRoute.name)
  }
})

tagsMenuStore.initTabs(cacheRoutes)

const state = reactive({
  activeKey: route.fullPath,
  scrollable: false,
  showDropdown: false,
  dropdownX: 0,
  dropdownY: 0
})

watch(
  () => route.fullPath,
  (to) => {
    // if (whiteList.includes(route.name)) return
    state.activeKey = to
    tagsMenuStore.addTabs(getSimpleRoute(route))
    // updateNavScroll(true)
  },
  { immediate: true }
)

/**
 * @description:
 * @param { Object } route
 * @return { Object }
 */
function getSimpleRoute(route) {
  const { fullPath, hash, meta, name, params, path, query } = route
  return { fullPath, hash, meta, name, params, path, query }
}

/**
 * @description: 左侧滚动
 * @return {*}
 */
function scrollPrev() {
//   const containerWidth = navScroll.value.offsetWidth
//   const currentScroll = navScroll.value.scrollLeft
//   if (!currentScroll) return
//   const scrollLeft = currentScroll > containerWidth ? currentScroll - containerWidth : 0
//   scrollTo(scrollLeft, (scrollLeft - currentScroll) / 20)
}
/**
 * @description: 右侧滚动
 * @return {*}
 */
function scrollNext() {
//   const containerWidth = navScroll.value.offsetWidth
//   const currentScroll = navScroll.value.scrollLeft
//   if (!currentScroll) return
//   const scrollLeft = currentScroll > containerWidth ? currentScroll - containerWidth : 0
//   scrollTo(scrollLeft, (scrollLeft - currentScroll) / 20)
}
/**
 * @description: 页面跳转
 * @return {*}
 */
function goPage(e) {
  const { fullPath } = e
  if (fullPath === route.fullPath) return
  state.activeKey = fullPath
  go(e, true)
}
/**
 * @description: 删除项
 * @return {*}
 */
function closeTabItem(e) {
  const { fullPath } = e
  const routeInfo = tabsList.value.find((item) => item.fullPath === fullPath)
  removeTab(routeInfo)
}

/**
 * @description:
 * @return {*}
 */

const removeTab = (route) => {
  if (tabsList.value.length === 1) {
    // return message.warning('这已经是最后一页，不能再关闭了！')
  }
  // delKeepAliveCompName()
  tagsMenuStore.closeCurrentTab(route)
  // 如果关闭的是当前页
  if (state.activeKey === route.fullPath) {
    const currentRoute = tabsList.value[Math.max(0, tabsList.value.length - 1)]
    state.activeKey = currentRoute.fullPath
    router.push(currentRoute)
  }
  // updateNavScroll()
}

// const delKeepAliveCompName = () => {
//   if (route.meta.keepAlive) {
//     const name = router.currentRoute.value.matched.find((item) => item.name === route.name)
//       ?.components?.default.name
//     if (name) {
//       asyncRouteStore.keepAliveComponents = asyncRouteStore.keepAliveComponents.filter(
//         (item) => item != name
//       )
//     }
//   }
// }

/* dropdown--start */
/* 右侧下拉菜单 */
const isCurrent = ref(false)
const tagsMemuOptions = computed(() => {
  const isDisabled = unref(tabsList).length <= 1
  return [
    {
      label: '刷新当前',
      key: '1',
      icon: renderIcon(ReloadOutlined)
    },
    {
      label: `关闭当前`,
      key: '2',
      disabled: unref(isCurrent) || isDisabled,
      icon: renderIcon(CloseOutlined)
    },
    {
      label: '关闭其他',
      key: '3',
      disabled: isDisabled,
      icon: renderIcon(ColumnWidthOutlined)
    },
    {
      label: '关闭全部',
      key: '4',
      disabled: isDisabled,
      icon: renderIcon(MinusOutlined)
    }
  ]
})
/* 操作右侧下拉菜单 */
const closeHandleSelect = (key) => {
  switch (key) {
    // 刷新
    case '1':
      reloadPage()
      break
      // 关闭
    case '2':
      removeTab(route)
      break
      // 关闭其他
    case '3':
      closeOther(route)
      break
      // 关闭所有
    case '4':
      closeAll()
      break
  }
  // updateNavScroll()
  state.showDropdown = false
}
/* 刷新页面 */
const reloadPage = () => {
  // delKeepAliveCompName()
  router.push({
    path: '/redirect' + unref(route).fullPath
  })
}
/* 注入刷新页面方法 */
provide('reloadPage', reloadPage)
/* 关闭其他 */
const closeOther = (route) => {
  tagsMenuStore.closeOtherTabs(route)
  state.activeKey = route.fullPath
  router.replace(route.fullPath)
  // updateNavScroll()
}

/* 关闭全部 */
const closeAll = () => {
  tagsMenuStore.closeAllTabs()
  router.replace(baseMenu)
  // updateNavScroll()
}
/* dropdown--end */
/* contextMenu--start */
/**
 * @description: 右键菜单
 * @return {*}
 */
function handleContextMenu(e, item) {
  e.preventDefault()
  isCurrent.value = baseMenu === item.path
  state.showDropdown = false
  nextTick().then(() => {
    state.showDropdown = true
    state.dropdownX = e.clientX
    state.dropdownY = e.clientY
  })
}
function onClickOutside() {
  state.showDropdown = false
}
/* contextMenu--end */
/**
 * @description: 页面跳转
 * @param undefined
 * @param undefined
 * @return {*}
 */
function go(opt, isReplace = false) {
  if (!opt) {
    return
  }
  if (isString(opt)) {
    isReplace ? replace(opt).catch(e => console.log(e)) : push(opt).catch(e => console.log(e))
  } else {
    const o = opt
    isReplace ? replace(o).catch(e => console.log(e)) : push(o).catch(e => console.log(e))
  }
}

</script>
<style scoped lang='scss'>
  .tabs-view {
    width: 100%;
    padding: 6px 0;
    display: flex;
    transition: all 0.2s ease-in-out;
    background: #f5f7f9;
    .tabs-view-main {
      height: 32px;
      display: flex;
      max-width: 100%;
      min-width: 100%;
      .tabs-card{
        -webkit-box-flex: 1;
        flex-grow: 1;
        flex-shrink: 1;
        overflow: hidden;
        position: relative;
        &.tabs-card-scrollable {
            padding: 0 32px;
            overflow: hidden;
        }
        .tabs-card-prev,
        .tabs-card-next {
          width: 32px;
          text-align: center;
          position: absolute;
          line-height: 32px;
          cursor: pointer;
          .n-icon {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 32px;
            width: 32px;
          }
        }
        .tabs-card-scroll {
          white-space: nowrap;
          overflow: hidden;
          .tabs-card-scroll-item {
            background: #ffffff;
            // color: v-bind('tagsMenuSetting.color');
            height: 32px;
            padding: 6px 16px 4px;
            border-radius: 3px;
            margin-right: 6px;
            cursor: pointer;
            display: inline-block;
            position: relative;
            flex: 0 0 auto;
            span {
              float: left;
              vertical-align: middle;
            }
            &:hover {
              color: #515a6e;
            }
            .n-icon {
              height: 22px;
              width: 21px;
              margin-right: -6px;
              position: relative;
              vertical-align: middle;
              text-align: center;
              color: #808695;
              &:hover {
                color: #515a6e !important;
              }
              svg {
                height: 21px;
                display: inline-block;
              }
            }
            &.active-item {
              color: #2d8cf0;
            }
          }
        }
      }
    }

    .tabs-close {
      min-width: 32px;
      width: 32px;
      height: 32px;
      line-height: 32px;
      text-align: center;
      // background: var(--color);
      border-radius: 2px;
      cursor: pointer;
      .tabs-close-btn {
        // color: var(--color);
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }

  .tabs-view-fix {
    position: fixed;
    z-index: 5;
    padding: 6px 19px 6px 10px;
    left: 200px;
  }

</style>
