import { useState, useEffect, useRef, useLayoutEffect } from "react";
import { Link } from "react-router-dom";
import { getFullApiUrl } from "../utils/apiConfig";
import { motion } from "framer-motion";
import { Heart, Eye, Star, ShoppingBag, ShoppingCart } from "lucide-react";
import "../styles/ProductList.css";
import {
useCreateWishlistItemMutation,
useDeleteWishlistItemsMutation,
useGetWishlistsQuery,
useGetCartsQuery,
useCreateCartSnapshotMutation,
useUpdateCartSnapshotMutation,
} from "../store/slices/userApiSlice";
import {
notifyCartAction,
notifyWishlistAction,
} from "../utils/notificationService";
import { useSelector } from "react-redux";
import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";
export default function ItemSection() {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const {
userInfo,
loading: authLoading,
isLoggedIn,
} = useSelector((state) => state.auth);
const navigate = useNavigate();
const [createWishlistItem] = useCreateWishlistItemMutation();
const [deleteWishlistItems] = useDeleteWishlistItemsMutation();
const {
data: wishlistData,
isLoading: wishlistLoading,
refetch: refetchWishlist,
} = useGetWishlistsQuery(undefined, {
skip: !isLoggedIn,
});
const wishlistProductIds = new Set(
(wishlistData?.wishlist || []).map((p) => p.productId),
);
const { data: cartsData, refetch: refetchCarts } = useGetCartsQuery(
undefined,
{
skip: !isLoggedIn,
},
);
const [createCartSnapshot] = useCreateCartSnapshotMutation();
const [updateCartSnapshot] = useUpdateCartSnapshotMutation();
const cartItems = cartsData?.carts?.[0]?.cartItems || [];
useEffect(() => {
fetch(
`${getFullApiUrl()}/products`,
)
.then((res) => res.json())
.then((data) => {
setProducts(data.products);
setLoading(false);
})
.catch(() => {
setLoading(false);
console.error("Failed to fetch products");
});
}, []);
const groupByCategory = () => {
const grouped = {};
if (!Array.isArray(products)) return grouped;
products.forEach((product) => {
if (!grouped[product.category]) {
grouped[product.category] = [];
}
if (grouped[product.category].length < 4) {
grouped[product.category].push(product);
}
});
return grouped;
};
const groupedProducts = groupByCategory();
const toggleWishlist = async (productId, product) => {
if (authLoading) {
toast.info("Checking login status...");
return;
}
if (!isLoggedIn) {
toast.error("You must be logged in to add to wishlist!", {
autoClose: 2000,
});
setTimeout(() => navigate("/login"), 1500);
return;
}
try {
const isWishlisted = wishlistProductIds.has(productId);
if (!isWishlisted) {
await createWishlistItem({ productId }).unwrap();
notifyWishlistAction("add", product);
} else {
await deleteWishlistItems({ productIds: [productId] }).unwrap();
notifyWishlistAction("remove", product);
}
refetchWishlist();
window.dispatchEvent(new Event("wishlist-updated"));
} catch (error) {
console.error("Error toggling wishlist:", error);
notifyWishlistAction("failed", product);
}
};
const isInCart = (productId) => {
return cartItems.some((item) => item.productId === productId);
};
const getCartItemQty = (productId) => {
const item = cartItems.find((item) => item.productId === productId);
return item ? item.qty : 0;
};
const handleAddToCart = async (product) => {
if (authLoading) {
toast.info("Checking login status...");
return;
}
if (!isLoggedIn) {
toast.error("You must be logged in to add to cart!", { autoClose: 2000 });
setTimeout(() => navigate("/login"), 1500);
return;
}
try {
const existingItem = cartItems.find(
(item) => item.productId === product._id,
);
let updatedCartItems;
if (existingItem) {
updatedCartItems = cartItems.map((item) =>
item.productId === product._id
? { ...item, qty: item.qty + 1 }
: item,
);
await updateCartSnapshot({
createdAt: cartsData?.carts?.[0]?.createdAt,
update: {
cartItems: updatedCartItems,
amount: calculateCartAmount(updatedCartItems),
status: "pending",
},
});
notifyCartAction("update", product);
} else if (!cartsData?.carts || cartsData.carts.length === 0) {
updatedCartItems = [
{
productId: product._id,
name: product.name,
price: product.price,
qty: 1,
category: product.category,
seller: product.seller,
stock: product.stock,
image:
product.images && product.images[0]
? product.images[0].image
: "",
ratings: product.ratings,
},
];
await createCartSnapshot({
cart: {
cartItems: updatedCartItems,
amount: calculateCartAmount(updatedCartItems),
status: "pending",
},
});
notifyCartAction("add", product);
} else {
updatedCartItems = [
...cartItems,
{
productId: product._id,
name: product.name,
price: product.price,
qty: 1,
category: product.category,
seller: product.seller,
stock: product.stock,
image:
product.images && product.images[0]
? product.images[0].image
: "",
ratings: product.ratings,
},
];
await updateCartSnapshot({
createdAt: cartsData?.carts?.[0]?.createdAt,
update: {
cartItems: updatedCartItems,
amount: calculateCartAmount(updatedCartItems),
status: "pending",
},
});
notifyCartAction("add", product);
}
refetchCarts();
window.dispatchEvent(new Event("cart-updated"));
} catch (error) {
console.error("Error adding to cart:", error);
notifyCartAction("failed", product);
}
};
function calculateCartAmount(cartItems) {
return cartItems.reduce((acc, item) => acc + item.price * item.qty, 0);
}
const renderStars = (rating) => {
const stars = [];
const fullStars = Math.floor(rating);
const decimalPart = rating - fullStars;
for (let i = 0; i < 5; i++) {
if (i < fullStars) {
stars.push(