import React, { useState, useMemo } from 'react'; import { View, Alert, Platform } from 'react-native'; import { useRouter } from 'expo-router'; import { tw, MyTextInput, LoadingDialog, MyText, MyTouchableOpacity } from 'common-ui'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import { trpc } from '@/src/trpc-client'; import { useCentralProductStore } from '@/src/store/centralProductStore'; import { useCentralSlotStore } from '@/src/store/centralSlotStore'; import { clearLocalCart } from '@/hooks/cart-query-hooks'; import { useQueryClient } from '@tanstack/react-query'; import { FontAwesome5, FontAwesome6 } from '@expo/vector-icons'; interface PaymentAndOrderProps { selectedAddress: number | null; selectedSlots: Record; selectedCouponId: number | null; cartItems: any[]; totalPrice: number; totalSavings?: number; discountAmount: number; finalTotal: number; finalTotalWithDelivery: number; deliveryCharge: number; constsData?: any; selectedCoupons: any[]; isFlashDelivery?: boolean; onCancel?: () => void; } const PaymentAndOrderComponent: React.FC = ({ selectedAddress, selectedSlots, selectedCouponId, cartItems, totalPrice, totalSavings = 0, discountAmount, finalTotal, finalTotalWithDelivery, deliveryCharge, constsData, selectedCoupons, isFlashDelivery = false, onCancel, }) => { const router = useRouter(); const queryClient = useQueryClient(); const [userNotes, setUserNotes] = useState(''); const [isLoadingDialogOpen, setIsLoadingDialogOpen] = useState(false); const [paymentMethod, setPaymentMethod] = useState<'online' | 'cod'>('cod'); // Helper function to clear cart and invalidate queries const clearCartAndInvalidateQueries = async (cartType: 'regular' | 'flash' = 'regular') => { await clearLocalCart(cartType); queryClient.invalidateQueries({ queryKey: [`local-cart-${cartType}`] }); }; const products = useCentralProductStore((state) => state.products); const productsById = useCentralProductStore((state) => state.productsById); const productSlotsMap = useCentralSlotStore((state) => state.productSlotsMap); // Memoized flash-eligible product IDs const flashEligibleProductIds = useMemo(() => { if (!products.length) return new Set(); return new Set( products .filter((product) => productSlotsMap[product.id]?.isFlashAvailable) .map((product) => product.id) ); }, [products, productSlotsMap]); const placeOrderMutation = trpc.user.order.placeOrder.useMutation({ onSuccess: (data) => { const orders = data.data; // Now an array of orders const firstOrder = orders[0]; // Use first order for payment flow if (!firstOrder.isCod) { // createRazorpayOrderMutation.mutate({ orderId: firstOrder.id.toString() }); } else { // Clear cart and navigate to success page clearCartAndInvalidateQueries(isFlashDelivery ? 'flash' : 'regular'); const successPath = isFlashDelivery ? '/(drawer)/(tabs)/flash-delivery/order-success' : './order-success'; router.replace(`${successPath}?orderId=${firstOrder.id}&totalAmount=${finalTotalWithDelivery}`); } }, onError: (error: any) => { Alert.alert('Error', error.message || 'Failed to place order'); }, onSettled: () => { setIsLoadingDialogOpen(false); }, }); const verifyPaymentMutation = trpc.user.payment.verifyPayment.useMutation({ onSuccess: () => { const orders = placeOrderMutation.data?.data || []; const firstOrder = orders[0]; // Clear cart and navigate to success page clearCartAndInvalidateQueries(isFlashDelivery ? 'flash' : 'regular'); const successPath = isFlashDelivery ? '/(drawer)/(tabs)/flash-delivery/order-success' : './order-success'; router.replace(`${successPath}?orderId=${firstOrder?.id}&totalAmount=${finalTotalWithDelivery}`); }, onError: (error: any) => { Alert.alert('Error', error.message || 'Payment verification failed'); }, }); const markPaymentFailedMutation = trpc.user.payment.markPaymentFailed.useMutation(); const handlePlaceOrder = () => { if (!selectedAddress) { Alert.alert('Error', 'Please select an address'); return; } const availableItems = cartItems .filter(item => { if (productSlotsMap[item.skuId]?.isOutOfStock) return false; // For flash delivery, check if product supports flash delivery if (isFlashDelivery) { return flashEligibleProductIds.has(item.skuId); } // For regular delivery, only include items with assigned slots return selectedSlots[item.id]; }) .map(item => item.id); if (availableItems.length === 0) { Alert.alert('Error', 'No valid items to order'); return; } setIsLoadingDialogOpen(true); const orderData = { selectedItems: availableItems.map(itemId => { const item = cartItems.find(cartItem => cartItem.id === itemId); return { skuId: item.skuId, quantity: item.quantity, slotId: isFlashDelivery ? null : selectedSlots[itemId] }; }), addressId: selectedAddress, paymentMethod: paymentMethod, couponId: selectedCouponId || undefined, userNotes: userNotes, isFlashDelivery: isFlashDelivery, }; placeOrderMutation.mutate(orderData); }; return ( <> {/* Back Button */} {onCancel && ( Back to Cart )} {/* Special Instructions */} Delivery Instructions {/* Payment Method */} Payment Method {/* No selection dot for disabled state */} Pay Online (Coming Soon) UPI, Cards, Netbanking setPaymentMethod('cod')} style={tw`flex-row items-center p-4 rounded-xl border ${paymentMethod === 'cod' ? 'border-brand500 bg-blue-50' : 'border-gray-200'}`} > {paymentMethod === 'cod' && } Cash on Delivery Pay when you receive UPI accepted during COD Cash payment {/* Bill Details */} Bill Details {/* Item Total */} Item Total ₹{Math.trunc(totalPrice)} {/* Total Savings */} {totalSavings > 1 && ( Total Savings ₹{Math.trunc(totalSavings)} )} {/* Discount */} {discountAmount > 0 && ( Product Discount -₹{Math.trunc(discountAmount)} )} {/* Delivery Fee */} Delivery Fee {deliveryCharge === 0 && ( isFlashDelivery ? (constsData?.flashDeliveryCharge > 0 && ( ₹{constsData?.flashDeliveryCharge} )) : (constsData?.deliveryCharge > 0 && ( ₹{constsData?.deliveryCharge} )) )} {deliveryCharge === 0 ? 'Free' : `₹${deliveryCharge}`} {/* Free Delivery Nudge */} {deliveryCharge > 0 && (() => { const threshold = isFlashDelivery ? constsData?.flashFreeDeliveryThreshold : constsData?.freeDeliveryThreshold; return threshold > 0 && finalTotal < threshold && ( Add products worth ₹{(threshold - finalTotal).toFixed(0)} for free delivery ); })()} {/* Divider */} {/* Grand Total */} To Pay ₹{finalTotalWithDelivery} {/* Savings Banner */} {(discountAmount > 0 || deliveryCharge === 0 || totalSavings > 1) && ( You saved ₹{Math.trunc(discountAmount + totalSavings + (deliveryCharge === 0 ? ( isFlashDelivery ? constsData?.flashDeliveryCharge : constsData?.deliveryCharge ) : 0))} on this order )} {/* Bottom Action Bar */} {!selectedAddress && ( Please select a delivery address to place order )} Place Order ); }; export default PaymentAndOrderComponent;