"use client";

import { usePathname } from "next/navigation";
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from "react";

import CartDrawerComponent from "../components/CartDrawerComponent";
import { Footer } from "../components/Footer";
import { Header } from "../components/Header";
import { InactiveCartDialog } from "../components/InactiveCartDialog";
import { SessionDialogComponent } from "../components/SessionDialogComponent";
import Sidebar from "../components/Sidebar";
import { CART_STATUS } from "../constants/app";
import { FeatureCodes } from "../constants/feature-flags";
import { ROUTES } from "../constants/routes";
import { useAddressForm } from "../hooks/useAddressForm";
import { useCart } from "../hooks/useCart";
import { useCountries } from "../hooks/useCountries";
import useCustomRouter from "../hooks/useCustomRouter";
import useDebounce from "../hooks/useDebounce";
import useOnlineUser from "../hooks/useOnlineUser";
import { useShippingAddressForm } from "../hooks/useShippingAddressForm";
import useUserActivity from "../hooks/useUserActivity";
import { useCartStore } from "../stores/cartStore";
import { useLoadingStore } from "../stores/loadingStore";
import { useUserStore } from "../stores/userStore";
import { IFeatureFlags } from "../types/feature-flags";
import { deleteToken, getTokenExpiredTime } from "../utils/user-session.util";
// import { PhoneShippingDialog } from '../components/PhoneShippingDialog';

const MainWrapperContext = createContext<any>({});

export type MainWrapperProps = {
  children: React.ReactNode;
  featureFlags: { [key: string]: IFeatureFlags };
  handleRefreshToken: () => Promise<any>;
  eligibleForPayableClaim?: boolean | null;
};

