import { useCallback, useEffect, useMemo, useState } from "react";
import {
  Routes,
  Route,
  Navigate,
  Outlet,
  useLocation,
  useNavigate,
} from "react-router-dom";
import { useAuth } from "@/auth";
import { useDispatch, useSelector } from "react-redux";
import { actions, selectors } from "@/store";
import routes, {
  hasNavigation,
  getRouteBy,
  hasNoFooter,
  hasNoHeader,
  hasNavbarFooter,
  hasFullDataModal,
} from "@/routes";
import BirthdayPage from "../BirthdayPage";
import BirthtimePage from "../BirthtimePage";
import CreateProfilePage from "../CreateProfilePage";
import EmailEnterPage from "../EmailEnterPage";
import SubscriptionPage from "../SubscriptionPage";
import PaymentPage from "../PaymentPage";
import WallpaperPage from "../WallpaperPage";
import StaticPage from "../StaticPage";
import NotFoundPage from "../NotFoundPage";
import Header from "../Header";
import Navbar from "../Navbar";
import Footer from "../Footer";
import "./styles.css";
import DidYouKnowPage from "../DidYouKnowPage";
import FreePeriodInfoPage from "../FreePeriodInfoPage";
import AttentionPage from "../AttentionPage";
import FeedbackPage from "../FeedbackPage";
import CompatibilityPage from "../Compatibility";
import BreathPage from "../BreathPage";
import PriceListPage from "../PriceListPage";
import CompatResultPage from "../CompatResultPage";
import HomePage from "../HomePage";
import UserCallbacksPage from "../UserCallbacksPage";
import NavbarFooter, { INavbarHomeItems } from "../NavbarFooter";
import { EPathsFromHome } from "@/store/siteConfig";
import parseAPNG, { APNG } from "apng-js";
import { useApi, useApiCall } from "@/api";
import { Asset } from "@/api/resources/Assets";
import PaymentResultPage from "../PaymentPage/results";
import PaymentSuccessPage from "../PaymentPage/results/SuccessPage";
import PaymentFailPage from "../PaymentPage/results/ErrorPage";
import { StripePage } from "../StripePage";
import AuthPage from "../AuthPage";
import AuthResultPage from "../AuthResultPage";
import MagicBallPage from "../pages/MagicBall";
import BestiesHoroscopeResult from "../pages/BestiesHoroscopeResult";
import PredictionMoonResult from "../pages/PredictionMoonResult";
import MyHoroscopeResult from "../pages/MyHoroscopeResult";
import ThermalResult from "../pages/ThermalResult";
import MoonPhaseTrackerResult from "../pages/MoonPhaseTrackerResult";
import EnergyVampirismResult from "../pages/EnergyVampirismResult";
import NameHoroscopeResult from "../pages/NameHoroscopeResult";
import GenderPage from "../pages/Gender";
import QuestionnairePage from "../pages/Questionnaire";
import GoalSetupPage from "../pages/GoalSetup";
import HyperPersonalizedAstrologyPage from "../pages/HyperPersonalizedAstrologyPage";
import NoBirthtimePage from "../pages/NoBirthtime";
import LoadingInRelationshipPage from "../pages/LoadingInRelationship";
import WorksForUsPage from "../pages/WorksForUs";
import RelationshipAlmostTherePage from "../pages/RelationshipAlmostThere";
import Modal from "../Modal";
import FullDataModal from "../FullDataModal";

