import React, { useCallback, useEffect, useState } from "react";
import { Routes, Route } from "react-router-dom";
// import { AuthContext } from "@/context/Auth";
// import { GlobalContext } from "@/context/Global";

import PrivateRoute from "./PrivateRoutes";
import PublicRoute from "./PublicRoutes";
import { PublicWrapper } from "@/components/PublicWrapper";
import { NotFoundPage } from "@/pages/404";
import { SnackBar } from "@/components/SnackBar";
import { SessionExpiredModal } from "@/components/SessionExpiredModal";

// generatePagesRoutes
import { AdminWrapper } from "@/components/AdminWrapper";

import {
  AddAdminSettingTablePage,
  AddAdminSowTablePage,
  AddAdminWireframeTablePage,
  AdminForgotPage,
  AdminLoginPage,
  AdminProfilePage,
  AdminResetPage,
  EditAdminProjectTablePage,
  EditAdminSettingTablePage,
  EditAdminSowTablePage,
  AdminEmailListPage,
  AdminUserListPage,
  AskGptAdminSowTablePage,
  ListAdminDeploymentTablePage,
  AdminBaasPage,
  ListAdminProjectTablePage,
  ListAdminSettingTablePage,
  ListAdminSowTablePage,
  ListAdminWireframeTablePage,
  AdminDashboardPage,
  LandingPage,
  Pay,
  PreWireframeFlow,
  ViewAdminDeploymentTablePage,
  ViewAdminProjectTablePage,
  ViewAdminSettingTablePage,
  ViewAdminSowTablePage,
  ViewAdminWireframeTablePage,
  MagicLoginVerifyPage,
  UserMagicLoginPage,
  TestGPT,
  Postman,
  GenerateUI,
  GenerateQuery,
} from "./LazyLoad";

import EditWireframePage from "@/pages/Admin/Edit/EditWireframePage";
import { useContexts } from "@/hooks/useContexts";
import { RoleEnum } from "@/utils/Enums";
import { LazyLoad } from "@/components/LazyLoad";
import { RouteChangeModal } from "@/components/RouteChangeModal";

export interface DynamicWrapperProps {
  isAuthenticated?: boolean;
  role?: string;
  children: React.ReactNode;
}

export const DynamicWrapper: React.FC<DynamicWrapperProps> = ({
  isAuthenticated,
  role,
  children,
}) => {
  if (!isAuthenticated) {
    return <PublicWrapper>{children}</PublicWrapper>;
  }
  if (isAuthenticated) {
    if (role === RoleEnum.ADMIN) {
      return <AdminWrapper>{children}</AdminWrapper>;
    }
  }
};

export interface NotFoundProps {
  isAuthenticated?: boolean;
  role?: string | null;
}

export const NotFound: React.FC<NotFoundProps> = ({
  isAuthenticated,
  role,
}) => {
  if (!isAuthenticated) {
    return (
      <PublicWrapper>
        <NotFoundPage />
      </PublicWrapper>
    );
  }
  if (isAuthenticated) {
    if (role === RoleEnum.ADMIN) {
      return (
        <AdminWrapper>
          <NotFoundPage />
        </AdminWrapper>
      );
    }
  }
};

