import { useState, useEffect, useMemo, useRef } from "react";
import {
  useGetCategoryProductsQuery,
  useLazyGetAllCategoryProductsPaginatedQuery,
} from "../../../app/api/categories";
import { useLazyGetBrandProductsQuery } from "../../../app/api/brandsApi";
import { useLazyGetCollectionProductsPaginatedQuery } from "../../../app/api/collectionsApi";

const useCategoryProducts = ({
  categoryId,
  collectionId,
  brandId,
  selectedCategory,
  isSubCategory,
  currentPage,
  selectedFilterCategory,
  selectedFilterBrand,
  minPrice,
  maxPrice,
  searchQuery,
}) => {
  const [products, setProducts] = useState([]);
  const [hasMore, setHasMore] = useState(true);

  const isFetchingRef = useRef(false);
  const lastFetchKeyRef = useRef(null);
  const abortControllerRef = useRef(null);

  const contextId = useMemo(() => {
    const parts = [
      selectedFilterCategory && `fcat-${selectedFilterCategory}`,
      categoryId && `cat-${categoryId}`,
      brandId && `brand-${brandId}`,
      collectionId && `col-${collectionId}`,
      selectedFilterBrand && `fbrand-${selectedFilterBrand}`,
      minPrice && `min-${minPrice}`,
      maxPrice && `max-${maxPrice}`,
    ].filter(Boolean);
    return parts.join("|") || "none";
  }, [
    selectedFilterCategory,
    categoryId,
    brandId,
    collectionId,
    selectedFilterBrand,
    minPrice,
    maxPrice,
  ]);

  const fetchParams = useMemo(
    () => ({
      page: currentPage,
      limit: 6,
      brands: selectedFilterBrand || undefined,
      min_price: minPrice || undefined,
      max_price: maxPrice || undefined,
    }),
    [currentPage, selectedFilterBrand, minPrice, maxPrice],
  );

  const fetchKey = `${contextId}-p${currentPage}`;

  const shouldUseBaseQuery =
    categoryId &&
    !isSubCategory &&
    !searchQuery &&
    !selectedFilterCategory &&
    !selectedFilterBrand &&
    !brandId &&
    !collectionId;

  const {
    data: paginatedCategoryProducts,
    isLoading: categoryLoading,
    isFetching: categoryFetching,
  } = useGetCategoryProductsQuery(
    {
      categoryId: categoryId,
      page: currentPage,
      min_price: minPrice || undefined,
      max_price: maxPrice || undefined,
    },
    {
      skip: !shouldUseBaseQuery,
    },
  );

  const [
    fetchCategoryPaginated,
    {
      data: lazyCategoryProducts,
      isLoading: lazyCategoryLoading,
      isFetching: lazyCategoryFetching,
      reset: resetCategoryPaginated,
    },
  ] = useLazyGetAllCategoryProductsPaginatedQuery();

  const [
    fetchBrandPaginated,
    {
      data: paginatedBrandProducts,
      isLoading: brandPaginatedLoading,
      isFetching: brandFetching,
      reset: resetBrandPaginated,
    },
  ] = useLazyGetBrandProductsQuery();

  const [
    fetchCollectionPaginated,
    {
      data: paginatedCollectionProducts,
      isLoading: collectionPaginatedLoading,
      isFetching: collectionFetching,
      reset: resetCollectionPaginated,
    },
  ] = useLazyGetCollectionProductsPaginatedQuery();

  useEffect(() => {
    setProducts([]);
    setHasMore(true);

    resetCategoryPaginated?.();
    resetBrandPaginated?.();
    resetCollectionPaginated?.();

    lastFetchKeyRef.current = null;
    isFetchingRef.current = false;

    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
  }, [
    contextId,
    resetCategoryPaginated,
    resetBrandPaginated,
    resetCollectionPaginated,
  ]);

  useEffect(() => {
    if (searchQuery) return;

    if (lastFetchKeyRef.current === fetchKey) {
      return;
    }

    if (isFetchingRef.current) {
      return;
    }

    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    abortControllerRef.current = new AbortController();
    isFetchingRef.current = true;
    lastFetchKeyRef.current = fetchKey;

    const executeFetch = async () => {
      try {
        if (selectedFilterBrand) {
          await fetchBrandPaginated({
            id: selectedFilterBrand,
            ...fetchParams,
          });
          return;
        }

        if (selectedFilterCategory) {
          await fetchCategoryPaginated({
            category: {
              id: selectedFilterCategory,
              children: [],
            },
            ...fetchParams,
          });
          return;
        }

        if (categoryId && isSubCategory) {
          await fetchCategoryPaginated({
            category: {
              id: parseInt(categoryId),
              children: [],
            },
            ...fetchParams,
          });
          return;
        }

        if (brandId) {
          await fetchBrandPaginated({
            id: brandId,
            ...fetchParams,
          });
          return;
        }

        if (collectionId) {
          await fetchCollectionPaginated({
            collectionId,
            ...fetchParams,
          });
          return;
        }
      } catch (error) {
        if (error.name !== "AbortError") {
          console.error("Fetch error:", error);
        }
      } finally {
        isFetchingRef.current = false;
      }
    };

    executeFetch();

    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [
    fetchKey,
    searchQuery,
    selectedFilterBrand,
    selectedFilterCategory,
    categoryId,
    isSubCategory,
    brandId,
    collectionId,
    fetchParams,
    fetchCategoryPaginated,
    fetchBrandPaginated,
    fetchCollectionPaginated,
  ]);

  useEffect(() => {
    const updateProducts = (newData, hasNextPage) => {
      if (!newData || newData.length === 0) {
        if (currentPage === 1) {
          setProducts([]);
          setHasMore(false);
        }
        return;
      }

      setProducts((prev) => {
        if (currentPage === 1) {
          return newData;
        }

        const existingIds = new Set(prev.map((p) => p.id));
        const newProducts = newData.filter((p) => !existingIds.has(p.id));

        return newProducts.length > 0 ? [...prev, ...newProducts] : prev;
      });

      setHasMore(hasNextPage);
    };

    if (paginatedCategoryProducts && shouldUseBaseQuery) {
      updateProducts(
        paginatedCategoryProducts.data || [],
        !!paginatedCategoryProducts.pagination?.next_page_url,
      );
      return;
    }

    if (lazyCategoryProducts) {
      updateProducts(
        lazyCategoryProducts.data || [],
        lazyCategoryProducts.pagination?.hasMorePages || false,
      );
      return;
    }

    // Brand products
    if (paginatedBrandProducts) {
      updateProducts(
        paginatedBrandProducts.data || [],
        !!paginatedBrandProducts.pagination?.next_page_url,
      );
      return;
    }

    if (paginatedCollectionProducts) {
      updateProducts(
        paginatedCollectionProducts.data || [],
        !!paginatedCollectionProducts.pagination?.next_page_url,
      );
    }
  }, [
    paginatedCategoryProducts,
    lazyCategoryProducts,
    paginatedBrandProducts,
    paginatedCollectionProducts,
    currentPage,
    shouldUseBaseQuery,
  ]);

  const isLoading =
    categoryLoading ||
    lazyCategoryLoading ||
    brandPaginatedLoading ||
    collectionPaginatedLoading ||
    categoryFetching ||
    lazyCategoryFetching ||
    brandFetching ||
    collectionFetching;

  return {
    products,
    hasMore,
    isLoading,
    setProducts,
    setHasMore,
  };
};

export default useCategoryProducts;