function App(): JSX.Element {
  const [isSpecialOfferOpen, setIsSpecialOfferOpen] = useState<boolean>(false);
  const [leoApng, setLeoApng] = useState<Error | APNG>(Error);
  const [padLockApng, setPadLockApng] = useState<Error | APNG>(Error);
  const navigate = useNavigate();
  const api = useApi();
  const dispatch = useDispatch();
  const { token, user } = useAuth();

  const closeSpecialOfferAttention = () => {
    setIsSpecialOfferOpen(false);
    navigate(routes.client.auth());
  };

  const assetsData = useCallback(async () => {
    const { assets } = await api.getAssets({
      category: String("au"),
    });
    return assets;
  }, [api]);

  const { data } = useApiCall<Asset[]>(assetsData);

  useEffect(() => {
    (async () => {
      if (!token.length || !user) return;
      const {
        user: { has_subscription },
      } = await api.getSubscriptionStatus({
        token,
      });

      if (has_subscription && user) {
        return dispatch(actions.status.update("subscribed"));
      }
      if (!has_subscription && user) {
        return dispatch(actions.status.update("unsubscribed"));
      }
      if (!user) {
        return dispatch(actions.status.update("lead"));
      }
    })();
  }, [dispatch, api, token, user]);

  useEffect(() => {
    async function getApng() {
      if (!data) return;
      const response = await fetch(
        data.find((item) => item.key === "au.apng.leo")?.url || ""
      );
      const arrayBuffer = await response.arrayBuffer();
      setLeoApng(parseAPNG(arrayBuffer));
    }
    getApng();
  }, [data]);

  useEffect(() => {
    (async () => {
      const response = await fetch("/padlock_icon_animation_closing.png");
      const arrayBuffer = await response.arrayBuffer();
      setPadLockApng(parseAPNG(arrayBuffer));
    })();
  }, []);

  useEffect(() => {
    if (!user) return;
    dispatch(actions.form.addEmail(user.email));
  }, []);

  return (
    <Routes>
      <Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}>
        {/* Test Routes Start */}
        <Route path={routes.client.notFound()} element={<NotFoundPage />} />
        <Route path={routes.client.gender()} element={<GenderPage />} />
        <Route
          path={routes.client.questionnaire()}
          element={<QuestionnairePage />}
        >
          <Route path=":stepId" element={<QuestionnairePage />}>
            <Route path=":question" element={<QuestionnairePage />} />
          </Route>
        </Route>
        <Route path={routes.client.goalSetup()} element={<GoalSetupPage />} />
        <Route
          path={routes.client.hyperPersonalizedAstrology()}
          element={<HyperPersonalizedAstrologyPage />}
        />
        <Route path={routes.client.noTime()} element={<NoBirthtimePage />} />
        <Route
          path={routes.client.loadingInRelationship()}
          element={<LoadingInRelationshipPage />}
        />
        <Route path={routes.client.worksForUs()} element={<WorksForUsPage />} />
        <Route
          path={routes.client.relationshipAlmostThere()}
          element={<RelationshipAlmostTherePage />}
        />
        {/* Test Routes End */}

        <Route
          path={routes.client.paymentResult()}
          element={<PaymentResultPage />}
        />
        <Route
          path={routes.client.paymentSuccess()}
          element={<PaymentSuccessPage />}
        />
        <Route
          path={routes.client.paymentFail()}
          element={<PaymentFailPage />}
        />
        <Route element={<AuthorizedUserOutlet />}>
          <Route path={routes.client.root()} element={<MainPage />} />
          <Route path={routes.client.birthday()} element={<BirthdayPage />} />
          <Route
            path={routes.client.didYouKnow()}
            element={<DidYouKnowPage />}
          />
          <Route
            path={routes.client.freePeriodInfo()}
            element={<FreePeriodInfoPage />}
          />
          <Route
            path={routes.client.attention()}
            element={
              <AttentionPage
                isOpenModal={isSpecialOfferOpen}
                onCloseSpecialOffer={closeSpecialOfferAttention}
              />
            }
          />
          <Route path={routes.client.feedback()} element={<FeedbackPage />} />
          <Route path={routes.client.birthtime()} element={<BirthtimePage />} />
          <Route path={routes.client.createProfile()} element={<SkipStep />} />
          <Route
            path={routes.client.emailEnter()}
            element={<EmailEnterPage />}
          />
          <Route
            path={routes.client.auth()}
            element={<AuthPage padLockApng={padLockApng} />}
          />
          <Route
            path={routes.client.authResult()}
            element={<AuthResultPage />}
          />
          <Route path={routes.client.static()} element={<StaticPage />} />
          <Route path={routes.client.priceList()} element={<PriceListPage />} />
          {/* <Route
            path={routes.client.wallpaper()}
            element={<ProtectWallpaperPage />}
          /> */}
        </Route>
        <Route element={<AuthorizedUserOutlet />}>
          <Route
            path={routes.client.subscription()}
            element={<SubscriptionPage />}
          >
            <Route path=":subPlan" element={<SubscriptionPage />} />
          </Route>
        </Route>
        {/* <Route element={<PrivateOutlet />}> */}
        <Route element={<AuthorizedUserOutlet />}>
          {/* <Route
              path={routes.client.subscription()}
              element={<SubscriptionPage />}
            /> */}
          <Route
            path={routes.client.paymentMethod()}
            element={<PaymentPage />}
          />
          <Route
            path={routes.client.paymentStripe()}
            element={<StripePage />}
          />
        </Route>
        {/* <Route element={<PrivateSubscriptionOutlet />}> */}
        <Route path={routes.client.home()} element={<HomePage />} />
        <Route
          path={routes.client.compatibility()}
          element={<CompatibilityPage />}
        />
        <Route
          path={routes.client.compatibilityResult()}
          element={<CompatResultPage />}
        />
        <Route
          path={routes.client.breath()}
          element={<BreathPage leoApng={leoApng} />}
        />
        <Route
          path={routes.client.breathResult()}
          element={<UserCallbacksPage />}
        />
        <Route path={routes.client.wallpaper()} element={<WallpaperPage />} />
        <Route path={routes.client.magicBall()} element={<MagicBallPage />} />
        <Route
          path={routes.client.horoscopeBestiesResult()}
          element={<BestiesHoroscopeResult />}
        />
        <Route
          path={routes.client.predictionMoonResult()}
          element={<PredictionMoonResult />}
        />
        <Route
          path={routes.client.myHoroscopeResult()}
          element={<MyHoroscopeResult />}
        />
        <Route
          path={routes.client.thermalResult()}
          element={<ThermalResult />}
        />
        <Route
          path={routes.client.moonPhaseTracker()}
          element={<MoonPhaseTrackerResult />}
        />
        <Route
          path={routes.client.energyVampirismResult()}
          element={<EnergyVampirismResult />}
        />
        <Route
          path={routes.client.nameHoroscopeResult()}
          element={<NameHoroscopeResult />}
        />
        {/* </Route> */}
        {/* </Route> */}
        <Route path="*" element={<NotFoundPage />} />
      </Route>
    </Routes>
  );
}

