import React, { useState, useRef, useEffect } from "react"; import { View, Text, ScrollView, TouchableOpacity, Alert, ActivityIndicator, } from "react-native"; import ScreenWrapper from "~/components/ui/ScreenWrapper"; import { Button } from "~/components/ui/button"; import { Input } from "~/components/ui/input"; import { UploadCloud } from "lucide-react-native"; import Dropdown, { type DropdownOption } from "~/components/ui/dropdown"; import ModalToast from "~/components/ui/toast"; import BackButton from "~/components/ui/backButton"; import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile"; import AuthService from "~/lib/services/authServices"; import { uploadKycDocument } from "~/lib/services/kycDocumentService"; import * as ImagePicker from "expo-image-picker"; export default function KycScreen() { const { user, refreshProfile } = useAuthWithProfile(); const [activeTab, setActiveTab] = useState<"personal" | "business">( "personal" ); const [fanNumber, setFanNumber] = useState(""); const [tin, setTin] = useState(""); const [businessType, setBusinessType] = useState(""); const [nationalIdUri, setNationalIdUri] = useState(null); const [nationalIdLabel, setNationalIdLabel] = useState(""); const [businessLicenseUri, setBusinessLicenseUri] = useState( null ); const [businessLicenseLabel, setBusinessLicenseLabel] = useState(""); const [pickingNationalId, setPickingNationalId] = useState(false); const [pickingBusinessLicense, setPickingBusinessLicense] = useState(false); const [submitting, setSubmitting] = useState(false); 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); const businessTypeOptions: DropdownOption[] = [ { label: "Retail & E-commerce", value: "Retail & E-commerce" }, { label: "Food & Beverage", value: "Food & Beverage" }, { label: "Transportation & Logistics", value: "Transportation & Logistics", }, { label: "Finance & Fintech", value: "Finance & Fintech" }, { label: "Healthcare & Pharmacy", value: "Healthcare & Pharmacy", }, { label: "Education & Training", value: "Education & Training" }, { label: "Construction & Real Estate", value: "Construction & Real Estate", }, { label: "Technology & Software", value: "Technology & Software", }, { label: "Entertainment & Events", value: "Entertainment & Events" }, { label: "Agriculture & Farming", value: "Agriculture & Farming" }, { label: "Freelancer / Sole Proprietor", value: "Freelancer / Sole Proprietor", }, { label: "Other", value: "Other" }, ]; 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); }; useEffect(() => { return () => { if (toastTimeoutRef.current) { clearTimeout(toastTimeoutRef.current); } }; }, []); const handlePrimary = async () => { if (!user?.uid) { showToast("Error", "You must be logged in to save KYC.", "error"); return; } try { setSubmitting(true); const updateData: any = {}; if (activeTab === "personal") { if (!fanNumber.trim()) { showToast("Error", "Please enter your FAN Number.", "error"); setSubmitting(false); return; } updateData.fanNumber = fanNumber.trim(); if (nationalIdUri) { try { const url = await uploadKycDocument( user.uid, nationalIdUri, "personal-id" ); updateData.nationalIdUrl = url; } catch (e) { console.error("[KYC] Failed to upload national ID", e); showToast("Error", "Failed to upload National ID.", "error"); setSubmitting(false); return; } } } else { if (!tin.trim()) { showToast("Error", "Please enter your EIN / TIN.", "error"); setSubmitting(false); return; } if (!businessType.trim()) { showToast("Error", "Please enter your business type.", "error"); setSubmitting(false); return; } updateData.tin = tin.trim(); updateData.businessType = businessType.trim(); if (businessLicenseUri) { try { const url = await uploadKycDocument( user.uid, businessLicenseUri, "business-license" ); updateData.businessLicenseUrl = url; } catch (e) { console.error("[KYC] Failed to upload business license", e); showToast("Error", "Failed to upload Business License.", "error"); setSubmitting(false); return; } } } const result = await AuthService.updateUserProfile(user.uid, updateData); if (!result.success) { console.error("[KYC] updateUserProfile failed", result.error); showToast("Error", result.error || "Failed to save KYC.", "error"); return; } try { await refreshProfile(); } catch (e) { console.warn("[KYC] Failed to refresh profile after KYC save", e); } // Successful save: clear all KYC fields setFanNumber(""); setTin(""); setBusinessType(""); setNationalIdUri(null); setNationalIdLabel(""); setBusinessLicenseUri(null); setBusinessLicenseLabel(""); showToast("Success", "KYC information saved.", "success"); } catch (e) { console.error("[KYC] Unexpected error while saving KYC", e); showToast("Error", "Unexpected error while saving KYC.", "error"); } finally { setSubmitting(false); } }; const handlePickNationalId = async () => { if (pickingNationalId) return; try { setPickingNationalId(true); const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permissionResult.granted) { Alert.alert( "Permission Required", "Please allow access to your photo library to upload your ID." ); return; } const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, quality: 0.8, }); if (!result.canceled && result.assets[0]) { const uri = result.assets[0].uri; setNationalIdUri(uri); const name = uri.split("/").pop() || "Selected file"; setNationalIdLabel(name); } } catch (e) { console.error("[KYC] Error while selecting National ID", e); showToast("Error", "Failed to select National ID.", "error"); } finally { setPickingNationalId(false); } }; const handlePickBusinessLicense = async () => { if (pickingBusinessLicense) return; try { setPickingBusinessLicense(true); const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permissionResult.granted) { Alert.alert( "Permission Required", "Please allow access to your photo library to upload your Business License." ); return; } const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, quality: 0.8, }); if (!result.canceled && result.assets[0]) { const uri = result.assets[0].uri; setBusinessLicenseUri(uri); const name = uri.split("/").pop() || "Selected file"; setBusinessLicenseLabel(name); } } catch (e) { console.error("[KYC] Error while selecting Business License", e); showToast("Error", "Failed to select Business License.", "error"); } finally { setPickingBusinessLicense(false); } }; return ( Information KYC Fill out the information below to add more limits to your account {/* tab */} setActiveTab("personal")} className={`flex-1 items-center py-2 rounded-full ${ activeTab === "personal" ? "bg-white" : "bg-transparent" }`} activeOpacity={0.8} > Personal setActiveTab("business")} className={`flex-1 items-center py-2 rounded-full ${ activeTab === "business" ? "bg-white" : "bg-transparent" }`} activeOpacity={0.8} > Business {activeTab === "personal" ? ( FAN Number National ID Upload ) : ( ) } /> ) : ( EIN / TIN Type of Business setBusinessType(value)} placeholder="Select type of business" /> Business License ) : ( ) } /> )} ); }