'use client'; import { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import toast, { Toaster } from 'react-hot-toast'; import Link from 'next/link'; import { useParams, useRouter } from 'next/navigation'; import { MapPin, Bed, Bath, Square, DollarSign, Heart, Share2, Phone, Mail, MessageCircle, Calendar, Shield, Star, ChevronLeft, ChevronRight, Check, X, Wifi, Car, Wind, Camera, Home, Building2, Users, Clock, FileText, LogIn, Loader2, ArrowLeft, ImageIcon, ChevronDown } from 'lucide-react'; import { getRentProperty, getSaleProperty, getSalePropertyById, bookReservation, getAvailableDateRanges, getOwnerContactInformation } from '../../utils/api'; import AuthService from '../../services/AuthService'; import { useFavorites } from '@/app/contexts/FavoritesContext'; import { BuildingTypeKeys, PropertyStatusKeys, extractCity } from '../../enums'; import PropertyRatingList from '@/app/components/ratings/PropertyRatingList'; import PropertyRatingForm from '@/app/components/ratings/PropertyRatingForm'; import StarRating from '@/app/components/ratings/StarRating'; import { getPropertyAverageRating } from '../../utils/ratings'; import dynamic from 'next/dynamic'; import 'leaflet/dist/leaflet.css'; const MapContainer = dynamic(() => import('react-leaflet').then(m => m.MapContainer), { ssr: false }); const TileLayer = dynamic(() => import('react-leaflet').then(m => m.TileLayer), { ssr: false }); const Marker = dynamic(() => import('react-leaflet').then(m => m.Marker), { ssr: false }); const Popup = dynamic(() => import('react-leaflet').then(m => m.Popup), { ssr: false }); function formatCurrency(amount) { if (!amount || isNaN(amount)) return '0'; return Number(amount).toLocaleString('ar-SA'); } function buildImageUrl(img) { if (!img) return ''; const apiBase = typeof window !== 'undefined' ? (process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api') : ''; if (img.startsWith('http')) return img; return `${apiBase}${img.startsWith('/') ? '' : '/Pictures/'}${img}`; } function mapApiDetail(item) { if (!item) return null; const info = item.propertyInformation || {}; const details = (() => { try { return JSON.parse(info.detailsJSON || '{}'); } catch { return {}; } })(); const isRent = item.dailyRent != null || item.monthlyRent != null; const dailyPrice = item.dailyRent || 0; const monthlyPrice = item.monthlyRent || 0; const salePrice = item.price || 0; const price = isRent ? (monthlyPrice || dailyPrice) : salePrice; const priceUnit = isRent ? (monthlyPrice ? 'monthly' : 'daily') : 'sale'; const propType = BuildingTypeKeys[info.buildingType] ?? BuildingTypeKeys[item.type] ?? 'apartment'; const typeLabel = { apartment: 'شقة', villa: 'فيلا', house: 'بيت', sweet: 'سويت', studio: 'استوديو', office: 'مكتب', shop: 'متجر', warehouse: 'مستودع', farms: 'مزرعة', room: 'غرفة' }[propType] || 'عقار'; const status = PropertyStatusKeys[info.status] ?? PropertyStatusKeys[item.status] ?? 'available'; const statusLabel = { available: 'متاح', booked: 'محجوز', maintenance: 'صيانة', not_available: 'غير متاح' }[status] || 'متاح'; const rawImages = Array.isArray(info.images) ? info.images : []; const images = rawImages.length > 0 ? rawImages.map(buildImageUrl) : []; const services = details.services || {}; const terms = details.terms || {}; return { id: item.id, title: info.address || `عقار #${item.id}`, description: info.description || '', type: propType, typeLabel, price, priceUnit, priceDisplay: { daily: dailyPrice, monthly: monthlyPrice, sale: salePrice }, isRent, location: { city: extractCity(info.address) || 'دمشق', address: info.address || '', lat: parseFloat(info.cordsX) || 0, lng: parseFloat(info.cordsY) || 0, }, bedrooms: info.numberOfBedRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, images, status, statusLabel, services, terms, details, deposit: item.deposit || 0, currencyId: item.currencyId, isSmokeAllow: item.isSmokeAllow, isVisitorAllow: item.isVisitorAllow, specializedFor: item.specializedFor, _raw: item, }; } export default function PropertyDetailsPage() { const params = useParams(); const router = useRouter(); const { isFavorite, addFavorite, removeFavorite } = useFavorites(); const [property, setProperty] = useState(null); const [loading, setLoading] = useState(true); const [currentImage, setCurrentImage] = useState(0); const [showLoginDialog, setShowLoginDialog] = useState(false); const [bookingDates, setBookingDates] = useState({ start: '', end: '' }); const [bookingLoading, setBookingLoading] = useState(false); const [bookingError, setBookingError] = useState(null); const [bookingSuccess, setBookingSuccess] = useState(false); const [availableRanges, setAvailableRanges] = useState([]); const [favLoading, setFavLoading] = useState(false); const [avgRating, setAvgRating] = useState(null); const [showRatingForm, setShowRatingForm] = useState(false); const [showContact, setShowContact] = useState(false); const [contactInfo, setContactInfo] = useState(null); const [ownerData, setOwnerData] = useState(null); useEffect(() => { const id = params.id; if (!id) return; setLoading(true); async function fetchProperty() { try { let data = null; try { data = await getRentProperty(id); } catch {} if (!data) { try { data = await getSalePropertyById(id) || await getSaleProperty(id); } catch {} } if (!data) { try { data = await getSaleProperty(id); } catch {} } if (data) { const mapped = mapApiDetail(data); setProperty(mapped); if (mapped) fetchAvgRating(mapped.id); } } catch (err) { console.error('[PropertyDetail] Failed:', err); } finally { setLoading(false); } } fetchProperty(); }, [params.id]); const fetchAvgRating = async (propId) => { try { const avg = await getPropertyAverageRating(propId); setAvgRating(avg); } catch {} }; const fetchContactInfo = async () => { if (!property) return; try { const info = await getOwnerContactInformation(property._raw?.propertyInformationId || property.id); setContactInfo(info); setShowContact(true); } catch (err) { toast.error('فشل تحميل معلومات الاتصال'); } }; const handleFavorite = async () => { if (!AuthService.isAuthenticated()) { setShowLoginDialog(true); return; } if (!property) return; setFavLoading(true); try { if (isFavorite(property.id)) { await removeFavorite(property.id); } else { await addFavorite(property.id); } } catch (err) { toast.error('حدث خطأ'); } finally { setFavLoading(false); } }; const handleBookNow = async () => { if (!AuthService.isAuthenticated()) { setShowLoginDialog(true); return; } if (!bookingDates.start || !bookingDates.end) { setBookingError('يرجى تحديد تاريخ البداية والنهاية'); return; } setBookingLoading(true); setBookingError(null); try { await bookReservation(property._raw?.propertyInformationId || property.id, bookingDates.start, bookingDates.end); setBookingSuccess(true); toast.success('تم إرسال طلب الحجز بنجاح'); } catch (err) { setBookingError(err.message || 'فشل الحجز'); } finally { setBookingLoading(false); } }; const handleRatingSuccess = () => { setShowRatingForm(false); if (property) fetchAvgRating(property.id); }; if (loading) { return (
جاري تحميل العقار...
لم يتم العثور على العقار المطلوب
{property.description}
شارك تجربتك مع المستأجرين الآخرين
سيتم مراجعة طلبك من قبل المالك
للحجز أو إضافة المفضلة، سجل دخولك.
تسجيل الدخول إنشاء حساب