'use client' import { useState, useEffect, useCallback } from 'react' import { useSession } from 'next-auth/react' import { useRouter } from 'next/navigation' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Separator } from '@/components/ui/separator' import { Badge } from '@/components/ui/badge' import { ArrowLeft, CreditCard, Truck, Plus, MapPin } from 'lucide-react' import { cartManager } from '@/lib/cart' import { toast } from 'sonner' import Link from 'next/link' import Image from 'next/image' interface CartItem { id: string name: string price: number quantity: number image: string | null } interface Address { id: string firstName: string lastName: string company?: string address1: string address2?: string city: string state: string zipCode: string country: string phone?: string isDefault: boolean type: 'HOME' | 'WORK' | 'OTHER' } declare global { interface Window { Razorpay: any; } } export default function CheckoutPage() { const router = useRouter() const { data: session, status } = useSession() const [cart, setCart] = useState([]) const [addresses, setAddresses] = useState([]) const [selectedAddressId, setSelectedAddressId] = useState('') const [loading, setLoading] = useState(false) const [useNewAddress, setUseNewAddress] = useState(false) const [formData, setFormData] = useState({ email: '', firstName: '', lastName: '', address: '', city: '', state: '', zipCode: '', phone: '' }) const [saveAddress, setSaveAddress] = useState(false) const [processingPayment, setProcessingPayment] = useState(false) const loadCart = useCallback(() => { const cartItems = cartManager.getCart() setCart(cartItems || []) if (cartItems.length === 0) { router.push('/products') } }, [router]) const fetchAddresses = useCallback(async () => { if (status !== 'authenticated') return try { const response = await fetch('/api/user/addresses') if (response.ok) { const data = await response.json() const userAddresses = data.addresses || [] setAddresses(userAddresses) // Auto-select default address const defaultAddress = userAddresses.find((addr: Address) => addr.isDefault) if (defaultAddress) { setSelectedAddressId(defaultAddress.id) } else if (userAddresses.length > 0) { setSelectedAddressId(userAddresses[0].id) } else { setUseNewAddress(true) } } } catch (error) { console.error('Error fetching addresses:', error) setUseNewAddress(true) } }, [status]) const fetchUserProfile = useCallback(async () => { if (status !== 'authenticated') return try { const response = await fetch('/api/user/profile') if (response.ok) { const userData = await response.json() // Prefill form with user data setFormData(prev => ({ ...prev, email: userData.email || session?.user?.email || '', firstName: userData.name?.split(' ')[0] || session?.user?.name?.split(' ')[0] || '', lastName: userData.name?.split(' ').slice(1).join(' ') || session?.user?.name?.split(' ').slice(1).join(' ') || '', phone: userData.phone || '' })) } } catch (error) { console.error('Error fetching user profile:', error) // Fallback to session data if (session?.user) { setFormData(prev => ({ ...prev, email: session.user.email || '', firstName: session.user.name?.split(' ')[0] || '', lastName: session.user.name?.split(' ').slice(1).join(' ') || '' })) } } }, [status, session?.user]) useEffect(() => { loadCart() }, [loadCart]) useEffect(() => { if (status === 'authenticated') { fetchAddresses() fetchUserProfile() } else if (status === 'unauthenticated') { // For guest checkout, keep form empty setUseNewAddress(true) } }, [status, fetchAddresses, fetchUserProfile]) const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target setFormData(prev => ({ ...prev, [name]: value })) } const getSubtotal = () => { return cart.reduce((sum, item) => sum + (item.price * item.quantity), 0) } const getTotal = () => { return getSubtotal() // Add tax, shipping, etc. here if needed } const getSelectedAddress = () => { return addresses.find(addr => addr.id === selectedAddressId) } const handlePlaceOrder = async () => { // Get shipping address data let shippingAddress let savedAddressId = null if (useNewAddress) { // Validate new address form const requiredFields = ['email', 'firstName', 'lastName', 'address', 'city', 'state', 'zipCode', 'phone'] const missingFields = requiredFields.filter(field => !formData[field as keyof typeof formData]) if (missingFields.length > 0) { toast.error('Please fill in all required fields') return } shippingAddress = formData // Save address if user is authenticated and opted to save if (status === 'authenticated' && saveAddress) { try { const addressData = { firstName: formData.firstName, lastName: formData.lastName, address1: formData.address, city: formData.city, state: formData.state, zipCode: formData.zipCode, phone: formData.phone, isDefault: addresses.length === 0, // Set as default if it's the first address type: 'HOME' } const response = await fetch('/api/user/addresses', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(addressData) }) if (response.ok) { const newAddress = await response.json() savedAddressId = newAddress.address.id toast.success('Address saved for future use!') } } catch (error) { console.error('Error saving address:', error) // Don't fail the order if address saving fails } } } else { const selectedAddr = getSelectedAddress() if (!selectedAddr) { toast.error('Please select a shipping address') return } // Check if email is provided if (!formData.email) { toast.error('Please provide your email address') return } shippingAddress = { email: formData.email, firstName: selectedAddr.firstName, lastName: selectedAddr.lastName, address: `${selectedAddr.address1}${selectedAddr.address2 ? ', ' + selectedAddr.address2 : ''}`, city: selectedAddr.city, state: selectedAddr.state, zipCode: selectedAddr.zipCode, phone: selectedAddr.phone || formData.phone || '' } savedAddressId = selectedAddressId } setLoading(true) try { const orderData = { items: cart.map(item => ({ productId: item.id, quantity: item.quantity, price: item.price })), total: getTotal(), shippingAddress, shippingAddressId: savedAddressId } const response = await fetch('/api/orders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }) if (!response.ok) { const errorData = await response.json() if (response.status === 401) { toast.error('Please sign in to place an order') router.push('/auth/signin?callbackUrl=/checkout') return } throw new Error(errorData.error || 'Failed to create order') } const order = await response.json() // Initialize Razorpay payment await initializePayment(order) } catch (error) { console.error('Error placing order:', error) toast.error('Failed to place order. Please try again.') } finally { setLoading(false) } } const initializePayment = async (order: any) => { setProcessingPayment(true) // Add debugging logs console.log('Order data received:', order) console.log('Razorpay Key ID:', order.razorpayKeyId) console.log('Razorpay Order ID:', order.razorpayOrderId) console.log('Total amount:', order.total) console.log('Environment:', order.isProduction ? 'Production' : 'Test') // Check if Razorpay is loaded if (!window.Razorpay) { toast.error('Payment gateway not loaded. Please refresh the page.') setProcessingPayment(false) return } // Validate required data if (!order.razorpayKeyId) { toast.error('Payment configuration error. Please try again.') setProcessingPayment(false) return } // Show environment warning for test mode if (!order.isProduction) { toast.info('Running in test mode - No actual payment will be charged') } const options = { key: order.razorpayKeyId, amount: Math.round(order.total * 100), // Convert to paise currency: 'INR', name: 'Padmaaja Rasooi', description: `Order Payment ${order.isProduction ? '' : '(Test Mode)'}`, order_id: order.razorpayOrderId, handler: async function (response: any) { try { console.log('Payment response:', response) const verifyResponse = await fetch('/api/orders/verify-payment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ razorpay_order_id: response.razorpay_order_id, razorpay_payment_id: response.razorpay_payment_id, razorpay_signature: response.razorpay_signature, orderId: order.id }) }) if (verifyResponse.ok) { cartManager.clearCart() toast.success('Payment successful! Order confirmed.') router.push(`/order-confirmation?orderId=${order.id}`) } else { const errorData = await verifyResponse.json() console.error('Verification failed:', errorData) toast.error('Payment verification failed') } } catch (error) { console.error('Payment verification error:', error) toast.error('Payment verification failed') } finally { setProcessingPayment(false) } }, prefill: { name: formData.firstName + ' ' + formData.lastName, email: formData.email, contact: formData.phone }, modal: { ondismiss: function() { setProcessingPayment(false) toast.error('Payment cancelled') } }, theme: { color: order.isProduction ? '#10B981' : '#F59E0B' // Green for production, amber for test } } console.log('Razorpay options:', options) try { const rzp = new window.Razorpay(options) rzp.open() } catch (error) { console.error('Error opening Razorpay:', error) toast.error('Failed to open payment gateway') setProcessingPayment(false) } } // Load Razorpay script useEffect(() => { const script = document.createElement('script') script.src = 'https://checkout.razorpay.com/v1/checkout.js' script.async = true script.onload = () => { console.log('Razorpay script loaded successfully') } script.onerror = () => { console.error('Failed to load Razorpay script') toast.error('Failed to load payment gateway') } document.body.appendChild(script) return () => { if (document.body.contains(script)) { document.body.removeChild(script) } } }, []) if (cart.length === 0) { return (

Your cart is empty

) } return (

Checkout

{status === 'unauthenticated' && (

Sign in for a faster checkout experience

)}
{/* Checkout Form */}
{/* Contact Information */} Contact Information {status === 'authenticated' && ( Welcome back, {session?.user?.name || session?.user?.email}! )}
{status === 'authenticated' && session?.user?.email && (

Using your account email

)}
{/* Shipping Address */} Shipping Address {status === 'authenticated' && addresses.length > 0 && (
{!useNewAddress && (
{addresses.map((address) => (
setSelectedAddressId(address.id)} >
{address.firstName} {address.lastName} {address.isDefault && ( Default )} {address.type}
{address.company &&
{address.company}
}
{address.address1}
{address.address2 &&
{address.address2}
}
{address.city}, {address.state} {address.zipCode}
{address.phone &&
{address.phone}
}
setSelectedAddressId(address.id)} className="mt-1" />
))}
)}
)} {(useNewAddress || addresses.length === 0 || status === 'unauthenticated') && (
{status === 'unauthenticated' && (

💡 Sign in to use saved addresses and speed up checkout

)}
{/* Save Address Option for Authenticated Users */} {status === 'authenticated' && (
setSaveAddress(e.target.checked)} className="rounded" />
)}
)}
{/* Payment Method */} Payment Method

Payment will be processed securely via Razorpay

{process.env.NODE_ENV === 'development' && (

🧪 Development Mode: Using Razorpay test environment - No real payments will be processed

)}
{/* Order Summary */}
Order Summary {cart.map((item) => (
{item.name}

{item.name}

Quantity: {item.quantity}

₹{(item.price * item.quantity).toFixed(2)}

))}
Subtotal ₹{getSubtotal().toFixed(2)}
Shipping Free
Total ₹{getTotal().toFixed(2)}
) }