import NotPermission from '@/components/error/403.tsx'
import NotFound from '@/components/error/404.tsx'
import ErrorPage from '@/components/error/error.tsx'
import Loading from '@/components/loading'
import FetchLoading from '@/components/loading/FetchLoading.tsx'
import PageLoading from '@/components/page-loading'
import { PageStoreProvider } from '@/store'
import { AuthenticatedRoute as AuthenticatedImport } from './_authenticatedRoute.tsx'
import EmptyLayout from '@/layout/EmptyLayout.tsx'
// import ListPageLayout from '@/layout/ListPageLayout.tsx'
// import { Route as DashboardImport } from '@/pages/dashboard'
import { Route as LoginRouteImport } from '@/pages/login'
import { generateUUID } from '@/utils/uuid.ts'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
    AnyRoute,
    createRootRouteWithContext,
    createRoute,
    createRouter, lazyRouteComponent,
    Outlet,
    redirect,
    RouterProvider,
} from '@tanstack/react-router'
// import { TanStackRouterDevtools } from '@tanstack/router-devtools'
import { memo, useEffect, useRef } from 'react'
import RootLayout from './layout/RootLayout'
import { IRootContext, MenuItem } from './global'
import { DevTools } from 'jotai-devtools'
import { useAtomValue } from 'jotai'
import { userMenuDataAtom } from '@/store/system/user.ts'

const PageRootLayout = () => {
    return <PageStoreProvider>
        <RootLayout/>
    </PageStoreProvider>
}

export const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            retry: false,
        }
    }
})


const rootRoute = createRootRouteWithContext<IRootContext>()({
    component: () => (

            <>
                <FetchLoading/>
                <Outlet/>
                <DevTools/>
                {/*<TanStackRouterDevtools position={'bottom-right'}/>*/}
            </>
    ),
    beforeLoad: ({ location }) => {
        if (location.pathname === '/') {
            return redirect({ to: '/dashboard' })
        }
    },
    loader: () => {

    },
    notFoundComponent: NotFound,
    pendingComponent: PageLoading,
    errorComponent: ({ error }) => <ErrorPage error={error}/>,
})

const emptyRoute = createRoute({
    getParentRoute: () => rootRoute,
    id: '/_empty',
    component: EmptyLayout,
})

const authRoute = AuthenticatedImport.update({
    getParentRoute: () => rootRoute,
    id: '/_authenticated',
} as any)

const layoutNormalRoute = createRoute({
    getParentRoute: () => rootRoute,
    id: '/_normal_layout',
    component: PageRootLayout,
})

const layoutAuthRoute = createRoute({
    getParentRoute: () => authRoute,
    id: '/_auth_layout',
    component: PageRootLayout,
})

const notAuthRoute = createRoute({
    getParentRoute: () => layoutNormalRoute,
    path: '/not-auth',
    component: NotPermission
})

// const dashboardRoute = DashboardImport.update({
//     path: '/dashboard',
//     getParentRoute: () => layoutAuthRoute,
// } as any)

const loginRoute = LoginRouteImport.update({
    path: '/login',
    getParentRoute: () => emptyRoute,
} as any)

//
// const menusRoute = createRoute({
//     getParentRoute: () => layoutAuthRoute,
//     path: '/system/menus',
// }).lazy(async () => await import('@/pages/system/menus').then(d => d.Route))
//
// const departmentsRoute = createRoute({
//     getParentRoute: () => layoutAuthRoute,
//     path: '/system/departments',
// }).lazy(async () => await import('@/pages/system/departments').then(d => d.Route))
//
// const usersRoute = createRoute({
//     getParentRoute: () => layoutAuthRoute,
//     path: '/system/users',
// }).lazy(async () => await import('@/pages/system/users').then(d => d.Route))
//
// const rolesRoute = createRoute({
//     getParentRoute: () => layoutAuthRoute,
//     path: '/system/roles',
// }).lazy(async () => await import('@/pages/system/roles').then(d => d.Route))


