import Colls, { keyObj } from '@/common/utils/colls'
import {
  createRouter,
  createWebHistory,
  RouteRecordRaw
} from 'vue-router'
import Evt from '@/common/utils/evt.ts'
import { useAppSettingStore } from '@/common/app/app-setting-store.ts'
import { useAppUserStore } from '@/common/app/app-user-store.ts'
import {
  HomeMenu,
  MenuCategory
} from '@/common/app/contants.ts'
import { reloadUserInfo } from '@/common/app'
import { appBaseUrl } from '@/common'

/**
 * 特殊页面
 */
enum SpecialPage {
  Main = 'main',
  Login = 'login',
  Home = 'tsp',
  NotFund = 'notFund'
}

// 导入 src/pages 目录下的所有 page.ts 文件
// K：文件路径，V：PageConfig 对象
const configPath_pageConfig_map: Record<string, RouterTypes.PageConfig> = import.meta.glob('@/pages/**/page.ts', {eager: true, import: 'default'})

// 处理页面配置，如：默认值填充
const pageConfigs = Object.entries(configPath_pageConfig_map).map(([ configPath, pageConfig ]) => {
  let routePath = configPath.replace(/\S*pages\/(\S*)\/page.ts/, '$1')
  let {
    parent = SpecialPage.Main,
    path = routePath,
    name = routePath.substring(routePath.lastIndexOf('/') + 1),
    meta,
    component,
    beforeEnter,
  } = pageConfig

  return {
    parent,
    path,
    name,
    meta,
    component,
    beforeEnter,
  } as RouterTypes.PageConfig
})

// 按路由名称分组
export const pageInfo = keyObj(pageConfigs, it => it.name!, it => it)

/**
 * 页面配置转路由
 *
 * @param parentPageConfig
 * @param callback 路由处理函数
 * @return 路由配置
 */
function toRoute(parentPageConfig?: RouterTypes.PageConfig, callback?: (parent: string, parentRoute: RouteRecordRaw) => void): { parent: string, route: RouteRecordRaw } | null {
  if (parentPageConfig == null) return null
  let {parent, path, name, meta, props, component, beforeEnter} = parentPageConfig
  let parentRoute = {
    path,
    name,
    meta,
    props,
    component,
    beforeEnter,
    children: [],
  } as RouteRecordRaw

  callback?.(parent!, parentRoute)

  return {parent: parent!, route: parentRoute}
}

export function addRoutes(routNames: string[]) {
  if (Colls.isEmpty(routNames)) return
  let pages = routNames
      .map(it => pageInfo[it])
      .filter(it => it != null && !router.hasRoute(it.name!))
  for (let page of pages) {
    let routeInfo = toRoute(page)
    if (routeInfo == null) return
    let {parent, route} = routeInfo
    if (route.name === parent) {
      router.addRoute(route)
    } else {
      router.addRoute(parent!, route)
    }
  }
}

export function removeRoutes(routNames: string[]) {
  if (Colls.isEmpty(routNames)) return
  for (let routName of routNames) {
    if (router.hasRoute(routName)) {
      router.removeRoute(routName)
    }
  }
}

function buildDefaultRoutes() {
  return [
    toRoute(pageInfo[SpecialPage.Main]!,
        (_, parentRoute) => {
          parentRoute.redirect = '/' + SpecialPage.Home
          parentRoute.children = [
            toRoute(pageInfo[SpecialPage.Home]!)!.route,
          ]
        },
    )!.route,
    toRoute(pageInfo[SpecialPage.Login]!)!.route,
    toRoute(pageInfo[SpecialPage.NotFund]!)!.route,
  ]
}

// 创建路由实例
const router = createRouter({
  history: createWebHistory(appBaseUrl),
  routes: buildDefaultRoutes(),
})

let loading = false

router.beforeEach((to, from) => {
  const appUserStore = useAppUserStore()
  const appSettingStore = useAppSettingStore()
  let name = <string>to.name
  // 加载路由
  if (router.getRoutes().length <= 4 && appSettingStore.menus != null && appSettingStore.menus.length > 0) {
    const pages = appSettingStore.menus.filter(it => it.menuCategory === MenuCategory.Page || it.menuCategory === MenuCategory.SubPage).map(it => it.routeName)
    addRoutes(pages)
    return {
      replace: true,
      name: SpecialPage.Home,
    }
  }

  if (SpecialPage.Login === name || SpecialPage.NotFund === name) {
    return true
  }

  // 已登录
  if (appUserStore.isAuthenticated) {
    if (from.path === '/') {
      // 浏览器刷新
      reloadUserInfo()
      if (name !== SpecialPage.Home) {
        return {
          replace: true,
          name: SpecialPage.Home,
        }
      }
    } else {
      loading = true
      Evt.emit('loading', 'start')
    }
    return true
  }

  // 未登录
  return {
    replace: true,
    name: SpecialPage.Login,
  }
})

router.afterEach(() => {
  if (loading) {
    loading = false
    Evt.emit('loading', 'finish')
  }
})

Evt.on('login', _ => {
  addRoutes(useAppSettingStore().menus
      .filter(it => it.id !== HomeMenu.id && (it.menuCategory === MenuCategory.Page || it.menuCategory === MenuCategory.SubPage))
      .map(it => it.routeName))
  router.replace('/')
})

Evt.on('logout', _ => {
  removeRoutes(pageConfigs.filter(it => it.name !== SpecialPage.Main
      && it.name !== SpecialPage.Login
      && it.name !== SpecialPage.Home
      && it.name !== SpecialPage.NotFund
  ).map(it => it.name!))
  router.push({name: SpecialPage.Login})
})

export default router
