import React, { useState, useEffect, useRef } from "react"; import { View, ScrollView, Keyboard, Platform, KeyboardAvoidingView, TouchableWithoutFeedback, Image, TouchableOpacity, } from "react-native"; import { Button } from "~/components/ui/button"; import { Input } from "~/components/ui/input"; import { Label } from "~/components/ui/label"; import { Text } from "~/components/ui/text"; import { router } from "expo-router"; import { ROUTES } from "~/lib/routes"; import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile"; import { AuthService } from "~/lib/services/authServices"; import BackButton from "~/components/ui/backButton"; import ScreenWrapper from "~/components/ui/ScreenWrapper"; import WalletService from "~/lib/services/walletService"; import { fullNameSchema, phoneNumberSchema, pinSchema, confirmPinSchema, addressSchema, validate, } from "~/lib/utils/validationSchemas"; import { useAuthStore } from "~/lib/stores/authStore"; import ModalToast from "~/components/ui/toast"; import * as ImagePicker from "expo-image-picker"; import { Icons } from "~/assets/icons"; import { Plus } from "lucide-react-native"; import { uploadProfileImage } from "~/lib/services/profileImageService"; // Conditionally import FCMService only for native let FCMService: any = null; if (Platform.OS !== "web") { FCMService = require("~/lib/services/fcmService").FCMService; } export default function GoogleSetup() { const { user, refreshProfile, refreshWallet } = useAuthWithProfile(); const { signOut } = useAuthStore(); // Pre-fill with Google account info if available const [fullName, setFullName] = useState(user?.displayName || ""); const [phoneNumber, setPhoneNumber] = useState(""); const [address, setAddress] = useState(""); const [pin, setPin] = useState(""); const [confirmPin, setConfirmPin] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [profileImage, setProfileImage] = useState(null); const [toastVisible, setToastVisible] = useState(false); const [toastTitle, setToastTitle] = useState(""); const [toastDescription, setToastDescription] = useState( undefined ); const [toastVariant, setToastVariant] = useState< "success" | "error" | "warning" | "info" >("info"); const toastTimeoutRef = useRef | null>(null); console.log("GOOGLE SETUP PAGE LOADED, user:", user?.uid); const showToast = ( title: string, description?: string, variant: "success" | "error" | "warning" | "info" = "info" ) => { if (toastTimeoutRef.current) { clearTimeout(toastTimeoutRef.current); } setToastTitle(title); setToastDescription(description); setToastVariant(variant); setToastVisible(true); toastTimeoutRef.current = setTimeout(() => { setToastVisible(false); toastTimeoutRef.current = null; }, 2500); }; // Redirect if no user is authenticated useEffect(() => { if (!user) { console.log("NO USER FOUND, redirecting to signin"); router.replace(ROUTES.SIGNIN); } }, [user]); // Update fullName when user data becomes available useEffect(() => { if (user?.displayName && !fullName) { setFullName(user.displayName); } }, [user?.displayName]); const handleSelectProfileImage = async () => { try { const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permissionResult.granted) { showToast( "Permission Required", "Please allow access to your photo library to select a profile picture.", "error" ); return; } const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [1, 1], quality: 0.8, }); if (!result.canceled && result.assets[0]) { setProfileImage(result.assets[0].uri); } } catch (e) { showToast("Error", "Failed to select image", "error"); } }; const handleCompleteSetup = async () => { Keyboard.dismiss(); // Dev-only shortcut: on emulator/dev builds, skip profile setup and go straight home if (__DEV__) { console.log( "DEV google setup bypass: skipping profile creation and navigating to HOME" ); router.replace(ROUTES.HOME); return; } if (!user) { showToast("Error", "No authenticated user found", "error"); return; } // Validate full name const fullNameResult = validate(fullNameSchema, fullName); if (!fullNameResult.success) { showToast("Error", fullNameResult.error, "warning"); return; } // Validate phone number const phoneResult = validate(phoneNumberSchema, phoneNumber); if (!phoneResult.success) { showToast("Error", phoneResult.error, "warning"); return; } // Validate PIN const pinResult = validate(pinSchema, pin); if (!pinResult.success) { showToast("Error", pinResult.error, "warning"); return; } // Validate confirm PIN const confirmPinResult = validate(confirmPinSchema(pin), confirmPin); if (!confirmPinResult.success) { showToast("Error", confirmPinResult.error, "warning"); return; } // Validate address (optional) const addressResult = validate(addressSchema, address); if (!addressResult.success) { showToast("Error", addressResult.error, "warning"); return; } setLoading(true); setError(null); try { let photoUrl: string | undefined; if (profileImage) { try { photoUrl = await uploadProfileImage(user.uid, profileImage); } catch (e) { console.warn("Failed to upload profile image during setup", e); } } await AuthService.createUserProfile(user.uid, { fullName: fullName.trim(), phoneNumber: phoneNumber.trim(), address: address.trim() || undefined, email: user.email || "", pin: pin.trim(), signupType: "google", createdAt: new Date(), updatedAt: new Date(), photoUrl, }); // Initialize FCM token for new user (native only) if (Platform.OS !== "web" && FCMService) { try { const fcmResult = await FCMService.initializeTokenForNewUser( user.uid ); if (fcmResult.success) { console.log("FCM token initialized for new user"); } else { console.warn("Failed to initialize FCM token:", fcmResult.error); } } catch (fcmError) { console.error("Error initializing FCM token:", fcmError); } } // Create wallet for the user await WalletService.createUserWallet(user.uid); console.log("User wallet created successfully"); // Refresh profile and wallet to update auth context await refreshProfile(); await refreshWallet(); router.replace(ROUTES.HOME); } catch (error) { console.error("Profile setup error:", error); setError( error instanceof Error ? error.message : "Failed to complete setup" ); showToast( "Error", "Failed to complete profile setup. Please try again.", "error" ); } finally { setLoading(false); } }; const handleBackPress = () => { showToast( "Cancel Setup", "Are you sure you want to cancel? You will need to sign in again.", "warning" ); setTimeout(async () => { try { await signOut(); router.replace(ROUTES.SIGNIN); } catch (error) { console.error("Error signing out:", error); router.replace(ROUTES.SIGNIN); } }, 1500); }; if (!user) { return null; // Will redirect to signin } return ( Welcome to AmbaPay! Just a few more details to get you started. {profileImage ? ( ) : ( )} ); }