"use client"; import React, { useState } from "react"; import Link from "next/link"; import { motion, AnimatePresence } from "motion/react"; import { X, Download, Package, ShoppingBag, MapPin, Clock, CreditCard, CheckCircle2, Truck, PackageCheck, XCircle, AlertCircle, Wallet, Building2, Loader2, ArrowRight, Sparkles, } from "lucide-react"; import { toPersian } from "../lib/utils"; import api from "../lib/services/api"; import { toast } from "sonner"; import { useSettingsStore } from "../lib/store/settingsStore"; import SafeImage from "./SafeImage"; interface OrderDetailsModalProps { isOpen: boolean; onClose: () => void; order: Record | null; onOrderUpdated?: (orderId: string, newStatus: string) => void; } export default function OrderDetailsModal({ isOpen, onClose, order, onOrderUpdated, }: OrderDetailsModalProps) { const getText = useSettingsStore((state) => state.getText); const isCardToCardEnabled = getText('PAY_GATEWAY_CARD_ENABLE', 'true') === 'true' && getText('cart_to_cart_enabled', 'true') === 'true'; const [retryModalOpen, setRetryModalOpen] = useState(false); const [selectedMethod, setSelectedMethod] = useState<'online' | 'wallet' | 'card'>('online'); const [isProcessingPayment, setIsProcessingPayment] = useState(false); const [zoomedImage, setZoomedImage] = useState(null); if (!order) return null; const orderId = String(order.id || ''); const orderStatus = String(order.status || ''); const isPendingPayment = orderStatus === 'pending_payment'; const getProductName = (p: Record | undefined) => String(p?.nameFa || p?.name || p?.nameEn || 'محصول کنینا'); const getProductImage = (p: Record | undefined) => String(p?.imageUrl || p?.image || '/products/product-placeholder.png'); const displayTrackingCode = String( order.trackingNumber || (typeof order.id === 'string' ? order.id.substring(0, 8) : '') || 'CN-0000' ); const shippingAddress = (order.shippingAddress || order.address || {}) as Record; const rawDate = order.date || order.createdAt; const orderDate = rawDate ? new Date(String(rawDate)) : new Date(); const formattedDate = orderDate.toLocaleDateString("fa-IR"); const formattedTime = orderDate.toLocaleTimeString("fa-IR", { hour: '2-digit', minute: '2-digit' }); const items = Array.isArray(order.items) ? (order.items as Record[]) : Array.isArray(order.orderItems) ? (order.orderItems as Record[]) : []; const itemsSubtotal = items.reduce((sum: number, item: Record) => { const prod = item.product as Record | undefined; const price = Number(prod?.priceValue || item.priceValue || 0); return sum + price * Number(item.quantity || 1); }, 0); const charityAmount = Number(order.charityDonation || 0); const totalAmount = Number(order.total || order.totalAmount || itemsSubtotal + charityAmount); const isRefill = Boolean(order.isRefill); const getPaymentMethodTitle = (method?: unknown) => { const m = String(method || ''); if (m === 'wallet') return 'کیف پول الکترونیک کنینا'; if (m === 'card' || m === 'card_to_card') return 'کارت به کارت مستقیم'; return 'درگاه پرداخت اینترنتی زیبال (شتاب)'; }; const handlePrint = () => { const printWindow = window.open('', '_blank'); if (!printWindow) return; const itemsHtml = items .map((item: Record) => { const prod = item.product as Record | undefined; const pName = getProductName(prod); const pImg = getProductImage(prod); const pPrice = Number(prod?.priceValue || item.priceValue || 0); const rowTotal = pPrice * Number(item.quantity || 1); return `
${pName} ${pName}
${toPersian( Number(item.quantity || 1) )} ${toPersian( pPrice.toLocaleString() )} تومان ${toPersian( rowTotal.toLocaleString() )} تومان `; }) .join(''); printWindow.document.write(` فاکتور رسمی کنینا - ${displayTrackingCode}
Canina Iran

صورتحساب فروش کالا و خدمات

شناسه فاکتور: ${toPersian( displayTrackingCode )}
اطلاعات سفارش:
تاریخ ثبت: ${toPersian(formattedDate)} - ساعت ${toPersian( formattedTime )}
روش پرداخت: ${getPaymentMethodTitle(order.paymentMethod)}
وضعیت: ${getStatusLabel(orderStatus)}
نشانی تحویل گیرنده:
${ String(order.shippingAddress || 'آدرس ثبتی کاربر در حساب کاربری') }
${itemsHtml}
شرح کالا / مکمل دارویی تعداد مبلغ واحد مبلغ کل
جمع اقلام: ${toPersian(itemsSubtotal.toLocaleString())} تومان
${ charityAmount > 0 ? `
کمک به حیوانات بی‌سرپرست (ردپای مهربانی): ${toPersian(charityAmount.toLocaleString())}+ تومان
` : '' }
هزینه بسته‌بندی و ارسال اکسپرس: رایگان (تحویل سراسری)
مبلغ نهایی فاکتور: ${toPersian(totalAmount.toLocaleString())} تومان
`); printWindow.document.close(); }; const handleExecuteRetryPayment = async () => { try { setIsProcessingPayment(true); const res = await api.post(`/orders/${orderId}/retry-payment`, { paymentMethod: selectedMethod, }); if (res.data?.success) { if (selectedMethod === 'online') { // Initiate Zibal Payment const payRes = await api.post('/payment/zibal/initiate', { orderId, }); if (payRes.data?.paymentUrl) { toast.success('در حال انتقال به درگاه پرداخت زیبال...'); window.location.href = payRes.data.paymentUrl; return; } } else if (selectedMethod === 'wallet') { toast.success('پرداخت سفارش با موفقیت از طریق کیف پول انجام شد.'); if (onOrderUpdated) { onOrderUpdated(orderId, 'processing'); } setRetryModalOpen(false); onClose(); } else { toast.success('روش پرداخت به کارت به کارت تغییر یافت.'); if (onOrderUpdated) { onOrderUpdated(orderId, 'pending_payment'); } setRetryModalOpen(false); } } } catch (err: any) { console.error('Retry payment error:', err); } finally { setIsProcessingPayment(false); } }; function getStatusIcon(st: string) { switch (st) { case 'processing': return ; case 'packaged': case 'ready_to_ship': return ; case 'shipped': return ; case 'delivered': return ; case 'pending_payment': return ; case 'cancelled': return ; default: return ; } } function getStatusLabel(st: string) { switch (st) { case 'processing': return 'در حال پردازش در انبار'; case 'packaged': case 'ready_to_ship': return 'بسته‌بندی شده (آماده ارسال)'; case 'shipped': return 'تحویل شرکت پست / پیک'; case 'delivered': return 'تحویل موفق به مشتری'; case 'pending_payment': return 'در انتظار پرداخت / ناموفق'; case 'cancelled': return 'سفارش لغو شده'; default: return 'ثبت اولیه'; } } return ( {isOpen && (
{/* Modal Header */}

جزئیات کامل سفارش {toPersian(displayTrackingCode)}

ثبت شده در تاریخ {toPersian(formattedDate)}

{/* Pending Payment Notice Banner */} {isPendingPayment && (
پرداخت این سفارش هنوز تکمیل نشده است. می‌توانید همین حالا روش پرداخت را تغییر داده یا مجدداً پرداخت را انجام دهید.
)} {/* Content Scrollable */}
{/* Summary Stats */}
وضعیت سفارش
{getStatusIcon(orderStatus)} {getStatusLabel(orderStatus)}

سبد اقلام سفارش

{items.map((item: Record, idx: number) => { const prod = item.product as Record | undefined; const pName = getProductName(prod); const pImg = getProductImage(prod); const pPrice = Number(prod?.priceValue || item.priceValue || 0); const itemQty = Number(item.quantity || 1); const pSlug = String(prod?.slug || prod?.id || ''); return (
setZoomedImage(pImg)} className="w-14 h-14 bg-medical-gray-50 rounded-xl p-1 flex items-center justify-center shrink-0 border border-medical-gray-200 cursor-zoom-in hover:scale-105 transition-transform overflow-hidden" title="مشاهده تصویر بزرگ" >
{pSlug ? ( {pName} ) : (
{pName}
)}

{toPersian(itemQty)} عدد × {toPersian(pPrice.toLocaleString())} تومان

{toPersian((pPrice * itemQty).toLocaleString())} تومان
); })}
{/* Shipping & Payment */}

اطلاعات تحویل و آدرس

گیرنده: {String(shippingAddress.recipientName || shippingAddress.name || 'کاربر')}
شماره تماس: {toPersian(String(shippingAddress.phone || shippingAddress.mobile || '-'))}
نشانی کامل: {String(shippingAddress.fullAddress || shippingAddress.address || '-')}
{Boolean(shippingAddress.postalCode) && (
کد پستی: {toPersian(String(shippingAddress.postalCode))}
)}

اطلاعات و وضعیت پرداخت

شیوه پرداخت: {getPaymentMethodTitle(order.paymentMethod)}
مجموع اقلام: {toPersian(itemsSubtotal.toLocaleString())} تومان
{charityAmount > 0 && (
ردپای مهربانی: {toPersian(charityAmount.toLocaleString())}+ تومان
)}
هزینه ارسال: رایگان
مبلغ نهایی فاکتور: {toPersian(totalAmount.toLocaleString())} تومان
{/* Footer Actions */}
{isPendingPayment && ( )}
{/* Retry Payment Modal */} {retryModalOpen && (

انتخاب روش پرداخت سفارش

{isCardToCardEnabled && ( )}
)} {/* Image Zoom Modal */} {zoomedImage && (
setZoomedImage(null)} >
)}
)}
); }