"use client";

import { useGetFoods } from "@/app/[name]/(Main)/hooks/useMenuData";
import { useGetProfile } from "@/app/[name]/(Profile)/profile/hooks/userProfileData";
import { hasAuthToken } from "@/lib/api/func";
import { useReceiptStore } from "@/zustand/receiptStore";
import { useEffect, useMemo, useState } from "react";
import {
  cartItemsToFoods,
  guestCartItemsToFoods,
  hasCartEntries,
} from "../lib/cartUtils";
import { useBulkCart, useGetCartItems } from "./useCartData";

function useReceiptHydrated() {
  const [hydrated, setHydrated] = useState(() =>
    useReceiptStore.persist.hasHydrated()
  );

  useEffect(() => {
    const unsub = useReceiptStore.persist.onFinishHydration(() =>
      setHydrated(true)
    );
    setHydrated(useReceiptStore.persist.hasHydrated());
    return unsub;
  }, []);

  return hydrated;
}

export function useCartPageState() {
  const {
    isSuccess,
    isPending: profilePending,
    isFetched: profileFetched,
  } = useGetProfile();
  const localItems = useReceiptStore((state) => state.items);
  const clearLocalCart = useReceiptStore((state) => state.clear);
  const receiptHydrated = useReceiptHydrated();
  const [offlineSyncState, setOfflineSyncState] = useState<
    "idle" | "syncing" | "done"
  >("idle");

  const {
    data: cartData,
    isPending: cartPending,
    isFetching: cartFetching,
    isFetched: cartFetched,
  } = useGetCartItems(isSuccess);
  const { mutate: mutateBulkCart, isPending: bulkSyncPending } = useBulkCart();
  const { data: foodsResponse, isPending: foodsPending } = useGetFoods();

  const foods = foodsResponse?.data ?? [];
  const apiItems = cartData?.data?.items ?? [];
  const apiTotalItems = cartData?.data?.totalItems ?? 0;
  const apiHasItems =
    apiTotalItems > 0 || apiItems.some((item) => item.quantity > 0);
  const localHasItems = hasCartEntries(localItems);

  useEffect(() => {
    if (
      !isSuccess ||
      !cartFetched ||
      apiHasItems ||
      !localHasItems ||
      offlineSyncState !== "idle" ||
      bulkSyncPending
    ) {
      return;
    }

    const bulkItems = Object.entries(localItems)
      .filter(([, detail]) => detail?.quantity && detail.quantity > 0)
      .map(([foodId, detail]) => ({
        foodId: String(foodId),
        quantity: detail.quantity,
      }));

    if (bulkItems.length === 0) {
      return;
    }

    setOfflineSyncState("syncing");
    mutateBulkCart(
      { items: bulkItems },
      {
        onSuccess: () => clearLocalCart(),
        onSettled: () => setOfflineSyncState("done"),
      }
    );
  }, [
    isSuccess,
    cartFetched,
    apiHasItems,
    localHasItems,
    localItems,
    bulkSyncPending,
    offlineSyncState,
    mutateBulkCart,
    clearLocalCart,
  ]);

  const cartFoods = useMemo(() => {
    if (isSuccess) {
      return cartItemsToFoods(apiItems, foods);
    }
    return guestCartItemsToFoods(localItems, foods);
  }, [isSuccess, apiItems, localItems, foods]);

  const isAuthResolving =
    hasAuthToken() && (!profileFetched || profilePending);
  const isCartResolving = isSuccess && (!cartFetched || cartPending);
  const isCartRefetchingEmpty =
    isSuccess && cartFetched && cartFetching && !apiHasItems;
  const needsOfflineSync =
    isSuccess && cartFetched && localHasItems && !apiHasItems;
  const isOfflineSyncing = needsOfflineSync && offlineSyncState !== "done";
  const isGuestHydrating = !hasAuthToken() && !receiptHydrated;
  const guestAwaitingMenu =
    !isSuccess &&
    localHasItems &&
    cartFoods.length === 0 &&
    (foodsPending || foods.length === 0);

  const isLoading =
    isAuthResolving ||
    isCartResolving ||
    isCartRefetchingEmpty ||
    isOfflineSyncing ||
    isGuestHydrating ||
    guestAwaitingMenu;

  const hasItems = isSuccess ? apiHasItems : localHasItems;
  const isCartEmpty = !isLoading && !hasItems;

  return {
    isLoading,
    isCartEmpty,
    hasItems,
    cartFoods,
  };
}
