import router, {
  reloadRouter,
  removeRoutes,
} from '@/common/router/index.ts'
import Evt from '@/common/utils/evt.ts'
import { useAppSettingStore } from '@/common/app/app-setting-store.ts'
import { useAppPageStore } from '@/common/app/app-page-store.ts'
import { ElMessage } from 'element-plus'
import type { App } from 'vue'
import { SpecialPage } from '@/common/router/constants.ts'

type Option = Partial<Pick<AppTypes.PageContext, 'params' | 'insId' | 'title'>> & Pick<AppTypes.PageContext, 'routeName'>

function checkRoute(option: string | Option) {
  let opt: Option
  if (typeof option === 'string') {
    opt = {
      routeName: option,
    }
  } else {
    opt = option
  }
  const appSettingStore = useAppSettingStore()
  const menu = appSettingStore.menus.find(it => it.routeName === opt.routeName)

  if (menu == null
    || !router.hasRoute(opt.routeName)) {
    return reloadRouter()
      .then(() => {
        const menu_ = appSettingStore.menus.find(it => it.routeName === opt.routeName)
        if (menu_ == null || !router.hasRoute(opt.routeName)) {
          ElMessage.error('页面不存在')
          return Promise.reject('页面不存在')
        } else {
          return {option: opt, menu: menu_}
        }
      })
  }
  return Promise.resolve({option: opt, menu})
}

function jump(ctx: AppTypes.PageContext) {
  return router.push({name: ctx.routeName, params: ctx.params})
    .then(err => {
      if (err == null) {
        return Promise.resolve(ctx)
      }
      return Promise.reject(err)
    })
}

/**
 * 打开页面并添加标签
 *
 * @param option
 */
function open(option: string | Option) {
  return checkRoute(option)
    .then(({option, menu}) => {
      return jump({
        insId: option.insId ?? option.routeName,
        title: option.title ?? menu.title,
        keepAlive: true,
        params: option.params ?? {},
        routeName: option.routeName,
        menuId: menu.id,
        icon: menu.icon,
        breadcrumb: menu.breadcrumb,
      })
    })
    .then(useAppPageStore().open)
}

/**
 * 关闭页面并删除标签
 *
 * @param id
 */
function close(id: string) {
  useAppPageStore()
    .closePage(id)
    .then(ctx => {
      if (ctx == null) return Promise.resolve(null)
      return jump(ctx)
    })
}

function closeCurrent(id?: string) {
  return useAppPageStore().closeCurrent(id)
    .then(ctx => {
      if (ctx == null) return Promise.resolve(null)
      return jump(ctx)
    })
}

function closeLeft(id?: string) {
  useAppPageStore().closeLeft(id)
}

function closeRight(id?: string) {
  useAppPageStore().closeRight(id)
}

function closeOther(id?: string) {
  useAppPageStore().closeOther(id)
}

function closeAll() {
  return useAppPageStore().closeAll()
    .then(jump)
}

const install = (_: App): void => {
  Evt.on('login', (_) => {
    open(SpecialPage.Home)
  })

  Evt.on('browserReflash', (routeName: string) => {
    if (routeName === SpecialPage.Home) {
      open(routeName)
      return
    }
    checkRoute(SpecialPage.Home)
      .then(({option, menu}) => {
        useAppPageStore().open({
          insId: option.insId ?? option.routeName,
          title: option.title ?? menu.title,
          keepAlive: true,
          params: option.params ?? {},
          routeName: option.routeName,
          menuId: menu.id,
          icon: menu.icon,
          breadcrumb: menu.breadcrumb,
        })
        open(routeName)
      })
  })

  Evt.on('logout', (_) => {
    const routes = router
      .getRoutes()
      .filter((it) => it.name !== SpecialPage.Main && it.name !== SpecialPage.Login && it.name !== SpecialPage.NotFound && it.name !== SpecialPage.Home)
      .map((it) => it.name as string)
    removeRoutes(routes)
    router.push({replace: true, name: SpecialPage.Login})
  })

}

export default {
  open,
  close,
  closeCurrent,
  closeLeft,
  closeRight,
  closeOther,
  closeAll,
  install,
}


