import { ref } from 'vue'
import { defineStore } from 'pinia'
import type { RouteRecordRaw } from 'vue-router'
import { mapTree, toTreeArray } from 'xe-utils'
import { cloneDeep, omit } from 'lodash-es'
import { constantRoutes, systemRoutes } from '@/router/route'
import type { RouteItem } from '@/apis'
import { transformPathToName } from '@/utils'
import { asyncRouteModules } from '@/router/asyncModules'

const layoutComponentMap = {
  Layout: () => import('@/layout/index.vue'),
  ParentView: () => import('@/components/ParentView/index.vue'),
}

/** 将component由字符串转成真正的模块 */
const transformComponentView = (component: string) => {
  return layoutComponentMap[component as keyof typeof layoutComponentMap] || asyncRouteModules[component]
}

/**
 * @description 前端来做排序、格式化
 * @params {menus} 后端返回的路由数据，已经根据当前用户角色过滤掉了没权限的路由
 * 1. 对后端返回的路由数据进行排序，格式化
 * 2. 同时将component由字符串转成真正的模块
 */
const formatAsyncRoutes = (menus: RouteItem[]) => {
  if (!menus.length) return []

  const pathMap = new Map()
  return mapTree(menus, (item) => {
    pathMap.set(item.id, item.path)

    if (item.children?.length) {
      item.children.sort((a, b) => (a?.sort ?? 0) - (b?.sort ?? 0))
    }

    // 部分子菜单，例如：通知公告新增、查看详情，需要选中其父菜单
    if (item.parentId && item.type === 2 && item.permission) {
      item.activeMenu = pathMap.get(item.parentId)
    }

    return {
      path: item.path,
      name: item.name ?? transformPathToName(item.path),
      component: transformComponentView(item.component),
      redirect: item.redirect,
      meta: {
        title: item.title,
        hidden: item.isHidden,
        keepAlive: item.isCache,
        icon: item.icon,
        showInTabs: item.showInTabs,
        activeMenu: item.activeMenu,
      },
    }
  }) as unknown as RouteRecordRaw[]
}

/** 判断路由层级是否大于 2 */
export const isMultipleRoute = (route: RouteRecordRaw) => {
  return route.children?.some((child) => child.children?.length) ?? false
}

/** 路由降级（把三级及其以上的路由转化为二级路由） */
export const flatMultiLevelRoutes = (routes: RouteRecordRaw[]) => {
  return cloneDeep(routes).map((route) => {
    if (!isMultipleRoute(route)) return route

    return {
      ...route,
      children: toTreeArray(route.children).map((item) => omit(item, 'children')) as RouteRecordRaw[],
    }
  })
}

const storeSetup = () => {
  // 所有路由(常驻路由 + 动态路由)
  const routes = ref<RouteRecordRaw[]>([])
  // 动态路由(异步路由)
  const asyncRoutes = ref<RouteRecordRaw[]>([])

  // 合并路由
  const setRoutes = (data: RouteRecordRaw[]) => {
    // 合并路由并排序
    routes.value = [...constantRoutes, ...systemRoutes].concat(data)
      .sort((a, b) => (a.meta?.sort ?? 0) - (b.meta?.sort ?? 0))
    asyncRoutes.value = data
  }

  // 生成路由
  const generateRoutes = async (): Promise<RouteRecordRaw[]> => {
    // 获取路由数据并已通过适配器转换
    // const { data } = await getUserRouteWithAdapter()
    const data = [{
      id: 1000,
      parentId: 0,
      title: '系统管理',
      type: 1,
      path: '/system',
      name: 'System',
      component: 'Layout',
      redirect: '/system/user',
      icon: 'settings',
      isExternal: false,
      isCache: false,
      isHidden: false,
      sort: 1,
      children: [
        {
          id: 1010,
          parentId: 1000,
          title: '用户管理',
          type: 2,
          path: '/system/user',
          name: 'SystemUser',
          component: 'system/user/index',
          icon: 'user',
          isExternal: false,
          isCache: false,
          isHidden: false,
          sort: 1,
        },
        {
          id: 1030,
          parentId: 1000,
          title: '角色管理',
          type: 2,
          path: '/system/role',
          name: 'SystemRole',
          component: 'system/role/index',
          icon: 'user-group',
          isExternal: false,
          isCache: false,
          isHidden: false,
          sort: 2,
        },
        {
          id: 1050,
          parentId: 1000,
          title: '菜单管理',
          type: 2,
          path: '/system/menu',
          name: 'SystemMenu',
          component: 'system/menu/index',
          icon: 'menu',
          isExternal: false,
          isCache: false,
          isHidden: false,
          sort: 3,
        },
        {
          id: 1070,
          parentId: 1000,
          title: '个人中心',
          type: 2,
          path: '/user/profile',
          name: 'UserProfile',
          component: 'user/profile/index',
          icon: 'user',
          isExternal: false,
          isCache: false,
          isHidden: false,
          sort: 4,
        },
      ],
    }]
    // 使用已转换的数据生成路由
    const asyncRoutes = formatAsyncRoutes(data as unknown as RouteItem[])
    const flatRoutes = flatMultiLevelRoutes(cloneDeep(asyncRoutes))
    setRoutes(asyncRoutes)
    return flatRoutes
  }

  return {
    routes,
    asyncRoutes,
    generateRoutes,
  }
}

export const useRouteStore = defineStore('route', storeSetup, { persist: true })
