"use client"; import React, { useState, useMemo, useEffect } from "react"; import { Product } from "../lib/data/products"; import { productService } from "../lib/services/productService"; import { isSpeciesCompatible, matchesMedicalSymptom } from "../lib/petCompatibility"; import { motion, AnimatePresence } from "motion/react"; import { PetProfileSkeleton } from "./Skeleton"; import SafeImage from "./SafeImage"; import { Dog, Cat, ChevronRight, ChevronLeft, Heart, Activity, Weight, Calendar, ShieldCheck, Stethoscope, Plus, Clock, ClipboardList, Package, Star, Edit3, Trash2, AlertTriangle, TrendingUp, Check } from "lucide-react"; import { usePetStore, PetProfile as GlobalPetProfile, Reminder, HealthLog } from "../lib/store/usePetStore"; import { useCartStore } from "../lib/store/cartStore"; import SmartAdvisor from "./SmartAdvisor"; import OrderDetailsModal from "./OrderDetailsModal"; import { toast } from "sonner"; import { toPersian, cn } from "../lib/utils"; import api, { BASE_DOMAIN } from "../lib/services/api"; import { useRouter, useSearchParams } from 'next/navigation'; export default function PetProfile({ initialView, advisorNeed, embedded = false }: { initialView?: "index" | "detail" | "add" | "edit", advisorNeed?: string | null, embedded?: boolean }) { const router = useRouter(); const searchParams = useSearchParams(); const { pets, addPet, removePet, setActivePet, getActivePet, updatePet, addReminder, toggleReminder, addHealthLog } = usePetStore(); const { orders } = useCartStore(); const activePet = getActivePet(); const [isLoading, setIsLoading] = useState(true); const [products, setProducts] = useState([]); const [prescriptions, setPrescriptions] = useState([]); const [selectedInvoiceOrder, setSelectedInvoiceOrder] = useState(null); useEffect(() => { productService.getProducts({ limit: 999 }) .then(res => setProducts(res.data)) .catch(err => console.error("Error fetching products in PetProfile:", err)); if (typeof window !== 'undefined' && localStorage.getItem('accessToken')) { api.get("/prescriptions") .then(res => { const data = Array.isArray(res.data) ? res.data : (res.data?.data || []); setPrescriptions(data); }) .catch(() => {}); } }, []); useEffect(() => { const timer = setTimeout(() => setIsLoading(false), 800); return () => clearTimeout(timer); }, []); const [view, setView] = useState<"index" | "detail" | "add" | "edit">(initialView || (pets.length > 0 ? "index" : "add")); useEffect(() => { if (initialView) { Promise.resolve().then(() => setView(initialView)); } }, [initialView]); const [uploadProgress, setUploadProgress] = useState(null); const [activePetTab, setActivePetTab] = useState<"health" | "orders" | "prescriptions">("health"); // URL query param retention for pet and tab useEffect(() => { const petParam = searchParams.get('pet'); if (petParam && pets.length > 0) { const matchedPet = pets.find(p => p.id === petParam || p.name === petParam); if (matchedPet && matchedPet.id !== activePet?.id) { setActivePet(matchedPet.id); } } }, [searchParams, pets, activePet?.id, setActivePet]); // URL query param retention for tab useEffect(() => { const tabParam = searchParams.get('tab'); if (tabParam && ['health', 'orders', 'prescriptions'].includes(tabParam)) { setActivePetTab(tabParam as "health" | "orders" | "prescriptions"); } }, [searchParams]); const [petToDelete, setPetToDelete] = useState(null); // Modal states const [isAddingReminder, setIsAddingReminder] = useState(false); const [isAddingHealthLog, setIsAddingHealthLog] = useState(false); // New Reminder form state const [reminderForm, setReminderForm] = useState>({ title: "", time: "08:00", frequency: "روزانه", productId: "" }); // Health log form state const [logForm, setLogForm] = useState>({ appetite: "عالی", energy: "نرمال", digestion: "نرمال", note: "" }); const petOrders = useMemo(() => { if (!activePet) return []; return orders.filter(o => o.petId === activePet.id); }, [activePet, orders]); const petPrescriptions = useMemo(() => { if (!activePet) return []; return prescriptions.filter(rx => rx.petId === activePet.id || rx.pet?.id === activePet.id || rx.petName === activePet.name); }, [activePet, prescriptions]); const petCharityTotal = useMemo(() => { return petOrders.reduce((sum, o) => sum + (Number(o.charityDonation) || 0), 0); }, [petOrders]); const allCharityTotal = useMemo(() => { return orders.reduce((sum, o) => sum + (Number(o.charityDonation) || 0), 0); }, [orders]); const [step, setStep] = useState(1); const [formData, setFormData] = useState>({ name: "", type: "سگ", breed: "", age: 0, weight: 0, activityLevel: "متوسط", medicalConditions: [], reminders: [], logs: [], consumptions: [] }); const recommendedProducts = useMemo(() => { if (!activePet || products.length === 0) return []; const picks: { product: Product, reason?: string }[] = []; // Priority 1: Match activePet.medicalConditions directly against product.symptoms if (activePet.medicalConditions && activePet.medicalConditions.length > 0) { products.forEach(p => { if (!isSpeciesCompatible(p.suitableFor, activePet.type)) return; const matchedCondition = matchesMedicalSymptom(activePet.medicalConditions, p.symptoms, p.benefits); if (matchedCondition && !picks.some(x => x.product.id === p.id)) { picks.push({ product: p, reason: `پیشنهاد هوشمند برای تسکین ${matchedCondition}` }); } }); } // Priority 2: Biological & Life-stage factors if (activePet.age >= 7) { const seniorSupplements = products.filter(p => (p.id === "herz-vital" || p.slug?.includes("herz") || p.name.includes("قلب") || p.benefits?.includes("مسن")) && isSpeciesCompatible(p.suitableFor, activePet.type) ); seniorSupplements.forEach(p => { if (!picks.some(x => x.product.id === p.id)) { picks.push({ product: p, reason: "محافظت از قلب و مفاصل در سنین بالا" }); } }); } else if (activePet.age > 0 && activePet.age <= 1) { const growthSupplements = products.filter(p => (p.name.includes("رشد") || p.benefits?.includes("تغذیه توله") || p.benefits?.includes("کلسیم")) && isSpeciesCompatible(p.suitableFor, activePet.type) ); growthSupplements.forEach(p => { if (!picks.some(x => x.product.id === p.id)) { picks.push({ product: p, reason: "تغذیه متوازن و تقویت اسکلت در دوره رشد" }); } }); } if (activePet.activityLevel === "زیاد") { const performanceSupplements = products.filter(p => (p.name.includes("انرژی") || p.benefits?.includes("عضله") || p.benefits?.includes("مفصل")) && isSpeciesCompatible(p.suitableFor, activePet.type) ); performanceSupplements.forEach(p => { if (!picks.some(x => x.product.id === p.id)) { picks.push({ product: p, reason: "تقویت مفاصل و ریکاوری برای سطح فعالیت بالا" }); } }); } return picks; }, [activePet, products]); const handleNext = () => setStep(s => s + 1); const handleBackStep = () => setStep(s => s - 1); const handleSubmit = () => { const cleanedConditions = (formData.medicalConditions || []).filter(c => !c.includes("هیچ‌کدام")); const cleanedData = { ...formData, medicalConditions: cleanedConditions }; if (view === "edit" && activePet) { updatePet(activePet.id, cleanedData); toast.success("اطلاعات شناسنامه با موفقیت بروزرسانی شد"); setView("detail"); } else { addPet(cleanedData); toast.success("شناسنامه جدید با موفقیت صادر شد"); setView("detail"); } setStep(1); }; const handleHealthLogSubmit = () => { if (activePet) { addHealthLog(activePet.id, logForm); toast.success("گزارش سلامت با موفقیت ثبت شد"); setIsAddingHealthLog(false); setLogForm({ appetite: "عالی", energy: "نرمال", digestion: "نرمال", note: "" }); } }; const handleReminderSubmit = () => { if (activePet) { if (!reminderForm.title) { toast.error("لطفاً عنوان یادآور را وارد کنید"); return; } addReminder(activePet.id, reminderForm); toast.success("یادآور با موفقیت ثبت شد"); setIsAddingReminder(false); setReminderForm({ title: "", time: "08:00", frequency: "روزانه", productId: "" }); } }; const handleToggleReminder = (reminder: Reminder) => { if (activePet) { const today = new Date().toISOString().split('T')[0]; toggleReminder(activePet.id, reminder.id, today); const isCompleting = !reminder.completedDates.includes(today); if (isCompleting) { toast.success(`دوز ${reminder.title} تایید شد`); } } }; const startEdit = () => { if (activePet) { setFormData({ name: activePet.name, type: activePet.type, breed: activePet.breed, age: activePet.age, weight: activePet.weight, activityLevel: activePet.activityLevel, medicalConditions: activePet.medicalConditions, reminders: activePet.reminders || [], logs: activePet.logs || [], consumptions: activePet.consumptions || [] }); setView("edit"); setStep(1); } }; const confirmDelete = (pet: GlobalPetProfile) => { setPetToDelete(pet); }; const handlePetDelete = () => { if (petToDelete) { removePet(petToDelete.id); toast.error(`شناسنامه ${petToDelete.name} حذف شد`); setPetToDelete(null); if (pets.length <= 1) { setView("add"); } else { setView("index"); } } }; if (isLoading && view === "detail" && activePet) { return (
); } // 1. Pet Index Page if (view === "index") { return (