interface LayoutProps {
  setIsSpecialOfferOpen: React.Dispatch<React.SetStateAction<boolean>>;
}

function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element {
  const location = useLocation();
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const showNavbar = hasNavigation(location.pathname);
  const showFooter = hasNoFooter(location.pathname);
  const showHeader = hasNoHeader(location.pathname);
  const isRouteFullDataModal = hasFullDataModal(location.pathname);
  const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
  const changeIsSpecialOfferOpen = () => setIsSpecialOfferOpen(true);
  const homeConfig = useSelector(selectors.selectHome);
  const showNavbarFooter = homeConfig.isShowNavbar;

  const birthdate = useSelector(selectors.selectBirthdate);
  const dataItems = useMemo(() => [birthdate], [birthdate]);
  const [isShowFullDataModal, setIsShowFullDataModal] =
    useState<boolean>(false);

  useEffect(() => {
    setIsShowFullDataModal(getIsShowFullDataModal(dataItems));
  }, [dataItems]);

  const onCloseFullDataModal = (_birthDate: string) => {
    console.log("onCloseFullDataModal", _birthDate);
    dispatch(actions.form.addDate(_birthDate));
    setIsShowFullDataModal(getIsShowFullDataModal(dataItems));
  };

  const handleCompatibility = () => {
    dispatch(
      actions.siteConfig.update({
        home: {
          pathFromHome: EPathsFromHome.navbar,
          isShowNavbar: showNavbarFooter,
        },
      })
    );
    navigate(routes.client.compatibility());
  };
  const handleBreath = () => {
    dispatch(
      actions.siteConfig.update({
        home: {
          pathFromHome: EPathsFromHome.navbar,
          isShowNavbar: showNavbarFooter,
        },
      })
    );
    navigate(routes.client.breath());
  };

  const navbarItems: INavbarHomeItems[] = [
    {
      title: "Breathing",
      path: routes.client.breath(),
      paths: [routes.client.breath(), routes.client.breathResult()],
      image: "Breath.svg",
      onClick: handleBreath,
    },
    {
      title: "Aura",
      path: routes.client.home(),
      paths: [routes.client.home()],
      image: "Aura.svg",
      active: true,
      onClick: () => null,
    },
    {
      title: "Compatibility",
      path: routes.client.compatibility(),
      paths: [
        routes.client.compatibility(),
        routes.client.compatibilityResult(),
      ],
      image: "Compatibility.svg",
      onClick: handleCompatibility,
    },
    {
      title: "My Moon",
      path: routes.client.wallpaper(),
      paths: [routes.client.wallpaper()],
      image: "moon.svg",
      onClick: () => null,
    },
  ];

  return (
    <div className="container">
      {showHeader ? (
        <Header
          openMenu={() => setIsMenuOpen(true)}
          clickCross={changeIsSpecialOfferOpen}
        />
      ) : null}
      {isRouteFullDataModal && (
        <Modal open={isShowFullDataModal} isCloseButtonVisible={false}>
          <FullDataModal onClose={onCloseFullDataModal} />
        </Modal>
      )}
      <main className="content">
        <Outlet />
      </main>
      {showFooter ? <Footer color={showNavbar ? "black" : "white"} /> : null}
      {showNavbar ? (
        <Navbar isOpen={isMenuOpen} closeMenu={() => setIsMenuOpen(false)} />
      ) : null}
      {showNavbarFooter && hasNavbarFooter(location.pathname) ? (
        <NavbarFooter items={navbarItems} />
      ) : null}
    </div>
  );
}