export function MainWrapper({
  children,
  featureFlags,
  handleRefreshToken,
  eligibleForPayableClaim,
}: MainWrapperProps) {
  //
  let tokenTimeInterval: NodeJS.Timeout | undefined = undefined;
  const isRefreshingRef = useRef(false); // Guard against concurrent refresh attempts
  const [isSidebarOpen, setIsSidebarOpen] = useState(false);
  const [isCartDrawerOpen, setIsCartDrawerOpen] = useState(false);
  const [isPageEnabled, setIsPageEnabled] = useState<boolean>(false);
  const { onlineUser } = useOnlineUser();
  const { user, setUser } = useUserStore();
  const {} = useCart();
  const {} = useCountries();
  const {} = useAddressForm();
  const {} = useShippingAddressForm();
  const { cart, cartQty, loading: isCartLoading } = useCartStore();
  const { isUserActiveOnBrowser } = useUserActivity();
  const [isSessionExpired, setIsSessionExpired] = useState<boolean>(false);
  const { setLoading: setAppLoading } = useLoadingStore();
  const pathname = usePathname();
  const { push } = useCustomRouter();
  const [openInvalidDialog, setOpenInvalidDialog] = useState(false);

  useEffect(() => {
    setIsPageEnabled(true);
  }, [pathname, featureFlags, push, setIsPageEnabled]);

  const validateSessionTokenExpiry = useDebounce(async () => {
    if (isSessionExpired) return;
    tokenTimeInterval && clearInterval(tokenTimeInterval);

    const expiryTime = await getTokenExpiredTime(); // get the remaining token time from server

    // Guard: If no valid expiry time, don't start the interval loop
    if (!expiryTime || expiryTime <= 0) {
      console.warn("No valid token expiry time, skipping session check");
      return;
    }

    const now = Date.now() / 1000;
    // Guard: If token is already expired, handle it once instead of looping
    if (expiryTime - now <= 0) {
      setIsSessionExpired(true);
      await proceedLogout(false);
      return;
    }

    tokenTimeInterval = setInterval(async () => {
      const currentTime = Date.now() / 1000;
      const remainingSeconds = expiryTime - currentTime;

      if (remainingSeconds <= 30) {
        clearInterval(tokenTimeInterval);
        tokenTimeInterval = undefined;

        try {
          const isRefreshed = await proceedRefreshToken();

          if (isRefreshed) {
            validateSessionTokenExpiry();
            return;
          }
        } catch (error) {
          console.error("Token refresh failed:", error);
        }

        setIsSessionExpired(true);
        await proceedLogout(false); //disconnect if the token is already expired
        return;
      }
    }, 1000);
  }, 1000);

  // const [, setStartSessionCheck] = useState(validateSessionTokenExpiry);

  const toggleSidebar = useCallback(() => {
    setIsSidebarOpen((prevState) => !prevState);
  }, [setIsSidebarOpen]);

  const closeSidebar = useCallback(() => {
    setIsSidebarOpen(false);
  }, [setIsSidebarOpen]);

  // Toggle cart drawer functions
  const openCartDrawer = useCallback(() => {
    if (cart.cartState === CART_STATUS.shopping) {
      setIsCartDrawerOpen(true);
    } else if (cart.cartState === CART_STATUS.checkout) {
      push(ROUTES.dashboard.checkout);
    } else if (cart.cartState === CART_STATUS.payment) {
      push(ROUTES.dashboard.payment);
    }

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cart]);

  const closeCartDrawer = useCallback(() => setIsCartDrawerOpen(false), []);

  const proceedLogout = useCallback(async (autoRedirect: boolean = true) => {
    if (autoRedirect) await deleteToken();
    window.sessionStorage.clear();
    if (autoRedirect) window.open(ROUTES.auth.login, "_self");
  }, []);

  useLayoutEffect(() => {
    if (onlineUser) {
      setUser(onlineUser);
    }
  }, [onlineUser, setUser]);

  useEffect(() => {
    return () => {
      setTimeout(() => {
        setAppLoading(false);
      }, 2000);
    };
  }, [pathname, setAppLoading]);

  useEffect(() => {
    if (isSidebarOpen || isCartDrawerOpen) {
      document.body.classList.add("no-scroll");
    } else {
      document.body.classList.remove("no-scroll");
    }

    // Cleanup when the component unmounts
    return () => {
      document.body.classList.remove("no-scroll");
    };
  }, [isSidebarOpen, isCartDrawerOpen]);

  const proceedRefreshToken = useCallback(async () => {
    if (!isUserActiveOnBrowser) return false;
    if (isRefreshingRef.current) return false; // Prevent concurrent refresh attempts

    isRefreshingRef.current = true;
    try {
      const refreshedUser = await handleRefreshToken();
      if (refreshedUser) {
        setUser(refreshedUser);
        return true;
      }
      return false;
    } catch (error) {
      console.error("Token refresh error:", error);
      return false;
    } finally {
      isRefreshingRef.current = false;
    }
  }, [isUserActiveOnBrowser, setUser, handleRefreshToken]);

  useEffect(() => {
    validateSessionTokenExpiry();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const triggerInvalidDialog = useCallback(() => {
    setOpenInvalidDialog(true);
  }, []);

  useEffect(() => {
    if (pathname.startsWith("/aleta") && featureFlags) {
      if (
        !featureFlags?.[FeatureCodes.ALETA_PAYMENT] ||
        featureFlags?.[FeatureCodes.ALETA_PAYMENT].isActive !== true
      ) {
        push(ROUTES.dashboard.products);
      }
    }
  }, [pathname, featureFlags, push]);

  const MainData: MainWrapperContextDto = {
    proceedLogout,
    isSessionExpired,
    featureFlags,
    triggerInvalidDialog,
    eligibleForPayableClaim,
  };

  return (
    <MainWrapperContext.Provider value={MainData}>
      <InactiveCartDialog
        open={openInvalidDialog}
        handleOpen={setOpenInvalidDialog}
      />

      <div className={`flex min-h-screen bg-offWhite`}>
        <div
          className={`sidebar
                        bg-white border-r-slate-50
                        mobileSidebar ${isSidebarOpen ? "open" : ""}
                        `}
        >
          <Sidebar
            handleLogout={() => proceedLogout(true)}
            bidNumber={user?.bid}
            onClose={closeSidebar}
            cartProductsCount={cartQty}
          />
        </div>
        <div className="flex-1 overflow-hidden flex flex-col w-auto">
          <Header
            user={user}
            logout={() => proceedLogout(true)}
            onMenuClick={toggleSidebar}
            openCartDrawer={openCartDrawer}
            cartProductsCount={cartQty}
          />
          <div className="grow container mx-auto p-2 md:p-3 pb-44 md:pb-32 lg:pb-32">
            {isPageEnabled && children}
          </div>
          <Footer />
          <CartDrawerComponent
            open={isCartDrawerOpen}
            closeDrawer={closeCartDrawer}
            cartData={cart}
            isCartLoading={isCartLoading}
          />
          {/* <PhoneShippingDialog /> */}
        </div>
      </div>

      <SessionDialogComponent
        isExpired={isSessionExpired}
        callBackFn={() => proceedLogout()}
      />
    </MainWrapperContext.Provider>
  );
}

export const useMainContext = (): MainWrapperContextDto =>
  useContext(MainWrapperContext);

export type MainWrapperContextDto = {
  proceedLogout: (autoRedirect?: boolean) => void;
  isSessionExpired: boolean;
  featureFlags: { [key: string]: IFeatureFlags };
  triggerInvalidDialog: () => void;
  eligibleForPayableClaim: boolean;
};
