import React, { useState, useEffect, useCallback } from 'react'; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { SafeAreaView } from 'react-native-safe-area-context'; import { router, useLocalSearchParams } from 'expo-router'; import { usePaymentSheet } from '@stripe/stripe-react-native'; import { api } from '@/services/api'; import { useBeneficiary } from '@/contexts/BeneficiaryContext'; import { useAuth } from '@/contexts/AuthContext'; import { useToast } from '@/components/ui/Toast'; import { LoadingSpinner } from '@/components/ui/LoadingSpinner'; import { FullScreenError } from '@/components/ui/ErrorMessage'; import { AppColors, BorderRadius, FontSizes, FontWeights, Spacing, Shadows, } from '@/constants/theme'; import type { Beneficiary } from '@/types'; import { hasBeneficiaryDevices } from '@/services/BeneficiaryDetailController'; const STRIPE_API_URL = 'https://wellnuo.smartlaunchhub.com/api/stripe'; const STARTER_KIT = { name: 'WellNuo Starter Kit', price: '$399', priceValue: 399, description: '5 smart sensors that easily plug into any outlet and set up through the app in minutes', }; export default function PurchaseScreen() { const { id } = useLocalSearchParams<{ id: string }>(); const { user } = useAuth(); const toast = useToast(); const [beneficiary, setBeneficiary] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [isProcessing, setIsProcessing] = useState(false); const { initPaymentSheet, presentPaymentSheet } = usePaymentSheet(); const loadBeneficiary = useCallback(async () => { if (!id) return; setIsLoading(true); setError(null); try { const response = await api.getWellNuoBeneficiary(parseInt(id, 10)); if (response.ok && response.data) { setBeneficiary(response.data); // Redirect if user already has devices - shouldn't be on purchase page if (hasBeneficiaryDevices(response.data)) { router.replace(`/(tabs)/beneficiaries/${id}`); return; } // Redirect if equipment is ordered/shipped/delivered const status = response.data.equipmentStatus; if (status && ['ordered', 'shipped', 'delivered'].includes(status)) { router.replace(`/(tabs)/beneficiaries/${id}/equipment-status`); return; } } else { setError(response.error?.message || 'Failed to load beneficiary'); } } catch (err) { setError(err instanceof Error ? err.message : 'An error occurred'); } finally { setIsLoading(false); } }, [id]); useEffect(() => { loadBeneficiary(); }, [loadBeneficiary]); const handlePurchase = async () => { if (!beneficiary) return; setIsProcessing(true); try { const response = await fetch(`${STRIPE_API_URL}/create-payment-sheet`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: user?.email || 'guest@wellnuo.com', amount: STARTER_KIT.priceValue * 100, metadata: { userId: user?.user_id || 'guest', beneficiaryName: beneficiary.displayName, beneficiaryId: id, orderType: 'starter_kit', }, }), }); const data = await response.json(); if (!data.paymentIntent) { throw new Error(data.error || 'Failed to create payment sheet'); } const { error: initError } = await initPaymentSheet({ merchantDisplayName: 'WellNuo', paymentIntentClientSecret: data.paymentIntent, customerId: data.customer, customerEphemeralKeySecret: data.ephemeralKey, defaultBillingDetails: { email: user?.email || '', }, returnURL: 'wellnuo://stripe-redirect', applePay: { merchantCountryCode: 'US', }, googlePay: { merchantCountryCode: 'US', testEnv: true, }, }); if (initError) { throw new Error(initError.message); } const { error: presentError } = await presentPaymentSheet(); if (presentError) { if (presentError.code === 'Canceled') { setIsProcessing(false); return; } throw new Error(presentError.message); } // Payment successful - update equipment status to 'ordered' const statusResponse = await api.updateBeneficiaryEquipmentStatus( parseInt(id, 10), 'ordered' ); if (!statusResponse.ok) { // Failed to update equipment status, but continue anyway - payment was successful } // Show success and navigate to equipment tracking toast.success('Order Placed!', 'Your WellNuo Starter Kit is on its way.'); router.replace(`/(tabs)/beneficiaries/${id}/equipment-status`); } catch (error) { toast.error( 'Payment Failed', error instanceof Error ? error.message : 'Something went wrong. Please try again.' ); } finally { setIsProcessing(false); } }; const handleAlreadyHaveSensors = () => { router.push({ pathname: '/(auth)/activate', params: { beneficiaryId: id, lovedOneName: beneficiary?.displayName }, }); }; if (isLoading) { return ; } if (error || !beneficiary) { return ( ); } return ( {/* Header */} router.back()}> Get Started {/* Icon */} {/* Title */} Start Monitoring {beneficiary.displayName} To monitor wellness, you need WellNuo sensors installed in their home. {/* Kit Card */} {STARTER_KIT.name} {STARTER_KIT.price} {STARTER_KIT.description} {/* Security Badge */} Secure payment by Stripe {/* Actions */} {isProcessing ? ( ) : ( <> Buy Now )} I already have sensors ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: AppColors.background, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: Spacing.md, paddingVertical: Spacing.sm, borderBottomWidth: 1, borderBottomColor: AppColors.border, }, backButton: { padding: Spacing.xs, }, headerTitle: { fontSize: FontSizes.lg, fontWeight: FontWeights.semibold, color: AppColors.textPrimary, }, placeholder: { width: 32, }, content: { flex: 1, }, scrollContent: { padding: Spacing.lg, paddingBottom: Spacing.xxl, }, iconContainer: { width: 120, height: 120, borderRadius: 60, backgroundColor: AppColors.primaryLighter, justifyContent: 'center', alignItems: 'center', alignSelf: 'center', marginBottom: Spacing.lg, }, title: { fontSize: FontSizes['2xl'], fontWeight: FontWeights.bold, color: AppColors.textPrimary, textAlign: 'center', marginBottom: Spacing.sm, }, subtitle: { fontSize: FontSizes.base, color: AppColors.textSecondary, textAlign: 'center', marginBottom: Spacing.xl, lineHeight: 22, }, kitCard: { backgroundColor: AppColors.surface, borderRadius: BorderRadius.xl, padding: Spacing.lg, marginBottom: Spacing.lg, ...Shadows.md, }, kitName: { fontSize: FontSizes.lg, fontWeight: FontWeights.bold, color: AppColors.textPrimary, textAlign: 'center', }, kitPrice: { fontSize: FontSizes['3xl'], fontWeight: FontWeights.bold, color: AppColors.primary, textAlign: 'center', marginVertical: Spacing.md, }, kitDescription: { fontSize: FontSizes.base, color: AppColors.textSecondary, textAlign: 'center', lineHeight: 22, }, actionsSection: { gap: Spacing.md, }, buyButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: AppColors.primary, paddingVertical: Spacing.md, borderRadius: BorderRadius.lg, gap: Spacing.sm, }, buyButtonDisabled: { opacity: 0.7, }, buyButtonText: { fontSize: FontSizes.base, fontWeight: FontWeights.semibold, color: AppColors.white, }, securityBadge: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginTop: Spacing.md, gap: Spacing.xs, }, securityText: { fontSize: FontSizes.xs, color: AppColors.success, }, alreadyHaveButton: { alignItems: 'center', paddingVertical: Spacing.sm, }, alreadyHaveText: { fontSize: FontSizes.base, color: AppColors.textSecondary, textDecorationLine: 'underline', }, });