import { defineStore } from 'pinia'
import type { LocationQuery, RouteLocationNormalized, RouteParamsRaw, RouteRecordName, RouteLocationRaw } from 'vue-router'
import { isExternal } from '@/utils/util'
import router from '@/router'

// 标签页项类型定义
interface TabItem {
  name: RouteRecordName
  fullPath: string
  path: string
  title?: string
  icon?: string
  iconType?: number
  query?: LocationQuery
  params?: RouteParamsRaw
  fixed?: boolean
}

// 辅助函数：判断标签是否已存在
const findTabIndex = (fullPath: string, tabList: TabItem[]): number => {
  return tabList.findIndex((item) => item.fullPath === fullPath)
}

// 辅助函数：判断路由是否不能添加到标签页
const isRouteCannotBeTab = (route: RouteLocationNormalized): boolean => {
  const { path, meta } = route
  if (!path || isExternal(path)) return true
  if (meta?.hideTab) return true
  if ((['/login', '/403'] as string[]).includes(path)) {
    return true
  }
  return false
}

// 辅助函数：获取组件名称
const getComponentName = (route: RouteLocationNormalized): string | undefined => {
  return route.matched.at(-1)?.components?.default?.name
}

// 导出：获取路由参数
const getRouteParamsFromTab = (tabItem: TabItem) => {
  const { params, path, query } = tabItem
  return {
    params: params || {},
    path,
    query: query || {}
  }
}

