import { defineStore } from 'pinia'
import { routesMetas, RoutesName } from '@/router'
import { fetchRoleOptions, RoleOption } from '@/api'
import type { RoleOptions } from '@/api'

export type { RoleOptions, RoleOption } from '@/api'
export { fetchRoleOptions } from '@/api'

export type MenuTree = {
  key: RoleOption['id']
  title: string
  children: MenuTree[]
}
const transformMenuTree = (
  roleOptions: RoleOptions,
  disabledIds: RoleOption['id'][] = []
): MenuTree[] => {
  return roleOptions.map(role => ({
    title: routesMetas[role.path].title,
    key: role.id,
    children: role.children
      ? transformMenuTree(role.children, disabledIds)
      : [],
    disabled: disabledIds.includes(role.id)
  }))
}

export const transformNames = (options: RoleOptions) => {
  const names: RoutesName[] = []
  for (const option of options) {
    names.push(option.path)
    if (option.children) {
      names.push(...transformNames(option.children))
    }
  }
  return names
}

const findRole = (
  list: RoleOptions,
  predicate: (option: RoleOption) => boolean
): RoleOption | void => {
  for (const option of list) {
    if (predicate(option)) {
      return option
    } else if (option.children?.length) {
      const selected = findRole(option.children, predicate)
      if (selected) {
        return selected
      }
    }
  }
}

export const useRoleStore = defineStore('role', {
  state: () => ({
    list: [] as RoleOptions
  }),
  getters: {
    getRole: state => (name: RoutesName) =>
      findRole(state.list, role => role.path === name)!,
    getName: state => (id: RoleOption['id']) =>
      (findRole(state.list, role => role.id === id)! as any).path,
    getRoles() {
      return (names: RoutesName[]) => names.map(name => this.getRole(name))
    },
    getRoleId(state) {
      return (name: RoutesName) => this.getRole(name).id
    },
    getRoleIds() {
      return (names: RoutesName[]) => names.map(name => this.getRoleId(name))
    },
    getNames() {
      return (ids: RoleOption['id'][]) => ids.map(this.getName)
    },
    getMenuTree:
      state =>
      (disabledIds: RoleOption['id'][] = []) =>
        transformMenuTree(state.list, disabledIds)
  },
  actions: {
    async fetch() {
      this.list = await fetchRoleOptions()
    }
  }
})