declare module '@tanstack/react-router' {
    interface FileRoutesByPath {
        '/_authenticated': {
            preLoaderRoute: typeof AuthenticatedImport
            parentRoute: typeof rootRoute
        },
        '/_normal_layout': {
            preLoaderRoute: typeof layoutNormalRoute
            parentRoute: typeof rootRoute
        },
        '/_layout': {
            preLoaderRoute: typeof layoutAuthRoute
            parentRoute: typeof rootRoute
        },
        // '/': {
        //     preLoaderRoute: typeof DashboardImport
        //     parentRoute: typeof layoutAuthRoute
        // },
        // '/dashboard': {
        //     preLoaderRoute: typeof DashboardImport
        //     parentRoute: typeof layoutAuthRoute
        // },
        '/login': {
            preLoaderRoute: typeof LoginRouteImport
            parentRoute: typeof rootRoute
        },
        // '/system/menus': {
        //     preLoaderRoute: typeof menusRoute
        //     parentRoute: typeof layoutAuthRoute
        // },
        // '/system/departments': {
        //     preLoaderRoute: typeof departmentsRoute
        //     parentRoute: typeof layoutAuthRoute
        // },
        // '/system/users': {
        //     preLoaderRoute: typeof usersRoute
        //     parentRoute: typeof layoutAuthRoute
        // },
        // '/system/roles': {
        //     preLoaderRoute: typeof rolesRoute
        //     parentRoute: typeof layoutAuthRoute
        // },
        '/welcome': {
            preLoaderRoute: typeof rootRoute
            parentRoute: typeof layoutAuthRoute
        },
    }
}

const generateDynamicRoutes = (menuData: MenuItem[], parentRoute: AnyRoute) => {
    // 递归生成路由，如果有routes则递归生成子路由

    const generateRoutes = (menu: MenuItem, parentRoute: AnyRoute) => {
        const path = menu.path?.replace(parentRoute.options?.path, '')
        const isLayout = menu.children && menu.children.length > 0 && menu.type === 'menu'

        if (isLayout && (!menu.path || !menu.component)) {
            //没有component的layout，直接返回
            return createRoute({
                getParentRoute: () => layoutAuthRoute,
                id: `/layout-no-path-${generateUUID()}`,
                component: EmptyLayout,
            })
        }

        // @ts-ignore 添加menu属性，方便后面获取
        const options = {
            getParentRoute: () => parentRoute,
            menu,
        } as any

        if (isLayout) {
            options.id = path ?? `/layout-${generateUUID()}`
        } else {
            if (!path) {
                console.log(`${menu.name}没有设置视图`)
            } else {
                options.path = path
            }
        }

        let component = menu.component
        // menu.type
        // 1,组件(页面)，2，IFrame，3，外链接，4，按钮
        if (menu.type === 'iframe') {
            component = '@/components/Iframe'
        }

        //处理component路径
        component = component.replace(/^\/pages/, '')
        component = component.replace(/^\//, '')

        return createRoute({
            ...options,
            component: lazyRouteComponent(() => import(`./pages/${component}`)),
            notFoundComponent: NotFound,
        })
    }

    // 对menuData递归生成路由，只处理type =1 的菜单
    const did = (menus: MenuItem[], parentRoute: AnyRoute) => {
        return menus.filter((item) => item.type === 'menu').map((item, index) => {
            // 如果有children则递归生成子路由，同样只处理type =1 的菜单
            const route = generateRoutes(item, parentRoute)

            // console.log(route)
            if (item.children && item.children.length > 0) {
                const children = did(item.children, route)
                if (children.length > 0) {
                    route.addChildren(children)
                }
            }
            route.init({ originalIndex: index })
            return route
        })
    }

    const routes = did(menuData, parentRoute)

    parentRoute.addChildren(routes)

}
const routeTree = rootRoute.addChildren(
        [
            //非Layout
            loginRoute,
            emptyRoute,

            //不带权限Layout
            layoutNormalRoute.addChildren([
                notAuthRoute,
            ]),

            //带权限Layout
            // dashboardRoute,
            authRoute.addChildren(
                    [
                        layoutAuthRoute
                        /*.addChildren(
                          [
                            menusRoute,
                            departmentsRoute,
                            usersRoute,
                            rolesRoute,
                          ]
                        ),*/
                    ]),
        ]
)


export const RootProvider = memo((props: { context: Partial<IRootContext> }) => {

    const { data: menuData, isLoading, refetch } = useAtomValue(userMenuDataAtom)

    const isFetchRef = useRef(false)

    useEffect(() => {

        if (isFetchRef.current) {
            return
        }
        isFetchRef.current = true
        refetch()

    }, [])

    if (isLoading) {
        return <PageLoading/>
    }

    generateDynamicRoutes(menuData ?? [], layoutAuthRoute)

    const router = createRouter({
        routeTree,
        context: { queryClient, menuData: [] },
        defaultPreload: 'intent',
        defaultPendingComponent: () => <Loading loading={true} delay={300}/>
    })


    return (
            <QueryClientProvider client={queryClient}>
                <RouterProvider router={router} context={{ ...props.context, menuData, queryClient }}/>
            </QueryClientProvider>
    )
})