import {
  CreateSightPage,
  DevicesPage,
  EditSightPage,
  LoginPage,
  MainPage,
  SightListPage,
  MapPage,
  MediaListPage,
  MediaPreviewPage,
  MediaEditPage,
  CountryListPage,
  CityListPage,
  RouteListPage,
  UserListPage,
  SnapshotListPage,
  CarrierListPage,
  StationListPage,
  ArticleListPage,
  SnapshotCreatePage,
  CountryCreatePage,
  CityCreatePage,
  CarrierCreatePage,
  VehicleCreatePage,
  VehicleEditPage,
  CountryEditPage,
  CityEditPage,
  UserCreatePage,
  UserEditPage,
  CarrierEditPage,
  StationCreatePage,
  StationPreviewPage,
  StationEditPage,
  RouteCreatePage,
  RoutePreview,
  DemoPage,
  RouteEditPage,
  ArticlePreviewPage,
  CountryAddPage,
} from "@pages";
import {
  authStore,
  createSightStore,
  editSightStore,
  languageStore,
  ROUTE_REQUIRED_RESOURCES,
} from "@shared";
import { Layout } from "@widgets";
import { runInAction } from "mobx";
import React, { useEffect } from "react";

import {
  createBrowserRouter,
  RouterProvider,
  Navigate,
  Outlet,
  useLocation,
  useMatches,
} from "react-router-dom";

const PublicRoute = ({ children }: { children: React.ReactNode }) => {
  const { isAuthenticated } = authStore;
  const need_auth = import.meta.env.VITE_NEED_AUTH == "true";

  if (isAuthenticated || !need_auth) {
    return <Navigate to="/map" replace />;
  }
  return <>{children}</>;
};

const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
  const { isAuthenticated } = authStore;
  const need_auth = import.meta.env.VITE_NEED_AUTH == "true";

  const location = useLocation();
  const matches = useMatches();

  if (!isAuthenticated && need_auth) {
    return <Navigate to="/login" replace />;
  }

  if (location.pathname === "/" && authStore.canRead("map")) {
    return <Navigate to="/map" replace />;
  }

  const lastMatch = matches[matches.length - 1] as
    | { handle?: { permissions?: string[] } }
    | undefined;
  const requiredPermissions = lastMatch?.handle?.permissions ?? [];

  if (
    requiredPermissions.length > 0 &&
    !requiredPermissions.every((permission) => authStore.canAccess(permission))
  ) {
    return <Navigate to="/" replace />;
  }

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

const ClearStoresWrapper: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const location = useLocation();

  useEffect(() => {
    editSightStore.clearSightInfo();
    createSightStore.clearCreateSight();
    runInAction(() => {
      editSightStore.hasLoadedCommon = false;
    });

    if (
      location.pathname.includes("create") ||
      location.pathname.includes("edit") ||
      location.pathname.includes("add")
    ) {
      languageStore.setLanguage("ru");
    }
  }, [location]);

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

const router = createBrowserRouter([
  {
    path: "/login",
    element: (
      <PublicRoute>
        <LoginPage />
      </PublicRoute>
    ),
  },
  {
    path: "route-preview/:id",
    element: <RoutePreview />,
  },
  {
    path: "demo/:id",
    element: <DemoPage />,
  },
  {
    path: "/",
    element: (
      <ProtectedRoute>
        <Layout>
          <ClearStoresWrapper>
            <Outlet />
          </ClearStoresWrapper>
        </Layout>
      </ProtectedRoute>
    ),
    children: [
      {
        index: true,
        element: <MainPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/"],
        },
      },

      {
        path: "sight",
        element: <SightListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/sight"],
        },
      },
      {
        path: "sight/create",
        element: <CreateSightPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/sight/create"],
        },
      },
      {
        path: "sight/:id/edit",
        element: <EditSightPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/sight/:id/edit"],
        },
      },

      {
        path: "devices",
        element: <DevicesPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/devices"],
        },
      },

      {
        path: "map",
        element: <MapPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/map"],
        },
      },

      {
        path: "media",
        element: <MediaListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/media"],
        },
      },
      {
        path: "media/:id",
        element: <MediaPreviewPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/media/:id"],
        },
      },
      {
        path: "media/:id/edit",
        element: <MediaEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/media/:id/edit"],
        },
      },

      {
        path: "country",
        element: <CountryListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/country"],
        },
      },
      {
        path: "country/create",
        element: <CountryCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/country/create"],
        },
      },
      {
        path: "country/add",
        element: <CountryAddPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/country/add"],
        },
      },
      {
        path: "country/:id/edit",
        element: <CountryEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/country/:id/edit"],
        },
      },
      {
        path: "city",
        element: <CityListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/city"],
        },
      },
      {
        path: "city/create",
        element: <CityCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/city/create"],
        },
      },
      {
        path: "city/:id/edit",
        element: <CityEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/city/:id/edit"],
        },
      },
      {
        path: "route",
        element: <RouteListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/route"],
        },
      },
      {
        path: "route/create",
        element: <RouteCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/route/create"],
        },
      },
      {
        path: "route/:id/edit",
        element: <RouteEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/route/:id/edit"],
        },
      },

      {
        path: "user",
        element: <UserListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/user"],
        },
      },
      {
        path: "user/create",
        element: <UserCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/user/create"],
        },
      },
      {
        path: "user/:id/edit",
        element: <UserEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/user/:id/edit"],
        },
      },
      {
        path: "snapshot",
        element: <SnapshotListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/snapshot"],
        },
      },
      {
        path: "snapshot/create",
        element: <SnapshotCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/snapshot/create"],
        },
      },

      {
        path: "carrier",
        element: <CarrierListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/carrier"],
        },
      },
      {
        path: "carrier/create",
        element: <CarrierCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/carrier/create"],
        },
      },
      {
        path: "carrier/:id/edit",
        element: <CarrierEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/carrier/:id/edit"],
        },
      },
      {
        path: "station",
        element: <StationListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/station"],
        },
      },
      {
        path: "station/create",
        element: <StationCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/station/create"],
        },
      },
      {
        path: "station/:id",
        element: <StationPreviewPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/station/:id"],
        },
      },
      {
        path: "station/:id/edit",
        element: <StationEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/station/:id/edit"],
        },
      },
      {
        path: "vehicle/create",
        element: <VehicleCreatePage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/vehicle/create"],
        },
      },
      {
        path: "vehicle/:id/edit",
        element: <VehicleEditPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/vehicle/:id/edit"],
        },
      },
      {
        path: "article",
        element: <ArticleListPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/article"],
        },
      },
      {
        path: "article/:id",
        element: <ArticlePreviewPage />,
        handle: {
          permissions: ROUTE_REQUIRED_RESOURCES["/article/:id"],
        },
      },
    ],
  },
]);

export const Router = () => {
  return <RouterProvider router={router} />;
};
