"use client";
import { useEffect, useState, useCallback } from "react";
import Link from "next/link";
import { motion } from "framer-motion";
import { useTranslation } from "react-i18next";
import { Home, MapPin, Phone, ShieldCheck, CreditCard, Banknote, Building, ArrowLeftRight, Loader2, Check, X, Calendar, Clock, LogIn, Lock, Info, Landmark, Wallet } from "lucide-react";
import toast, { Toaster } from "react-hot-toast";
import AuthService from "@/app/services/AuthService";
import { payDeposit, getMyTransaction, getPaymentTypes } from "@/app/utils/api";
import Loading from "../loading";
const STATUS_MAP = ["pending", "ownerConfirmed", "depositPaid", "depositConfirmed", "completed", "cancelled"];
function getStatusConfig(t) {
return {
pending: { label: t("bookingStatus.pending"), color: "bg-yellow-100 text-yellow-800 border-yellow-300", icon: Clock },
ownerConfirmed: { label: t("bookingStatus.ownerConfirmed"), color: "bg-blue-100 text-blue-800 border-blue-300", icon: ShieldCheck },
depositPaid: { label: t("bookingStatus.depositPaid"), color: "bg-orange-100 text-orange-800 border-orange-300", icon: Wallet },
depositConfirmed: { label: t("bookingStatus.depositConfirmed"), color: "bg-green-100 text-green-800 border-green-300", icon: Check },
completed: { label: t("bookingStatus.completed"), color: "bg-teal-100 text-teal-800 border-teal-300", icon: Check },
cancelled: { label: t("bookingStatus.cancelled"), color: "bg-red-100 text-red-800 border-red-300", icon: X },
};
}
function getPaymentMethods(t) {
return [
{ id: "cash", label: t("payments.method.cash"), desc: t("payments.method.cashDesc"), icon: Banknote, active: true },
{ id: "office", label: t("payments.method.office"), desc: t("payments.method.officeDesc"), icon: Building, active: true },
{ id: "transfer", label: t("payments.method.transfer"), desc: t("payments.method.transferDesc"), icon: ArrowLeftRight, active: false },
{ id: "electronic", label: t("payments.method.electronic"), desc: t("payments.method.electronicDesc"), icon: CreditCard, active: false },
];
}
function formatCurrency(v, sign = "") {
return `${sign} ${Number(v ?? 0).toLocaleString()}`;
}
function formatDate(date) {
if (!date) return "";
const d = new Date(date);
if (Number.isNaN(d.getTime())) return "";
return d.toLocaleDateString("en-GB");
}
function normalizeText(value) {
return String(value ?? "")
.trim()
.toLowerCase();
}
function isHaramText(value) {
const text = normalizeText(value);
return text.includes("haram") || text.includes("هرم") || text.includes("هرام");
}
function isReceiptRequiredPayment(value, method = null) {
const haystack = [value, method?.name, method?.label, method?.id, method?.description].filter(Boolean).join(" ");
const text = normalizeText(haystack);
return (
text.includes("transfer") ||
text.includes("تحويل") ||
text.includes("حوالة") ||
text.includes("bank") ||
text.includes("بنك") ||
isHaramText(value) ||
isHaramText(method?.name) ||
isHaramText(method?.label) ||
isHaramText(method?.id) ||
isHaramText(method?.description)
);
}
export default function PaymentsPage() {
const { t, i18n } = useTranslation();
const [reservations, setReservations] = useState([]);
const [loading, setLoading] = useState(true);
const [payingId, setPayingId] = useState(null);
const [isGuest, setIsGuest] = useState(null);
const [paymentMethods, setPaymentMethods] = useState([]);
const [loadingPaymentMethods, setLoadingPaymentMethods] = useState(true);
const [selectedPayment, setSelectedPayment] = useState(null);
const loadReservations = useCallback(async () => {
try {
const json = await getMyTransaction();
const items = Array.isArray(json) ? json : [];
const mapped = items.map((item) => {
const deposit = item?.diposit || item?.deposit || {};
const reservation = deposit?.reservation || {};
const transaction = deposit?.transaction || {};
const currency = item?.currency || {};
const propertyInfo = reservation?.propertyInformation || {};
return {
id: deposit.id ?? reservation.id ?? item?.id,
reservationId: reservation.id ?? deposit.reservationId ?? item?.reservationId,
status: reservation.status ?? 0,
startDate: reservation.startDate,
endDate: reservation.endDate,
totalPrice: reservation.totalPrice ?? transaction.amount ?? 0,
depositAmount: transaction.amount ?? reservation.totalPrice ?? 0,
currencySign: currency.sign || t("currency.syp"),
currencyName: currency.name || "",
currencyRate: currency.rate,
propertyName: propertyInfo.name || propertyInfo.address || reservation.propertyName || `${t("payments.propertyLabel")} #${reservation.id || ""}`,
propertyAddress: propertyInfo.address || reservation.propertyAddress || "",
propertyCity: propertyInfo.city || reservation.city || "",
_deposit: deposit,
_reservation: reservation,
};
});
setReservations(mapped);
} catch (err) {
console.error(err);
toast.error(t("payments.loadingTransactions"));
} finally {
setLoading(false);
}
}, [t]);
const loadPaymentMethods = useCallback(async () => {
setLoadingPaymentMethods(true);
try {
const data = await getPaymentTypes();
const methods = Array.isArray(data) ? data : [];
setPaymentMethods(methods);
const firstActive = methods.find((method) => method?.isActive === true || method?.active === true);
if (firstActive) {
setSelectedPayment(firstActive.name ?? firstActive.id ?? null);
}
} catch (err) {
console.error("[Payments] failed to load payment methods", err);
setPaymentMethods([]);
} finally {
setLoadingPaymentMethods(false);
}
}, []);
useEffect(() => {
if (AuthService.isGuest()) {
setIsGuest(true);
setLoading(false);
return;
}
setIsGuest(false);
loadReservations();
}, [loadReservations]);
useEffect(() => {
loadPaymentMethods();
}, [loadPaymentMethods]);
const resolvePaymentTypeId = (paymentKey) => {
const method = paymentMethods.find((m) => String(m.id) === String(paymentKey) || String(m.name) === String(paymentKey));
return method?.id ?? paymentKey;
};
const handlePayDeposit = async (reservation, paymentKey, paymentImageFile) => {
const paymentTypeId = resolvePaymentTypeId(paymentKey);
const selectedMethod = paymentMethods.find((m) => String(m.id) === String(paymentTypeId) || String(m.name) === String(paymentTypeId));
const requiresReceiptUpload = isReceiptRequiredPayment(paymentKey, selectedMethod);
if (requiresReceiptUpload && !paymentImageFile) {
toast.error(t("payments.receiptRequired"));
return;
}
setPayingId(reservation.id);
try {
await payDeposit({
reservationId: reservation.id,
paymentTypeId,
paymentImage: paymentImageFile,
});
toast.success(t("payments.depositPaidSuccess"));
loadReservations();
} catch (err) {
toast.error(err?.message || t("payments.paymentFailed"));
} finally {
setPayingId(null);
}
};
const canPay = (status) => STATUS_MAP[status] === "ownerConfirmed";
if (loading) {
return
{t("payments.loginRequiredDesc")}
{t("payments.description")}
{t("payments.noTransactionsDesc")}
{t("payments.depositAmount")}
{formatCurrency(amount, r.currencySign)}
{t("payments.depositPaidToPlatform")}
{t("payments.cashOnlyNotice")}
{t("payments.paymentMethodLabel")}
{t("payments.receiptUploadRequiredHint")}
{t("payments.receiptDialogDescription")}
{t("payments.cashPendingDialogDesc1")}
{t("payments.cashPendingDialogDesc2")}
{t("payments.platformOfficeLabel")}
{t("payments.platformOfficeFullAddress")}
{t("payments.cashPaymentLocationLabel")}
{t("payments.platformOfficeFullAddress")}