import React, { useRef, useState } from "react"; import { Text, View, ScrollView, TextInput, ActivityIndicator, } from "react-native"; import { Button } from "~/components/ui/button"; import { router, useLocalSearchParams } from "expo-router"; import BackButton from "~/components/ui/backButton"; import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile"; import useTransactions from "~/lib/hooks/useTransactions"; import { ROUTES } from "~/lib/routes"; import ScreenWrapper from "~/components/ui/ScreenWrapper"; import { useTranslation } from "react-i18next"; import ModalToast from "~/components/ui/toast"; import { TicketService } from "~/lib/services/ticketService"; import { awardPoints } from "~/lib/services/pointsService"; import { applyReferral } from "~/lib/services/referralService"; export default function TransDetail() { const { t } = useTranslation(); const params = useLocalSearchParams<{ transactionId?: string; amount?: string; type?: string; recipientName?: string; date?: string; status?: string; note?: string; flowType?: string; ticketTierId?: string; eventId?: string; ticketCount?: string; fromHistory?: string; }>(); const { user } = useAuthWithProfile(); 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 [isProcessing, setIsProcessing] = useState(false); const [referralCode, setReferralCode] = useState(""); 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); }; // Parse amount from cents to dollars const amountInCents = parseInt(params.amount || "0"); const amountInDollars = amountInCents / 100; // Calculate processing fee (1.25% of the amount) const processingFeeInCents = Math.round(amountInCents * 0.0125); const processingFeeInDollars = processingFeeInCents / 100; // Calculate total (amount + processing fee) const totalInCents = amountInCents + processingFeeInCents; const totalInDollars = totalInCents / 100; const isEventTicket = params.type === "event_ticket"; const fromHistory = params.fromHistory === "true"; // Format date const formatDate = (dateString?: string) => { if (!dateString) return t("transdetail.dateUnknown"); const date = new Date(dateString); return date.toLocaleDateString("en-US", { month: "2-digit", day: "2-digit", year: "numeric", }); }; // Get transaction description based on type const getTransactionDescription = () => { switch (params.type) { case "send": return t("transdetail.descriptionSend", { recipientName: params.recipientName, }); case "receive": return t("transdetail.descriptionReceive", { recipientName: params.recipientName, }); case "add_cash": return t("transdetail.descriptionAddCash"); case "cash_out": return t("transdetail.descriptionCashOut"); case "event_ticket": return `Ticket purchase for ${params.recipientName || "event"}`; default: return t("transdetail.descriptionDefault"); } }; const handlePrimaryAction = async () => { if (isEventTicket) { if (!user) { showToast( t("transconfirm.toastErrorTitle"), "You must be logged in to buy tickets.", "error" ); return; } const ticketTierId = params.ticketTierId; const eventId = params.eventId; const ticketCount = params.ticketCount ? parseInt(params.ticketCount) : 1; if (!ticketTierId || !eventId || !ticketCount || isNaN(ticketCount)) { showToast( t("transconfirm.toastErrorTitle"), "Missing ticket information.", "error" ); return; } try { setIsProcessing(true); const token = await user.getIdToken(); await TicketService.buyTicket(token, { ticketTierId, eventId, ticketCount, }); try { await awardPoints("purchase_ticket"); } catch (error) { console.warn( "[TransDetail] Failed to award purchase ticket points", error ); } // Apply referral for event purchase if a code was provided if (referralCode.trim() && eventId) { try { const referralResult = await applyReferral({ referralCode: referralCode.trim(), uid: user.uid, referralReason: "event", contextId: eventId, }); console.log( "[TransDetail] Event referral apply result", referralResult ); if (!referralResult.success) { console.warn( "[TransDetail] Failed to apply event referral:", referralResult.error ); showToast( t("transconfirm.toastErrorTitle"), referralResult.error || "Failed to apply referral code", "error" ); } } catch (referralError) { console.error( "[TransDetail] Error while applying event referral code", referralError ); showToast( t("transconfirm.toastErrorTitle"), "Failed to apply referral code", "error" ); } } router.replace({ pathname: "/(screens)/taskcomp", params: { amount: amountInDollars.toFixed(2), message: `Ticket for ${ params.recipientName || "event" } purchased successfully.`, flowType: "event_ticket", }, }); } catch (error) { console.error("[TransDetail] Error buying ticket", error); let apiMessage: string | undefined; if (error instanceof Error) { try { const parsed = JSON.parse(error.message); if (parsed && typeof parsed.message === "string") { apiMessage = parsed.message; } } catch {} } showToast( t("transconfirm.toastErrorTitle"), apiMessage || "Could not complete ticket purchase. Please try again.", "error" ); } finally { setIsProcessing(false); } return; } if (!fromHistory && referralCode.trim() && user && params.transactionId) { try { setIsProcessing(true); const referralResult = await applyReferral({ referralCode: referralCode.trim(), uid: user.uid, referralReason: "transaction", contextId: params.transactionId, }); console.log( "[TransDetail] Transaction referral apply result", referralResult ); if (!referralResult.success) { console.warn( "[TransDetail] Failed to apply transaction referral:", referralResult.error ); showToast( t("transconfirm.toastErrorTitle"), referralResult.error || "Failed to apply referral code", "error" ); } } catch (referralError) { console.error( "[TransDetail] Error while applying transaction referral code", referralError ); showToast( t("transconfirm.toastErrorTitle"), "Failed to apply referral code", "error" ); } finally { setIsProcessing(false); } } router.replace(ROUTES.HOME); router.push(ROUTES.SEND_OR_REQUEST_MONEY); }; return ( {t("transdetail.title")} ${amountInDollars.toFixed(2)} {getTransactionDescription()} {t("transdetail.sectionTitle")} {t("transdetail.dateLabel")} {formatDate(params.date)} {t("transdetail.statusLabel")} {params.status || t("transdetail.statusUnknown")} {params.note && ( {t("transdetail.noteLabel")} {params.note} )} {t("transdetail.processingFeeLabel")} ${processingFeeInDollars.toFixed(2)} {t("transdetail.subtotalLabel")} ${amountInDollars.toFixed(2)} {t("transdetail.totalLabel")} ${totalInDollars.toFixed(2)} {/* Referral code input (only shown when not coming from History) */} {!fromHistory && ( {t("transdetail.referralCodeLabel", "Referral Code")} )} ); }