import React, { useState, useEffect } from 'react'; import { useParams, useNavigate, Link } from 'react-router-dom'; import { CheckCircle, AlertCircle, CreditCard, ArrowLeft, } from 'lucide-react'; import { toast } from 'react-toastify'; import { getBookingById, type Booking } from '../../services/api/bookingService'; import { getPaymentsByBookingId, type Payment, } from '../../services/api/paymentService'; import Loading from '../../components/common/Loading'; import { useFormatCurrency } from '../../hooks/useFormatCurrency'; import { parseDateLocal } from '../../utils/format'; import StripePaymentWrapper from '../../components/payments/StripePaymentWrapper'; const FullPaymentPage: React.FC = () => { const { bookingId } = useParams<{ bookingId: string }>(); const navigate = useNavigate(); const { formatCurrency } = useFormatCurrency(); const [booking, setBooking] = useState(null); const [stripePayment, setStripePayment] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [paymentSuccess, setPaymentSuccess] = useState(false); useEffect(() => { if (bookingId) { fetchData(Number(bookingId)); } }, [bookingId]); const fetchData = async (id: number) => { try { setLoading(true); setError(null); const bookingResponse = await getBookingById(id); if (!bookingResponse.success || !bookingResponse.data?.booking) { throw new Error('Booking not found'); } const bookingData = bookingResponse.data.booking; setBooking(bookingData); if (bookingData.status === 'confirmed' || bookingData.status === 'checked_in') { toast.success('Booking is already confirmed!'); navigate(`/bookings/${id}`); return; } if (bookingData.payment_method !== 'stripe') { toast.info('This booking does not use Stripe payment'); navigate(`/bookings/${id}`); return; } const paymentsResponse = await getPaymentsByBookingId(id); console.log('Payments response:', paymentsResponse); if (paymentsResponse.success && paymentsResponse.data?.payments) { const payments = paymentsResponse.data.payments; console.log('Payments found:', payments); const stripePaymentFound = payments.find( (p: Payment) => (p.payment_method === 'stripe' || p.payment_method === 'credit_card') && p.payment_status === 'pending' ); if (stripePaymentFound) { console.log('Found pending Stripe payment:', stripePaymentFound); setStripePayment(stripePaymentFound); } else { const completedPayment = payments.find( (p: Payment) => (p.payment_method === 'stripe' || p.payment_method === 'credit_card') && p.payment_status === 'completed' ); if (completedPayment) { console.log('Found completed Stripe payment:', completedPayment); setStripePayment(completedPayment); setPaymentSuccess(true); if ((bookingData.status as string) === 'confirmed' || (bookingData.status as string) === 'checked_in') { toast.info('Payment already completed. Booking is confirmed.'); setTimeout(() => { navigate(`/bookings/${id}`); }, 1500); return; } } else { console.warn('No Stripe payment found in payments array:', payments); console.warn('Booking payment method:', bookingData.payment_method); throw new Error('No Stripe payment record found for this booking. The payment may not have been created properly.'); } } } else { console.warn('Payments response not successful or no payments data:', paymentsResponse); if (bookingData.payments && bookingData.payments.length > 0) { console.log('Using payments from booking data:', bookingData.payments); const stripePaymentFromBooking = bookingData.payments.find( (p: any) => (p.payment_method === 'stripe' || p.payment_method === 'credit_card') && p.payment_status === 'pending' ); if (stripePaymentFromBooking) { setStripePayment(stripePaymentFromBooking as unknown as Payment); } else { throw new Error('No pending Stripe payment found for this booking'); } } else { console.error('No payments found for booking. This might be a timing issue.'); throw new Error('Payment information not found. Please wait a moment and refresh, or contact support if the issue persists.'); } } } catch (err: any) { console.error('Error fetching data:', err); const message = err.response?.data?.message || err.message || 'Unable to load payment information'; setError(message); toast.error(message); } finally { setLoading(false); } }; const formatPrice = (price: number) => formatCurrency(price); if (loading) { return ; } if (error || !booking || !stripePayment) { return (

{error || 'Payment information not found'}

Back to booking list
); } let paymentAmount = parseFloat(stripePayment.amount.toString()); const isPaymentCompleted = stripePayment.payment_status === 'completed'; console.log('Payment amount from payment record:', paymentAmount); console.log('Booking total price:', booking?.total_price); if (paymentAmount > 999999.99 || (booking && Math.abs(paymentAmount - booking.total_price) > 0.01)) { console.warn('Payment amount seems incorrect, using booking total price instead'); if (booking) { paymentAmount = parseFloat(booking.total_price.toString()); console.log('Using booking total price:', paymentAmount); } } if (paymentAmount > 999999.99) { const errorMsg = `Payment amount $${paymentAmount.toLocaleString()} exceeds Stripe's maximum. Please contact support.`; console.error(errorMsg); setError(errorMsg); return null; } return (
{} Back to booking details {} {isPaymentCompleted && (

Payment successful!

Your booking has been confirmed.

)} {} {!isPaymentCompleted && (

Complete Payment

Please complete your payment to confirm your booking

)}
{}
{}

Payment Information

Total Room Price {formatPrice(booking.total_price)}
Amount to Pay {formatPrice(paymentAmount)}
{isPaymentCompleted && (

✓ Payment completed on:{' '} {stripePayment.payment_date ? new Date(stripePayment.payment_date).toLocaleString('en-US') : 'N/A'}

{stripePayment.transaction_id && (

Transaction ID: {stripePayment.transaction_id}

)}
)}
{} {!isPaymentCompleted && booking && stripePayment && (

Card Payment

{paymentSuccess ? (

Payment Successful!

Your payment has been confirmed.

) : ( { setPaymentSuccess(true); toast.success('✅ Payment successful! Your booking has been confirmed.'); setTimeout(() => { navigate(`/bookings/${booking.id}`); }, 2000); }} onError={(error) => { toast.error(error || 'Payment failed'); }} /> )}
)}
{}

Booking Summary

Booking Number

{booking.booking_number}

Room

{booking.room?.room_number || 'N/A'}

Check-in

{parseDateLocal(booking.check_in_date).toLocaleDateString('en-US')}

Check-out

{parseDateLocal(booking.check_out_date).toLocaleDateString('en-US')}

Total Amount

{formatPrice(booking.total_price)}

); }; export default FullPaymentPage;