export default () => {
  const {
    globalState,
    globalDispatch: dispatch,
    authState: state,
    setGlobalState,
  } = useContexts();

  const isOpen = globalState?.isOpen ?? false;
  const openRouteChangeModal = globalState?.openRouteChangeModal ?? false;

  const [screenSize, setScreenSize] = useState(window.innerWidth);

  function setDimension(e: Event) {
    const target = e.currentTarget as Window;
    if (target.innerWidth >= 1024) {
      toggleSideBar(true);
    } else toggleSideBar(false);
    setScreenSize(target.innerWidth);
  }

  // const toTop = () => {
  //   containerRef.current.scrollTo(0, 0);
  // };

  const portalChange = useCallback(
    (e) => {
      if (
        (e.ctrlKey || e.metaKey) &&
        e.shiftKey &&
        e.altKey &&
        ["r", "R"].includes(e.key)
      ) {
        setGlobalState("openRouteChangeModal", true);
      }
      // console.log("PORTAL CHANGE  >>", openRouteChangeModal, e);
      if (["Escape", "escape", "ESCAPE", "Esc", "esc"].includes(e.key)) {
        setGlobalState("openRouteChangeModal", false);
      }
    },
    [openRouteChangeModal]
  );

  const toggleSideBar = (open: boolean) => {
    if (isOpen && screenSize < 1024) {
      dispatch({
        type: "OPEN_SIDEBAR",
        payload: { isOpen: open },
      });
    } else if (!isOpen && screenSize >= 1024) {
      dispatch({
        type: "OPEN_SIDEBAR",
        payload: { isOpen: open },
      });
    }
  };

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    window.addEventListener(
      "resize",
      (e) => {
        const target = e.currentTarget as Window;
        if (target.innerWidth >= 1024) {
          toggleSideBar(true);
        } else toggleSideBar(false);
        setScreenSize(target.innerWidth);
      },
      { signal }
    );

    return () => {
      controller.abort();
    };
  }, [screenSize]);

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    window.addEventListener("keydown", portalChange, { signal });

    return () => {
      controller.abort();
    };
  }, []);

  return (
    <div
      onClick={() => {
        isOpen ? toggleSideBar(false) : null;
      }}
      className={`h-svh min-h-svh max-h-svh overflow-y-hidden overflow-x-hidden bg-white`}
    >
      <Routes>
        <Route
          path="/admin/profile"
          element={
            <PrivateRoute
              access={"admin"}
              path={"/admin/profile"}
              element={
                <AdminWrapper>
                  <AdminProfilePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/email"
          element={
            <PrivateRoute
              access={"admin"}
              path={"/admin/email"}
              element={
                <AdminWrapper>
                  <AdminEmailListPage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/add-sow"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/add-sow"}
              element={
                <AdminWrapper>
                  <AddAdminSowTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/edit-sow/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/edit-sow/:id"}
              element={
                <AdminWrapper>
                  <EditAdminSowTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/view-sow/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/view-sow/:id"}
              element={
                <AdminWrapper>
                  <ViewAdminSowTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/ask-gpt/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/ask-gpt/:id"}
              element={
                <AdminWrapper>
                  <AskGptAdminSowTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/requirements"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/requirements"}
              element={
                <AdminWrapper>
                  <ListAdminSowTablePage />
                </AdminWrapper>
              }
            />
          }
        />
        <Route
          path="/admin/generate-ui/:component"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/generate-ui/:component"}
              element={
                <AdminWrapper>
                  <GenerateUI />
                </AdminWrapper>
              }
            />
          }
        />
        <Route
          path="/admin/generate-query/:query"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/generate-query/:query"}
              element={
                <AdminWrapper>
                  <GenerateQuery />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/requirement/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/requirement/:id"}
              element={
                <AdminWrapper>
                  <PreWireframeFlow />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/add-setting"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/add-setting"}
              element={
                <AdminWrapper>
                  <AddAdminSettingTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/edit-setting/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/edit-setting/:id"}
              element={
                <AdminWrapper>
                  <EditAdminSettingTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/view-setting/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/view-setting/:id"}
              element={
                <AdminWrapper>
                  <ViewAdminSettingTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/setting"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/setting"}
              element={
                <AdminWrapper>
                  <ListAdminSettingTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/add-wireframe"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/add-wireframe"}
              element={
                <AdminWrapper>
                  <AddAdminWireframeTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/view-wireframe/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/view-wireframe/:id"}
              element={
                <AdminWrapper>
                  <ViewAdminWireframeTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/build"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/build"}
              element={
                <AdminWrapper>
                  <ListAdminWireframeTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/edit-project/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/edit-project/:id"}
              element={
                <AdminWrapper>
                  <EditAdminProjectTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/view-project/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/view-project/:id"}
              element={
                <AdminWrapper>
                  <ViewAdminProjectTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/baas"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/baas"}
              element={
                <AdminWrapper>
                  <AdminBaasPage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/project"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/project"}
              element={
                <AdminWrapper>
                  <ListAdminProjectTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/users"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/users"}
              element={
                <AdminWrapper>
                  <AdminUserListPage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/deployment"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/deployment"}
              element={
                <AdminWrapper>
                  <ListAdminDeploymentTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/view-deployment/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/view-deployment/:id"}
              element={
                <AdminWrapper>
                  <ViewAdminDeploymentTablePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/edit-wireframe/:id"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/edit-wireframe/:id"}
              element={
                <AdminWrapper>
                  <EditWireframePage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/admin/dashboard"
          element={
            <PrivateRoute
              access={["admin", "super_admin"]}
              path={"/admin/dashboard"}
              element={
                <AdminWrapper>
                  <AdminDashboardPage />
                </AdminWrapper>
              }
            />
          }
        />

        <Route
          path="/"
          element={
            <PublicRoute
              path={"/"}
              element={
                <PublicWrapper>
                  <LandingPage />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/admin/login"
          element={
            <PublicRoute
              path={"/admin/login"}
              element={
                <PublicWrapper>
                  <AdminLoginPage />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/admin/forgot"
          element={
            <PublicRoute
              path={"/admin/forgot"}
              element={
                <PublicWrapper>
                  <AdminForgotPage />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/admin/reset"
          element={
            <PublicRoute
              path={"/admin/reset"}
              element={
                <PublicWrapper>
                  <AdminResetPage />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/magic-login"
          element={
            <PublicRoute
              path={"/magic-login"}
              element={
                <PublicWrapper>
                  <UserMagicLoginPage />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/magic-login/verify"
          element={
            <PublicRoute
              path={"/magic-login/verify"}
              element={
                <PublicWrapper>
                  <MagicLoginVerifyPage />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/pay"
          element={
            <PublicRoute
              path={"/pay"}
              element={
                <PublicWrapper>
                  <Pay />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/gpt"
          element={
            <PublicRoute
              path={"/gpt"}
              element={
                <PublicWrapper>
                  <TestGPT />
                </PublicWrapper>
              }
            />
          }
        />
        <Route
          path="/tools/postman"
          element={
            <PublicRoute
              path={"/tools/postman"}
              element={
                <PublicWrapper>
                  <Postman />
                </PublicWrapper>
              }
            />
          }
        />

        {/* Custom Routes */}

        <Route
          path={"*"}
          element={
            <PublicRoute
              path={"*"}
              element={
                <NotFound
                  isAuthenticated={state?.isAuthenticated}
                  role={state?.role}
                />
              }
            />
          }
        />
      </Routes>
      <SessionExpiredModal />
      <SnackBar />

      <LazyLoad>
        <RouteChangeModal
          isOpen={openRouteChangeModal}
          onClose={() => setGlobalState("openRouteChangeModal", false)}
          options={[
            ...(state?.isAuthenticated
              ? [
                  {
                    name: `${state?.role} Login`,
                    route: `/${state?.role}/login`,
                  },
                ]
              : [
                  { name: "Admin Login", route: "/admin/login" },
                  { name: "User Login", route: "/user/login" },
                ]),
          ]}
          title="Change Route"
        />
      </LazyLoad>
    </div>
  );
};