function AuthorizedUserOutlet(): JSX.Element {
  const status = useSelector(selectors.selectStatus);
  const { user } = useAuth();
  return user && status === "subscribed" ? (
    <Navigate to={routes.client.home()} replace={true} />
  ) : (
    <Outlet />
  );
}

// function PrivateOutlet(): JSX.Element {
//   const { user } = useAuth();
//   return user ? (
//     <Outlet />
//   ) : (
//     <Navigate to={routes.client.root()} replace={true} />
//   );
// }

// function PrivateSubscriptionOutlet(): JSX.Element {
//   // const isProduction = import.meta.env.MODE === "production";
//   const isProduction = false;
//   const status = useSelector(selectors.selectStatus);
//   return status === "subscribed" || !isProduction ? (
//     <Outlet />
//   ) : (
//     <Navigate to={getRouteBy(status)} replace={true} />
//   );
// }

function getIsShowFullDataModal(dataItems: Array<unknown> = []): boolean {
  let hasNoDataItem = false;

  for (const item of dataItems) {
    if (!item) {
      hasNoDataItem = true;
      break;
    }
  }

  return hasNoDataItem;
}

function SkipStep(): JSX.Element {
  const { user } = useAuth();
  return user ? (
    <Navigate to={routes.client.emailEnter()} replace={true} />
  ) : (
    <CreateProfilePage />
  );
}

function MainPage(): JSX.Element {
  const status = useSelector(selectors.selectStatus);
  return <Navigate to={getRouteBy(status)} replace={true} />;
}

export default App;
