import { cloneDeep } from 'lodash-es'
import type { RouteMeta, RouteRecordRaw } from 'vue-router'
import { resolveRoutePath } from '@main/utils'
import { systemRoutes } from '@main/router/routes'
import { menuApi } from '@main/api/modules/menu'
import useSettingsStore from './settings'
import useUserStore from './user'
import useTabbarStore from './tabbar'
import type { Route } from '#/global'

const useRouteStore = defineStore(
  // 唯一ID
  'route',
  () => {
    const settingsStore = useSettingsStore()
    const userStore = useUserStore()
    const tabbarStore = useTabbarStore()

    const isGenerate = ref(false)
    const routesRaw = ref<Route.recordMainRaw[]>([])
    const filesystemRoutesRaw = ref<RouteRecordRaw[]>([])
    const currentRemoveRoutes = ref<(() => void)[]>([])
    const systemMenuTree = ref<RouteRecordRaw[]>([])
    const systemMenuList = ref<RouteRecordRaw[]>([])
    const systemRouteMenu = ref<RouteRecordRaw[]>([])

    // 将多层嵌套路由处理成两层，保留顶层和最子层路由，中间层级将被拍平
    function flatAsyncRoutes<T extends RouteRecordRaw>(route: T): T {
      if (route.children) {
        route.children = flatAsyncRoutesRecursive(route.children, [{
          path: route.path,
          title: route.meta?.title,
          i18n: route.meta?.i18n,
          icon: route.meta?.icon,
          activeIcon: route.meta?.activeIcon,
          hide: !route.meta?.breadcrumb && route.meta?.breadcrumb === false,
        }], route.path, route.meta?.auth)
      }
      return route
    }
    function flatAsyncRoutesRecursive(routes: RouteRecordRaw[], breadcrumb: Route.breadcrumb[] = [], baseUrl = '', baseAuth: RouteMeta['auth']): RouteRecordRaw[] {
      const res: RouteRecordRaw[] = []
      routes.forEach((route) => {
        if (route.children) {
          const childrenBaseUrl = resolveRoutePath(baseUrl, route.path)
          const childrenBaseAuth = baseAuth ?? route.meta?.auth
          const tmpBreadcrumb = cloneDeep(breadcrumb)
          tmpBreadcrumb.push({
            path: childrenBaseUrl,
            title: route.meta?.title,
            i18n: route.meta?.i18n,
            icon: route.meta?.icon,
            activeIcon: route.meta?.activeIcon,
            hide: !route.meta?.breadcrumb && route.meta?.breadcrumb === false,
          })
          const tmpRoute = cloneDeep(route)
          tmpRoute.path = childrenBaseUrl
          if (!tmpRoute.meta) {
            tmpRoute.meta = {}
          }
          tmpRoute.meta.auth = childrenBaseAuth
          tmpRoute.meta.breadcrumbNeste = tmpBreadcrumb
          delete tmpRoute.children
          res.push(tmpRoute)
          const childrenRoutes = flatAsyncRoutesRecursive(route.children, tmpBreadcrumb, childrenBaseUrl, childrenBaseAuth)
          childrenRoutes.forEach((item) => {
            // 如果 path 一样则覆盖，因为子路由的 path 可能设置为空，导致和父路由一样，直接注册会提示路由重复
            if (res.some(v => v.path === item.path)) {
              res.forEach((v, i) => {
                if (v.path === item.path) {
                  res[i] = item
                }
              })
            }
            else {
              res.push(item)
            }
          })
        }
        else {
          const tmpRoute = cloneDeep(route)
          tmpRoute.path = resolveRoutePath(baseUrl, tmpRoute.path)
          // 处理面包屑导航
          const tmpBreadcrumb = cloneDeep(breadcrumb)
          tmpBreadcrumb.push({
            path: tmpRoute.path,
            title: tmpRoute.meta?.title,
            i18n: tmpRoute.meta?.i18n,
            icon: tmpRoute.meta?.icon,
            activeIcon: tmpRoute.meta?.activeIcon,
            hide: !tmpRoute.meta?.breadcrumb && tmpRoute.meta?.breadcrumb === false,
          })
          if (!tmpRoute.meta) {
            tmpRoute.meta = {}
          }
          tmpRoute.meta.auth = baseAuth ?? tmpRoute.meta?.auth
          tmpRoute.meta.breadcrumbNeste = tmpBreadcrumb
          res.push(tmpRoute)
        }
      })
      return res
    }
    // 扁平化路由（将三级及以上路由数据拍平成二级）
    const flatRoutes = computed(() => {
      const returnRoutes: RouteRecordRaw[] = []
      if (settingsStore.settings.app.routeBaseOn !== 'filesystem') {
        if (routesRaw.value) {
          routesRaw.value.forEach((item) => {
            const tmpRoutes = cloneDeep(item.children || [item]) as RouteRecordRaw[]
            tmpRoutes.map((v) => {
              if (!v.meta) {
                v.meta = {}
              }
              return v
            })
            returnRoutes.push(...tmpRoutes)
          })
          returnRoutes.forEach(item => flatAsyncRoutes(item))
        }
      }
      else {
        returnRoutes.push(...cloneDeep(filesystemRoutesRaw.value) as RouteRecordRaw[])
      }
      return returnRoutes
    })
    const flatSystemRoutes = computed(() => {
      const routes = [...systemRoutes]
      routes.forEach(item => flatAsyncRoutes(item))
      return routes
    })

    // 判断是否有权限
    function hasPermission(permissions: string[], route: Route.recordMainRaw | RouteRecordRaw) {
      let isAuth = false
      if (route.meta?.auth) {
        isAuth = permissions.some((auth) => {
          if (typeof route.meta?.auth === 'string') {
            return route.meta.auth !== '' ? route.meta.auth === auth : true
          }
          else if (typeof route.meta?.auth === 'object') {
            return route.meta.auth.length > 0 ? route.meta.auth.includes(auth) : true
          }
          else {
            return false
          }
        })
      }
      else {
        isAuth = true
      }
      return isAuth
    }
    // 根据权限过滤路由
    function filterAsyncRoutes<T extends Route.recordMainRaw[] | RouteRecordRaw[]>(routes: T, permissions: string[]): T {
      const res: any = []
      routes.forEach((route) => {
        if (hasPermission(permissions, route)) {
          const tmpRoute = cloneDeep(route)
          if (tmpRoute.children) {
            tmpRoute.children = filterAsyncRoutes(tmpRoute.children, permissions)
            tmpRoute.children.length && res.push(tmpRoute)
          }
          else {
            res.push(tmpRoute)
          }
        }
      })
      return res
    }
    const routes = computed(() => {
      let returnRoutes: Route.recordMainRaw[]
      // 如果权限功能开启，则需要对路由数据进行筛选过滤
      if (settingsStore.settings.app.enablePermission) {
        returnRoutes = filterAsyncRoutes(routesRaw.value as any, userStore.permissions)
      }
      else {
        returnRoutes = cloneDeep(routesRaw.value) as any
      }
      return returnRoutes
    })

    // 将设置 meta.singleMenu 的一级路由转换成二级路由
    function convertSingleRoutes<T extends Route.recordMainRaw[]>(routes: T): T {
      routes.map((route) => {
        if (route.children) {
          route.children.forEach((item, index, arr) => {
            if (item.meta?.singleMenu) {
              arr[index] = {
                ...item,
                component: () => import('@main/layouts/index.vue'),
                children: [
                  {
                    path: '',
                    component: item.component,
                    meta: {
                      title: item.meta.title,
                      i18n: item.meta.i18n,
                      sidebar: false,
                      breadcrumb: false,
                    },
                  },
                ],
              } as RouteRecordRaw
              delete arr[index].meta!.singleMenu
            }
          })
        }
        return route
      })
      return routes
    }

    // 根据权限动态生成路由（前端生成）
    async function generateRoutesAtFront(asyncRoutes: Route.recordMainRaw[]) {
      // 设置 routes 数据
      routesRaw.value = convertSingleRoutes(cloneDeep(asyncRoutes) as any)
      isGenerate.value = true
      // 加载常驻标签页
      if (settingsStore.settings.tabbar.enable) {
        tabbarStore.initPermanentTab()
      }
    }
    // 格式化后端路由数据
    function formatBackRoutes(routes: any): Route.recordMainRaw[] {
      const mainViews = import.meta.glob('@main/views/**/*.vue')
      const microViews = import.meta.glob('@micro/views/**/*.vue')
      return routes.map((route: any) => {
        switch (route.component) {
          case 'Layout':
            route.component = () => import('@main/layouts/index.vue')
            break
          default:
            if (route.component) {
              route.component = route?.framework ? mainViews[`/main-app/views/${route.component}`] : microViews[`/micro-app/views/${route.component}`]
            }
            else {
              delete route.component
            }
        }
        if (route.children?.length) {
          route.children = formatBackRoutes(route.children)
        }
        // if (route.jumpType === MenuJumpEnum.NONE) {
        //   route.component = () => import('@main/layouts/index.vue')
        // }

        return route
      })
    }
    // 根据权限动态生成路由（后端获取）
    async function generateRoutesAtBack() {
      await menuApi.getUserMenuList(false).then(async (res) => {
        const routesMenu = res.data.filter((v: { menuType: keyof typeof MenuBtnEnum }) => v.menuType === MenuBtnEnum.MENU)
        const _routes = routesMenu.map((v: any) => {
          const linkStartWidth = v.link.startsWith('/')
          if (v.parentId && linkStartWidth) {
            v.link = v.link.substring(1)
          }
          const fPath = v.link.startsWith('/') ? v.link : `/${v.link}`
          return {
            ...v,
            name: v.name,
            id: v.id,
            parentId: v.parentId,
            component: v.component,
            path: fPath,
            meta: {
              id: v.id,
              parentId: v.parentId,
              cache: v.keepAlive,
              title: v.name,
              i18n: '',
              icon: v.icon,
              isFirstLevel: !v.parentId,
              link: v.jumpType === MenuJumpEnum.EXTERNAL_LINK ? v.link : undefined,
              path: fPath,
              iframe: v.iframe,
              visible: v.visible,
              // 指定高亮侧边栏路由，需要设置完整路由地址
              activeMenu: v.activeMenu,
              // 该路由是否在侧边栏导航中展示
              sidebar: v.sidebar,
              // 该路由是否在面包屑导航中展示
              breadcrumb: v.breadcrumb,
              // 次导航是否默认展开
              defaultOpened: v.defaultOpened,
              activeIcon: v.activeIcon,
              badge: v.badge ? v.badge === 'point' ? true : v.badge : false, // boolean | string | number
            },
          }
        })
        const routeTree = ikTree.listToTree(_routes, { needSort: true })
        routeTree.forEach((route: any) => {
          if (!route.children) {
            route.singleMenu = true
            // route.children = []
          }
        })
        // 设置 routes 数据
        routesRaw.value = await formatBackRoutes(routeTree) as any// convertSingleRoutes(formatBackRoutes(menuList) as any)
        isGenerate.value = true
        // 初始化常驻标签页
        if (settingsStore.settings.tabbar.enable) {
          tabbarStore.initPermanentTab()
        }
        systemMenuTree.value = ikTree.listToTree(res.data, { needSort: true })
        systemMenuList.value = res.data
        systemRouteMenu.value = routesMenu
        // 所有按钮
        const just_btn = await res.data.filter(
          (item: any) => item.menuType === MenuBtnEnum.PAGE_BUTTON,
        ).map(({ menuType, name, permissionCode, parentId, remark, badge }: any) => {
          return {
            menuType, name, permissionCode, parentId, remark, badge,
          }
        })
        ikStore.session.setItem(
          MenuStorageEnum.BUTTON,
          just_btn,
        )
        ikStore.session.setItem(
          MenuStorageEnum.MENU,
          routesMenu,
        )
        // 所有菜单、按钮
        ikStore.forage.setItem(MenuStorageEnum.ALL, res.data)
        // 所有菜单
        ikStore.forage.setItem(MenuStorageEnum.MENU, routesMenu)
      }).catch(() => {})
    }
    // 根据权限动态生成路由（文件系统生成）
    async function generateRoutesAtFilesystem(asyncRoutes: RouteRecordRaw[]) {
      // 设置 routes 数据
      filesystemRoutesRaw.value = convertSingleRoutes(cloneDeep(asyncRoutes) as any)
      isGenerate.value = true
      // 加载常驻标签页
      if (settingsStore.settings.tabbar.enable) {
        tabbarStore.initPermanentTab()
      }
    }
    // 记录 accessRoutes 路由，用于登出时删除路由
    function setCurrentRemoveRoutes(routes: (() => void)[]) {
      currentRemoveRoutes.value = routes
    }
    // 清空动态路由
    function removeRoutes() {
      isGenerate.value = false
      routesRaw.value = []
      filesystemRoutesRaw.value = []
      currentRemoveRoutes.value.forEach((removeRoute) => {
        removeRoute()
      })
      currentRemoveRoutes.value = []
    }

    return {
      isGenerate,
      routes,
      currentRemoveRoutes,
      flatRoutes,
      flatSystemRoutes,
      systemMenuTree,
      systemMenuList,
      systemRouteMenu,
      generateRoutesAtFront,
      generateRoutesAtBack,
      generateRoutesAtFilesystem,
      setCurrentRemoveRoutes,
      removeRoutes,
    }
  },
)

export default useRouteStore
