import DefaultErrorPage from '@/pages/ErrorPage'
import { frameStore, userStore } from '@/store/mobx'
import { NavigationGuardsProps, RouteModel } from '@/types/router'
import { combinationPath } from '@/utils/util'
import React, { Component } from 'react'
import KeepAlive from 'react-activation'
// import { KeepAlive } from 'react-keep-alive'
import { Redirect, Route } from "react-router-dom"

class NavigationGuards extends Component<NavigationGuardsProps, any> {
    constructor(props: NavigationGuardsProps) {
        super(props)
        userStore.check()
    }
    /**
     * 判断pathTarget是否包涵pathConfig/
     * 即，pathConfig是否为pathTarget的子路径
     * @param pathConfig 配置文件中的路径的全路径
     * @param pathTarget 用户请求的路径
     */
    static switchRoute(pathConfig: string, pathTarget: string) {
        if (pathConfig === pathTarget) return true

        const reg = new RegExp(`(^${pathConfig})(?=/)`)
        return reg.test(pathTarget)
    }


    static permissionAuthentication(authArray: string[], myPermis: string) {
        return !!authArray.find((item) => item === myPermis)
    }

    shouldComponentUpdate(nextProps: any) {
        //与上次请求的路径相同时不重新渲染
        if (this.props.location.pathname === nextProps.location.pathname) return false
        return true
    }

    /**
     * 在路由配置信息中查找用户希望访问的组件
     * @param parentPath 父路由的路径
     * @param targetPath 用户当前希望访问的路径
     * @param routeConfig 路由配置信息
     * @param ErrorPage 错误页面
     */
    static findTargetRoute(parentPath: string, targetPath: string, routeConfig: RouteModel[]): { targetRoute: RouteModel | null | Error, realPath: string } {
        for (let i = 0; i < routeConfig.length; i++) {
            const item = routeConfig[i]
            const path = combinationPath(parentPath, item.path)

            if (targetPath && NavigationGuards.switchRoute(path, targetPath)) {
                return { targetRoute: { ...item, path }, realPath: path }
            }
        }
        return { targetRoute: null, realPath: "" }
    }

    render() {
        const { location, routeConfig, match } = this.props
        //如果没有提供routeConfig则不做任何事情
        if (!routeConfig || routeConfig.length <= 0) { return null }
        const ErrorPage =  DefaultErrorPage
        //父路由的路径
        const parentPath = match && match.path
        //用户当前希望访问的路径
        const targetPath: string | undefined = location?.pathname

        //如果访问子菜单，则跳转到子菜单的默认路由
        if (targetPath && frameStore.defaultRouteMapping.has(targetPath)) {
            const targetDefaultRoute: string = frameStore.defaultRouteMapping.get(targetPath) as string
            return <Redirect to={targetDefaultRoute}></Redirect>
        }

        const findRes = targetPath && NavigationGuards.findTargetRoute(parentPath, targetPath, routeConfig)
        const targetRoute: RouteModel | null | "" | undefined | Error = findRes && findRes.targetRoute


        const isLogin = userStore.isLogin

        if (targetRoute instanceof Error) return <ErrorPage/>

        if (findRes) {
            const path: string = findRes.realPath ? findRes.realPath : ""
            targetRoute && frameStore.setCurrentRoutePath(path)
        }

        if (!targetRoute) {
            return <ErrorPage/>
        }

        if (targetRoute.redirect && !targetRoute.component) {
            return <Redirect to={targetRoute.redirect}></Redirect>
        }


        //以下部分可提出去作为用户自定义部分
        if (isLogin) {
            return <LoginHandler ErrorPage={ErrorPage} targetRoute={targetRoute}></LoginHandler>
        } else {
            return <NotLoginHandler targetRoute={targetRoute}></NotLoginHandler>
        }
}
}

//已经登陆的状态下，处理路由
function LoginHandler(props: { targetRoute: RouteModel, ErrorPage: any }): any {
    const { targetRoute, ErrorPage } = props
    const { path, auth } = targetRoute
    const noCache = targetRoute.meta?.noCache ? targetRoute.meta.noCache : false

    if (path === '/login') {
        return <Redirect to="/console/dashboard"></Redirect>
    } else if (!auth || NavigationGuards.permissionAuthentication(auth, userStore.role)) {
        return (
            <Route path={path} render={
                props => (
                    noCache ?
                        <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component> :
                        (
                            <KeepAlive id={path}>
                                <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component>
                            </KeepAlive>
                        )
                )
            }></Route>
        )
    } else {
        return <ErrorPage message="您无权访问此页"></ErrorPage>
    }
}

//未登录状态下，处理路由
function NotLoginHandler(props: { targetRoute: RouteModel}): any {
    const { targetRoute } = props
    const { path, auth } = targetRoute

    if (auth && auth.length > 0) {
        return <Redirect to="/login"></Redirect>
    } else {
        return <Route path={path} render={
            props => (
                <targetRoute.component {...props} routeConfig={targetRoute.childRoutes}></targetRoute.component>
            )
        }></Route>
    }
}

export default NavigationGuards

