import { useEffect, useMemo, useState } from "react";
import { Navigate, type RouteObject, useRoutes } from "react-router-dom";
import { fetchDynamicRoutes } from "../api/upms";
import { LoadingView } from "../components/LoadingView";
import { DefaultLayout } from "../layouts/DefaultLayout";
import { SidebarLayout } from "../layouts/SidebarLayout";
import { DashboardPage } from "../pages/DashboardPage";
import { LoginPage } from "../pages/LoginPage";
import { NotFoundPage } from "../pages/NotFoundPage";
import { RoutePlaceholderPage } from "../pages/RoutePlaceholderPage";
import type { RouteNode } from "../types/route";

const layoutRegistry = {
    DEFAULT: DefaultLayout,
    SIDEBAR: SidebarLayout
};

function toChildRoute(route: RouteNode): RouteObject {
    const Component = route.component === "dashboard" ? DashboardPage : RoutePlaceholderPage;

    return {
        path: route.path === "/" ? "" : route.path.replace(/^\//, ""),
        element: <Component />
    };
}

function buildRoutes(dynamicRoutes: RouteNode[]): RouteObject[] {
    const grouped = dynamicRoutes.reduce<Record<string, RouteNode[]>>((acc, route) => {
        acc[route.layout] ??= [];
        acc[route.layout].push(route);
        return acc;
    }, {});

    const layoutRoutes = Object.entries(grouped).map(([layout, routes]) => {
        const Layout = layoutRegistry[layout as keyof typeof layoutRegistry] ?? DefaultLayout;
        return {
            path: "/",
            element: <Layout />,
            children: routes.map(toChildRoute)
        } satisfies RouteObject;
    });

    return [
        { path: "/login", element: <LoginPage /> },
        ...layoutRoutes,
        { path: "*", element: <NotFoundPage /> }
    ];
}

export function AppRouter() {
    const [dynamicRoutes, setDynamicRoutes] = useState<RouteNode[]>([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        fetchDynamicRoutes()
            .then((routes) => setDynamicRoutes(routes))
            .catch(() =>
                setDynamicRoutes([
                    {
                        id: "dashboard",
                        path: "/",
                        name: "dashboard",
                        component: "dashboard",
                        layout: "SIDEBAR",
                        meta: {
                            title: "控制台",
                            hidden: false,
                            permissionCodes: ["dashboard:view"]
                        },
                        children: []
                    }
                ])
            )
            .finally(() => setLoading(false));
    }, []);

    const routes = useMemo(() => {
        if (loading) {
            return [{ path: "*", element: <LoadingView message="正在加载路由..." /> }];
        }

        const nextRoutes = buildRoutes(dynamicRoutes);
        if (dynamicRoutes.length === 0) {
            nextRoutes.unshift({ path: "/", element: <Navigate to="/login" replace /> });
        }
        return nextRoutes;
    }, [dynamicRoutes, loading]);

    return useRoutes(routes);
}
