import type { ReactNode } from 'react';
import { Navigate, Outlet, useLocation, useRoutes } from 'react-router-dom';
import type { RouteObject } from 'react-router-dom';
import BasicLayout from '@/layouts/BasicLayout';
import NotFound from '@/pages/error/NotFound';
import Login from '@/pages/login';
import { useAuthStore } from '@/store/auth';
import {
  appRoutes,
  findFirstPath,
  type AppRouteItem,
} from './routeConfig';

/** 未登录时跳转登录页，并记录来源地址。 */
const RequireAuth = ({ children }: { children: ReactNode }) => {
  const token = useAuthStore((state) => state.token);
  const location = useLocation();

  if (!token) {
    return (
      <Navigate
        to="/login"
        replace
        state={{ from: `${location.pathname}${location.search}` }}
      />
    );
  }

  return <>{children}</>;
};

/** 分组路由的默认跳转：进入第一个子页面。 */
const GroupIndexRedirect = ({ item }: { item: AppRouteItem }) => {
  const target = findFirstPath(item);

  return <Navigate to={target ?? '/dashboard'} replace />;
};

/** 把嵌套的菜单配置转换成 react-router 的嵌套路由。 */
const toRouteObjects = (items: AppRouteItem[], parentPath = ''): RouteObject[] =>
  items.map((item) => {
    const relativePath =
      parentPath && item.path.startsWith(parentPath)
        ? item.path.slice(parentPath.length).replace(/^\//, '')
        : item.path.replace(/^\//, '');

    const childRoutes = item.children ? toRouteObjects(item.children, item.path) : [];

    const route: RouteObject = {
      path: relativePath,
      element: item.element ?? <Outlet />,
    };

    if (childRoutes.length > 0) {
      route.children = [
        { index: true, element: <GroupIndexRedirect item={item} /> },
        ...childRoutes,
      ];
    }

    return route;
  });

const routes: RouteObject[] = [
  { path: '/login', element: <Login /> },
  {
    path: '/',
    element: (
      <RequireAuth>
        <BasicLayout />
      </RequireAuth>
    ),
    children: [
      { index: true, element: <Navigate to="/dashboard" replace /> },
      ...toRouteObjects(appRoutes),
      { path: '*', element: <NotFound /> },
    ],
  },
];

const AppRouter = () => useRoutes(routes);

export default AppRouter;