همدم‌های من

مدیریت شناسنامه‌های سلامت و سوابق درمانی

{pets.map(pet => (
{pet.type === "سگ" ? : }

{pet.name}

{pet.breed}

وزن {toPersian(pet.weight)} کیلوگرم
سن {toPersian(pet.age)} سال
))}
{/* Delete Confirmation Modal */} {petToDelete && (
setPetToDelete(null)} />

حذف شناسنامه {petToDelete.name}؟

آیا از حذف شناسنامه {petToDelete.name} اطمینان دارید؟ این عمل غیرقابل بازگشت است و تمام سوابق سلامت او حذف خواهد شد.

)}
); } // 2. Add / Edit Pet Steps if (view === "add" || view === "edit") { if (view === "add" && pets.length === 0) { return (
{/* Render SmartAdvisor directly without redundant top banner */} { const newPet = { ...data, id: Date.now().toString(), reminders: [], logs: [], consumptions: [] } as unknown as GlobalPetProfile; addPet(newPet); setActivePet(newPet.id); toast.success(`شناسنامه سلامت ${data.name} با موفقیت صادر شد`); setView("detail"); }} />
); } return (
{/* Progress Bar */}

{view === "edit" ? "ویرایش شناسنامه" : "صدور شناسنامه سلامت"}

مرحله {toPersian(step)} از {toPersian(3)}: بروزرسانی اطلاعات تخصصی

{step === 1 && (
setFormData({ ...formData, name: e.target.value })} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg" placeholder="مثلاً: لوسی" />
setFormData({ ...formData, breed: e.target.value })} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-bold" placeholder="آلمانی، پرشین، میکس و..." />
{/* Photo preview container */}
{formData.imageUrl ? ( ) : ( )} {uploadProgress !== null && (
{toPersian(uploadProgress)}%
)}
setFormData({ ...formData, imageUrl: e.target.value })} className="flex-1 bg-white border border-medical-gray-200 rounded-xl py-2.5 px-3 focus:ring-2 focus:ring-canina-blue/20 outline-none text-xs font-mono" placeholder="آدرس اینترنتی تصویر..." />

فرمت‌های مجاز: JPG, PNG (حداکثر ۱۰ مگابایت)

)} {step === 2 && (
setFormData({ ...formData, age: parseInt(e.target.value) })} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg" placeholder="۳" />
setFormData({ ...formData, weight: parseFloat(e.target.value) })} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-6 pl-12 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg" />
{["کم", "متوسط", "زیاد"].map(level => ( ))}
)} {step === 3 && (
{[ "هیچ‌کدام (سلامت کامل و بدون سابقه بیماری)", "جراحی مفاصل", "زایمان اخیر", "بارداری", "مشکلات گوارشی", "ریزش موی شدید", "بی‌اشتهایی" ].map(condition => { const isNone = condition.includes("هیچ‌کدام"); const isSelected = isNone ? (formData.medicalConditions.length === 0 || formData.medicalConditions.includes(condition)) : formData.medicalConditions.includes(condition); return ( ); })}