import React, { useEffect, useRef, useState } from "react"; import { View, Text, ScrollView, Pressable } from "react-native"; import Svg, { G, Path } from "react-native-svg"; import { Button } from "~/components/ui/button"; import { LucideChevronRightCircle } from "lucide-react-native"; import { useLocalSearchParams, router } from "expo-router"; import { TransactionService } from "~/lib/services/transactionService"; import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile"; import { useUserWallet } from "~/lib/hooks/useUserWallet"; import BackButton from "~/components/ui/backButton"; import { AwashIcon, TeleBirrIcon } from "~/components/ui/icons"; import { calculateTotalAmountForSending, calculateProcessingFee, } from "~/lib/utils/feeUtils"; import { showAlert } from "~/lib/utils/alertUtils"; import { ROUTES } from "~/lib/routes"; import ScreenWrapper from "~/components/ui/ScreenWrapper"; import ModalToast from "~/components/ui/toast"; import BottomSheet from "~/components/ui/bottomSheet"; import { useTranslation } from "react-i18next"; export default function SendBank() { const { t } = useTranslation(); const params = useLocalSearchParams<{ amount: string; recipientName: string; recipientPhoneNumber: string; recipientType: "saved" | "contact"; recipientId: string; note: string; transactionType?: "send" | "cashout"; }>(); const { user } = useAuthWithProfile(); const { wallet, refreshWallet } = useUserWallet(user); const [selectedBank, setSelectedBank] = useState<"awash" | "telebirr" | null>( null ); const [isAccountSheetVisible, setIsAccountSheetVisible] = useState(false); const [selectedAccountId, setSelectedAccountId] = useState( null ); const [isProcessing, setIsProcessing] = 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 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 handleBankSelection = (bankProvider: "awash" | "telebirr") => { setSelectedBank(bankProvider); if (bankProvider !== "awash") { setSelectedAccountId(null); setIsAccountSheetVisible(false); } }; const handleSendOrCashOutTransaction = async () => { if (!selectedBank) { showToast( t("sendbank.toastErrorTitle"), t("sendbank.toastNoMethod"), "error" ); return; } if (!params.amount || !user?.uid) { showToast( t("sendbank.toastErrorTitle"), t("sendbank.toastMissingInfo"), "error" ); return; } if (selectedBank === "awash" && wallet?.cards && wallet.cards.length > 0) { if (!selectedAccountId) { showToast( t("sendbank.toastErrorTitle"), t("sendbank.toastNoAccount"), "error" ); return; } } const amountInCents = parseInt(params.amount); // Amount is already in cents if (isNaN(amountInCents) || amountInCents <= 0) { showToast( t("sendbank.toastErrorTitle"), t("sendbank.toastInvalidAmount"), "error" ); return; } // Check if user has sufficient balance if (params.transactionType === "cashout") { // For cashout, no processing fee if (!wallet || wallet.balance < amountInCents) { const required = (amountInCents / 100).toFixed(2); const available = ((wallet?.balance ?? 0) / 100).toFixed(2); showToast( t("sendbank.toastInsufficientBalanceTitle"), t("sendbank.toastInsufficientBalanceCashoutDescription", { required, available, }), "error" ); return; } } else { // For send money, include processing fee const totalRequired = calculateTotalAmountForSending(amountInCents); if (!wallet || wallet.balance < totalRequired) { const processingFee = calculateProcessingFee(amountInCents); const required = (totalRequired / 100).toFixed(2); const fee = (processingFee / 100).toFixed(2); const available = ((wallet?.balance ?? 0) / 100).toFixed(2); showToast( t("sendbank.toastInsufficientBalanceTitle"), t("sendbank.toastInsufficientBalanceSendDescription", { required, fee, available, }), "error" ); return; } } setIsProcessing(true); try { let result; let successMessage; console.log("PARAMS TRANSACTION TYPE", params.transactionType); if (params.transactionType === "cashout") { // Handle cash out transaction result = await TransactionService.cashOut(user.uid, { amount: amountInCents, // Amount is already in cents bankProvider: selectedBank, note: params.note || "Cash out to bank account", }); successMessage = `Successfully cashed out $${( amountInCents / 100 ).toFixed(2)} to your ${selectedBank} account`; } else { // Handle send money transaction if (!params.recipientName) { showToast( t("sendbank.toastErrorTitle"), t("sendbank.toastMissingRecipient"), "error" ); setIsProcessing(false); return; } result = await TransactionService.sendMoney(user.uid, { amount: amountInCents, // Amount is already in cents recipientName: params.recipientName, recipientPhoneNumber: params.recipientPhoneNumber, recipientType: params.recipientType, recipientId: params.recipientId, note: params.note || "", }); successMessage = `Successfully transferred $${( amountInCents / 100 ).toFixed(2)} to ${params.recipientName}`; } if (result.success) { await refreshWallet(); if (params.transactionType === "cashout") { router.replace({ pathname: ROUTES.CASHOUT_COMPLETION, params: { note: successMessage, amount: (amountInCents / 100).toFixed(2), }, }); } else { router.replace({ pathname: ROUTES.TASK_COMPLETION, params: { message: successMessage, amount: (amountInCents / 100).toFixed(2), recipientName: params.recipientName, bankProvider: selectedBank, }, }); } } else { showToast( t("sendbank.toastErrorTitle"), result.error || t("sendbank.toastProcessFailed"), "error" ); } } catch (error) { console.error("Error processing transaction:", error); showToast( t("sendbank.toastErrorTitle"), t("sendbank.toastProcessFailedWithRetry"), "error" ); } finally { setIsProcessing(false); } }; const handleClose = () => { router.back(); }; return ( {params.amount && ( ${(parseInt(params.amount) / 100).toFixed(2)}{" "} {params.transactionType === "cashout" ? t("sendbank.amountTitleCashOut") : t("sendbank.amountTitleToRecipient", { recipientName: params.recipientName, })} {params.note && ( {t("sendbank.noteWithText", { note: params.note })} )} setIsAccountSheetVisible(false)} > {t("sendbank.chooseAccountTitle")} {wallet?.cards && wallet.cards.length > 0 ? ( <> {wallet.cards.map((card) => ( setSelectedAccountId(card.id)} > {t("sendbank.accountLabel")} {card.cardNumber} ))} ) : ( {t("sendbank.noAccounts")} )} )} {t("sendbank.paymentOptionsTitle")} {selectedBank ? t("sendbank.paymentOptionsSelected", { providerName: selectedBank === "awash" ? t("sendbank.awashName") : t("sendbank.telebirrName"), }) : t("sendbank.paymentOptionsUnselected")} {/* Telebirr Section */} {t("sendbank.telebirrName")} handleBankSelection("telebirr")} disabled={isProcessing} > {t("sendbank.telebirrName")} {t("sendbank.telebirrSubtitle")} {/* Bank Section with Awash */} Bank { handleBankSelection("awash"); setIsAccountSheetVisible(true); }} disabled={isProcessing} > {t("sendbank.awashName")} {t("sendbank.awashSubtitle")} {/* Send Button */} {selectedBank && !isProcessing && ( )} {t("sendbank.poweredBy")} ); }