// 标签页状态管理
export const useTabsStore = defineStore('tabs', () => {
  // 状态定义
  const cachedTabComponents = ref<Set<string>>(new Set())
  const tabs = ref<TabItem[]>([])
  const tabMap = ref<Record<string, TabItem>>({})
  const indexRouteName = ref<RouteRecordName>('')
  // 计算属性
  const tabList = computed(() => tabs.value)
  const cachedTabList = computed(() => Array.from(cachedTabComponents.value))

  // 方法定义
  // 设置首页路由名称
  const setIndexRouteName = (name: RouteRecordName) => {
    indexRouteName.value = name
  }
  // 添加组件到缓存
  const addComponentToCache = (componentName?: string) => {
    if (componentName) {
      cachedTabComponents.value.add(componentName)
    }
  }
  // 从缓存中移除组件
  const removeComponentFromCache = (componentName?: string) => {
    if (componentName && cachedTabComponents.value.has(componentName)) {
      cachedTabComponents.value.delete(componentName)
    }
  }
  // 清空组件缓存
  const clearComponentCache = () => {
    cachedTabComponents.value.clear()
  }
  // 重置状态
  const resetTabsState = () => {
    cachedTabComponents.value = new Set()
    tabs.value = []
    tabMap.value = {}
    indexRouteName.value = ''
  }
  // 重新排序标签页
  const sortTabs = () => {
    tabs.value.sort((a, b) => {
      if (a.fixed && !b.fixed) return -1
      if (!a.fixed && b.fixed) return 1
      return 0
    })
  }
  // 添加标签页
  const addTab = () => {
    const route = unref(router.currentRoute)
    const { name, query, meta, params, fullPath, path } = route
    if (isRouteCannotBeTab(route)) return
    const tabIndex = findTabIndex(fullPath!, tabs.value)
    const componentName = getComponentName(route)
    const existingTab = tabMap.value[fullPath]
    const tabItem: TabItem = {
      name: name!,
      path,
      fullPath,
      title: meta?.title as string | undefined,
      icon: meta?.icon as string | undefined,
      iconType: meta?.iconType as number | undefined,
      query,
      params,
      fixed: existingTab?.fixed || false
    }
    if (meta?.keepAlive) {
      addComponentToCache(componentName)
    }
    if (tabIndex !== -1) {
      tabMap.value[fullPath] = {
        ...tabItem,
        fixed: existingTab?.fixed || false
      }
      const tabInList = tabs.value[tabIndex]
      if (tabInList) {
        tabInList.name = name!
        tabInList.path = path
        tabInList.title = meta?.title as string | undefined
        tabInList.icon = meta?.icon as string | undefined
        tabInList.iconType = meta?.iconType as number | undefined
        tabInList.query = query
        tabInList.params = params
      }
      return
    }
    tabMap.value[fullPath] = tabItem
    tabs.value.push(tabItem)
    sortTabs()
  }
  // 切换标签页固定状态
  const toggleTabFixed = (fullPath: string) => {
    const tab = tabMap.value[fullPath]
    if (!tab) return
    tab.fixed = !tab.fixed
    const tabIndex = findTabIndex(fullPath, tabs.value)
    if (tabIndex !== -1) {
      const currentTab = tabs.value[tabIndex]
      if (currentTab) {
        currentTab.fixed = tab.fixed
      }
    }
    sortTabs()
  }
  // 关闭指定标签页
  const closeTab = (fullPath: string) => {
    const tab = tabMap.value[fullPath]
    if (!tab) return
    if (tab.fixed) {
      return
    }
    const tabIndex = findTabIndex(fullPath, tabs.value)
    if (tabIndex === -1) return
    tabs.value.splice(tabIndex, 1)
    const { currentRoute, push } = router
    const componentName = getComponentName(currentRoute.value)
    removeComponentFromCache(componentName)
    if (fullPath !== currentRoute.value.fullPath) {
      return
    }
    let targetTab: TabItem | null = null
    if (tabIndex === 0) {
      targetTab = tabs.value[0] || null
    } else {
      targetTab = tabs.value[tabIndex - 1] || null
    }
    if (targetTab) {
      const targetRoute = getRouteParamsFromTab(targetTab)
      push(targetRoute)
    } else {
      push('/')
    }
  }
  // 关闭当前标签页并打开新标签页
  const closeOpenPage = (newRoute?: RouteLocationRaw) => {
    const currentFullPath = router.currentRoute.value.fullPath
    closeTab(currentFullPath)
    if (newRoute) {
      try {
        const resolvedRoute = router.resolve(newRoute)
        const hasValidMatch = resolvedRoute.matched.some(match => match.path !== '/:pathMatch(.*)*')
        if (hasValidMatch) {
          router.push(newRoute)
        } else {
          router.go(-1)
        }
      } catch (error) {
        console.error('路由解析错误:', error)
        router.go(-1)
      }
    } else {
      router.go(-1)
    }
  }
  // 关闭左侧标签页
  const closeLeftTabs = (currentFullPath: string) => {
    const currentIndex = findTabIndex(currentFullPath, tabs.value)
    if (currentIndex <= 0) return
    const tabsToClose = tabs.value.slice(0, currentIndex).filter((tab) => !tab.fixed)
    const isCurrentTabInLeft = tabsToClose.some(tab => tab.fullPath === router.currentRoute.value.fullPath)
    tabsToClose.forEach((tab) => {
      closeTab(tab.fullPath)
    })
    if (isCurrentTabInLeft) {
      const targetTab = tabMap.value[currentFullPath]
      if (targetTab) {
        router.push(getRouteParamsFromTab(targetTab))
      }
    }
  }
  // 关闭右侧标签页
  const closeRightTabs = (currentFullPath: string) => {
    const currentIndex = findTabIndex(currentFullPath, tabs.value)
    if (currentIndex >= tabs.value.length - 1) return
    const tabsToClose = tabs.value.slice(currentIndex + 1).filter((tab) => !tab.fixed)
    const isCurrentTabInRight = tabsToClose.some(tab => tab.fullPath === router.currentRoute.value.fullPath)
    tabsToClose.forEach((tab) => {
      closeTab(tab.fullPath)
    })
    if (isCurrentTabInRight) {
      const targetTab = tabMap.value[currentFullPath]
      if (targetTab) {
        router.push(getRouteParamsFromTab(targetTab))
      }
    }
  }
  // 关闭其他标签页
  const closeOtherTabs = (fullPath: string) => {
    const isCurrentTabNeedClose = router.currentRoute.value.fullPath !== fullPath && !tabs.value.find(tab => tab.fullPath === router.currentRoute.value.fullPath)?.fixed
    tabs.value = tabs.value.filter((item) => item.fullPath === fullPath || item.fixed)
    const newTabMap: Record<string, TabItem> = {}
    tabs.value.forEach((item) => {
      newTabMap[item.fullPath] = item
    })
    tabMap.value = newTabMap
    const rightClickedTab = tabMap.value[fullPath]
    if (rightClickedTab) {
      const newCache = new Set<string>()
      tabs.value.forEach(tab => {
        const componentName = getComponentName({ matched: [], path: tab.path, meta: {} } as any)
        if (componentName) {
          newCache.add(componentName)
        }
      })
      cachedTabComponents.value = newCache
    }
    if (isCurrentTabNeedClose) {
      const targetTab = tabMap.value[fullPath]
      if (targetTab) {
        router.push(getRouteParamsFromTab(targetTab))
      }
    }
  }
  // 关闭全部标签页
  const closeAllTabs = () => {
    const fixedTabs = tabs.value.filter((item) => item.fixed)
    tabs.value = fixedTabs
    const newTabMap: Record<string, TabItem> = {}
    fixedTabs.forEach((item) => {
      newTabMap[item.fullPath] = item
    })
    tabMap.value = newTabMap
    clearComponentCache()
    const { push, currentRoute } = router
    const currentTab = tabMap.value[currentRoute.value.fullPath]
    if (!currentTab) {
      const firstFixedTab = fixedTabs[0]
      if (firstFixedTab) {
        const targetRoute = getRouteParamsFromTab(firstFixedTab)
        push(targetRoute)
      } else {
        push('/')
      }
    }
  }

  return {
    cachedTabComponents,
    tabs,
    tabMap,
    indexRouteName,
    tabList,
    cachedTabList,
    setIndexRouteName,
    addComponentToCache,
    removeComponentFromCache,
    clearComponentCache,
    resetTabsState,
    addTab,
    closeTab,
    closeOtherTabs,
    closeAllTabs,
    toggleTabFixed,
    closeLeftTabs,
    closeRightTabs,
    closeOpenPage
  }
})

export { getRouteParamsFromTab }
export default useTabsStore
