import { clearAuthToken, getMessageFromFetchError, UserAccount, useUserFetcher } from "@frontend/kitui";
import type { OriginalUserAccount } from "@root/user";
import { clearUserData, setCustomerAccount, setUser, setUserAccount, useUserStore } from "@root/user";
import ContactFormModal from "@ui_kit/ContactForm";
import FloatingSupportChat from "@ui_kit/FloatingSupportChat";
import PrivateRoute from "@ui_kit/PrivateRoute";
import { useAfterPay } from "@utils/hooks/useAutoPay";
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
import { enqueueSnackbar } from "notistack";
import type { SuspenseProps } from "react";
import { lazy, Suspense } from "react";
import { lazily } from "react-lazily";
import { Navigate, Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { useAmoAccount } from "./api/integration";
import ListPageDummy from "./components/Dummys/pageDummys/listPageDummy";
import "./index.css";
import OutdatedLink from "./pages/auth/OutdatedLink";
import RecoverPassword from "./pages/auth/RecoverPassword";
import { Restore } from "./pages/auth/Restore";
import SigninDialog from "./pages/auth/Signin";
import SignupDialog from "./pages/auth/Signup";
import { InfoPrivilege } from "./pages/InfoPrivilege";
import AmoTokenExpiredDialog from "./pages/IntegrationsPage/IntegrationsModal/Amo/AmoTokenExpiredDialog";
import Landing from "./pages/Landing/Landing";
import Main from "./pages/main";

const MyQuizzesFull = lazy(() => import("./pages/createQuize/MyQuizzesFull"));
const QuizGallery = lazy(() => import("./pages/createQuize/QuizGallery"));
const ViewPage = lazy(() => import("./pages/ViewPublicationPage"));
const Analytics = lazy(() => import("./pages/Analytics/Analytics"));
const EditPage = lazy(() => import("./pages/startPage/EditPage"));
const { Tariffs } = lazily(() => import("./pages/Tariffs/Tariffs"));
const { DesignPage } = lazily(() => import("./pages/DesignPage/DesignPage"));
const { IntegrationsPage } = lazily(() => import("./pages/IntegrationsPage/IntegrationsPage"));
const { QuizAnswersPage } = lazily(() => import("./pages/QuizAnswersPage/QuizAnswersPage"));
const ChatImageNewWindow = lazy(() => import("@ui_kit/FloatingSupportChat/ChatImageNewWindow"));

const routeslink = [
  {
    path: "/edit",
    page: EditPage,
    header: true,
    sidebar: true,
    footer: true,
  },
  {
    path: "/design",
    page: DesignPage,
    header: true,
    sidebar: true,
    footer: true,
  },
  {
    path: "/integrations",
    page: IntegrationsPage,
    header: true,
    sidebar: true,
    footer: true,
  },
] as const;

const LazyLoading = ({ children, fallback }: SuspenseProps) => (
  <Suspense fallback={fallback ?? <></>}>{children}</Suspense>
);

export default function App() {
  const userId = useUserStore((state) => state.userId);
  const location = useLocation();
  const navigate = useNavigate();
  const { data: amoAccount } = useAmoAccount();

  useUserFetcher({
    url: `${process.env.REACT_APP_DOMAIN}/user/${userId}`,
    userId,
    onNewUser: setUser,
    onError: (error) => {
      const errorMessage = getMessageFromFetchError(error);
      if (errorMessage) {
        enqueueSnackbar(errorMessage);
        clearUserData();
        clearAuthToken();
      }
    },
  });

  useUserAccountFetcher<UserAccount>({
    url: `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1/account`,
    userId,
    onNewUserAccount: setCustomerAccount,
    onError: (error) => {
      const errorMessage = getMessageFromFetchError(error);
      if (errorMessage) {
        enqueueSnackbar(errorMessage);
        clearUserData();
        clearAuthToken();
        navigate("/signin");
      }
    },
  });

  useUserAccountFetcher<OriginalUserAccount>({
    url: `${process.env.REACT_APP_DOMAIN}/squiz/account/get`,
    userId,
    onNewUserAccount: setUserAccount,
    onError: (error) => {
      const errorMessage = getMessageFromFetchError(error);
      if (errorMessage) {
        enqueueSnackbar(errorMessage);
        clearUserData();
        clearAuthToken();
        navigate("/signin");
      }
    },
  });

  useAfterPay();

  if (location.state?.redirectTo)
    return (
      <Navigate
        to={location.state.redirectTo}
        replace
        state={{ backgroundLocation: location }}
      />
    );

  return (
    <>
      {amoAccount && <AmoTokenExpiredDialog isAmoTokenExpired={amoAccount.stale} />}
      <ContactFormModal />
      <FloatingSupportChat />
      {location.state?.backgroundLocation && (
        <Routes>
          <Route
            path="/signin"
            element={<SigninDialog />}
          />
          <Route
            path="/signup"
            element={<SignupDialog />}
          />
          <Route
            path="/recover"
            element={<Restore />}
          />
          <Route
            path="/changepwd"
            element={<RecoverPassword />}
          />
          <Route
            path="/changepwd/expired"
            element={<OutdatedLink />}
          />
        </Routes>
      )}
      <Routes location={location.state?.backgroundLocation || location}>
        <Route
          path="/"
          element={<Landing />}
        />
        <Route
          path="/signin"
          element={
            <Navigate
              to="/"
              replace
              state={{ redirectTo: "/signin" }}
            />
          }
        />
        <Route
          path="/signup"
          element={
            <Navigate
              to="/"
              replace
              state={{ redirectTo: "/signup" }}
            />
          }
        />
        <Route
          path="/recover"
          element={
            <Navigate
              to="/"
              replace
              state={{ redirectTo: "/recover" }}
            />
          }
        />
        <Route
          path="/changepwd"
          element={
            <Navigate
              to="/"
              replace
              state={{
                redirectTo: window.location.pathname + window.location.search,
              }}
            />
          }
        />
        <Route
          path="/changepwd/expired"
          element={
            <Navigate
              to="/"
              replace
              state={{ redirectTo: "/changepwd/expired" }}
            />
          }
        />
        <Route
          path="/gallery"
          element={<LazyLoading children={<QuizGallery />} />}
        />
        <Route
          path="/list"
          element={
            <LazyLoading
              children={<MyQuizzesFull />}
              fallback={<ListPageDummy />}
            />
          }
        />
        <Route
          path={"/view/:quizId"}
          element={<LazyLoading children={<ViewPage />} />}
        />
        <Route
          path={"/tariffs"}
          element={<LazyLoading children={<Tariffs />} />}
        />
        <Route
          path={"/analytics"}
          element={<LazyLoading children={<Analytics />} />}
        />
        <Route
          path={"/results/:quizId"}
          element={<LazyLoading children={<QuizAnswersPage />} />}
        />
        <Route
          path={"/qaz"}
          element={<LazyLoading children={<InfoPrivilege />} />}
        />
        <Route
          path={"/image/:srcImage"}
          element={<ChatImageNewWindow />}
        />
        <Route element={<PrivateRoute />}>
          {routeslink.map((e, i) => (
            <Route
              key={i}
              path={e.path}
              element={
                <LazyLoading
                  children={
                    <Main
                      Page={e.page}
                      header={e.header}
                      sidebar={e.sidebar}
                      footer={e.footer}
                    />
                  }
                />
              }
            />
          ))}
        </Route>
      </Routes>
    </>
  );
}
