"use client"; import React, { useState, useEffect } from "react"; import { motion } from "motion/react"; import { ChevronRight, ChevronLeft, MapPin, CreditCard, Truck, ShieldCheck, Calendar, Wallet, Clock, ArrowRight, CheckCircle2, Heart, PlusCircle } from "lucide-react"; import { toPersian, cn } from "../lib/utils"; import { useCartStore } from "../lib/store/cartStore"; import { usePetStore } from "../lib/store/usePetStore"; import { useUserStore } from "../lib/store/userStore"; import { Product, PRODUCTS } from "../lib/data/products"; import { productService } from "../lib/services/productService"; import { toast } from "sonner"; import { useRouter } from 'next/navigation'; export default function CheckoutPage() { const router = useRouter(); const { items, getTotal, getSubtotal, getDiscount, isSubscribed, charityDonation, setCharityDonation, addOrder, clearCart } = useCartStore(); const { getActivePet, updatePet } = usePetStore(); const { profile, updateProfile } = useUserStore(); const [step, setStep] = useState(1); const [loading, setLoading] = useState(false); const [useRoundUp, setUseRoundUp] = useState(false); const [dbProducts, setDbProducts] = useState([]); const [paymentMethod, setPaymentMethod] = useState('online'); const [selectedAddressId, setSelectedAddressId] = useState(''); const [showNewAddressForm, setShowNewAddressForm] = useState(false); // Custom manual address state if guest or not using stored addresses const [manualName, setManualName] = useState(''); const [manualPhone, setManualPhone] = useState(''); const [manualAddress, setManualAddress] = useState(''); useEffect(() => { productService.getProducts({ limit: 999 }).then(res => setDbProducts(res.data)); // Set default selected address if logged in if (profile.addresses && profile.addresses.length > 0) { const def = profile.addresses.find(a => a.isDefault) || profile.addresses[0]; setSelectedAddressId(def.id); } else if (profile.firstName) { // Pre-fill profile info for manual fields setManualName(`${profile.firstName} ${profile.lastName}`.trim()); setManualPhone(profile.mobile || ''); } }, [profile]); const subtotal = getSubtotal(); const roundedAmount = Math.ceil(subtotal / 10000) * 10000; const roundUpDiff = roundedAmount - subtotal; const handleCharityToggle = () => { if (!useRoundUp) { setCharityDonation(Math.max(roundUpDiff, Math.round(subtotal * 0.01))); setUseRoundUp(true); } else { setCharityDonation(0); setUseRoundUp(false); } }; const handleFinalize = async () => { const totalAmount = getTotal(); if (paymentMethod === 'wallet' && profile.walletBalance < totalAmount) { toast.error("اعتبار کیف پول شما کافی نیست. لطفاً ابتدا آن را شارژ کنید یا روش پرداخت دیگری انتخاب کنید."); return; } setLoading(true); const activePet = getActivePet(); try { // 1. If using wallet, deduct balance and add purchase transaction if (paymentMethod === 'wallet') { const newBalance = profile.walletBalance - totalAmount; const newTransaction = { id: `TR-${Math.floor(Math.random() * 90000) + 10000}`, type: 'purchase' as const, amount: totalAmount, date: new Date().toISOString(), status: 'success' as const }; await updateProfile({ walletBalance: newBalance, transactions: [newTransaction, ...(profile.transactions || [])] }); } // 2. Register the order in the backend const orderId = await addOrder({ items: [...items], total: totalAmount, charityDonation: charityDonation, petId: activePet?.id }); // 3. Update user charity total if (charityDonation > 0) { await updateProfile({ charityDonationTotal: (profile.charityDonationTotal || 0) + charityDonation }); } // 4. Update pet consumptions for the refill logic if (activePet) { const newConsumptions = [...(activePet.consumptions || [])]; items.forEach(item => { const existing = newConsumptions.find(c => c.productId === item.product.id); if (existing) { existing.remaining += item.product.packageSize * item.quantity; existing.packageSize = item.product.packageSize; } else { newConsumptions.push({ productId: item.product.id, packageSize: item.product.packageSize, remaining: item.product.packageSize * item.quantity }); } }); updatePet(activePet.id, { consumptions: newConsumptions }); } clearCart(); toast.success("سفارش شما با موفقیت ثبت شد و به پرونده سلامت همدمتان اضافه شد!"); router.push('/dashboard'); } catch (err: any) { toast.error(err.message || "خطا در ثبت سفارش. لطفاً مجدداً تلاش کنید."); } finally { setLoading(false); } }; if (items.length === 0) { return (

سبد خرید شما خالی است

); } return (
{/* Mobile Navigation & Breadcrumbs */}
router.push('/shop')}>سبد خرید نهایی‌سازی سفارش
{/* Desktop Breadcrumbs (Hidden on Mobile) */}
router.push('/')}>خانه درگاه پرداخت امن و نهایی‌سازی
{/* Main Form */}
{/* Step 1: Shipping */}
۱

اطلاعات ارسال

{profile.addresses && profile.addresses.length > 0 && !showNewAddressForm ? (

انتخاب از بین آدرس‌های ذخیره‌شده شما:

{profile.addresses.map((addr) => (
setSelectedAddressId(addr.id)} className={cn( "p-4 rounded-2xl border-2 cursor-pointer transition-all flex items-start gap-3", selectedAddressId === addr.id ? "border-canina-blue bg-canina-blue/5" : "border-medical-gray-100 hover:border-medical-gray-200" )} > setSelectedAddressId(addr.id)} className="mt-1" />
{addr.title} {addr.isDefault && ( پیش‌فرض )}

{addr.province}، {addr.city}، {addr.detail}

گیرنده: {addr.receptorName} | همراه: {toPersian(addr.phone)}

))}
) : (
{profile.addresses && profile.addresses.length > 0 && ( )}
setManualName(e.target.value)} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-3 sm:py-4 px-4 sm:px-6 text-xs sm:text-sm focus:outline-none focus:ring-2 focus:ring-canina-blue/20" placeholder="مثلاً: پارسا آقایی" />
setManualPhone(e.target.value.replace(/[^0-9]/g, ''))} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-3 sm:py-4 px-4 sm:px-6 text-xs sm:text-sm focus:outline-none focus:ring-2 focus:ring-canina-blue/20" placeholder="۰۹۱۲XXXXXXX" />