import { useState, useEffect, useCallback } from "react" import { useSession } from "next-auth/react" import { useRouter } from "next/navigation" import { notifications } from "@/lib/notifications" import { useProfileImageContext } from "@/contexts/ProfileImageContext" import { validateMedicalInfo } from "@/components/account/MedicalInfoSection" interface FormData { name: string lastname: string email: string identificacion?: string currentPassword: string newPassword: string confirmPassword: string phone?: string dateOfBirth?: string gender?: string address?: string emergencyContact?: string medicalHistory?: string allergies?: string currentMedications?: string } export function useAccountForm() { const { data: session, update } = useSession() const router = useRouter() const { updateProfileImage } = useProfileImageContext() const [formData, setFormData] = useState({ name: "", lastname: "", email: "", currentPassword: "", newPassword: "", confirmPassword: "", phone: "", dateOfBirth: "", gender: "", address: "", emergencyContact: "", medicalHistory: "", allergies: "", currentMedications: "" }) const [loading, setLoading] = useState(false) const [profileImage, setProfileImage] = useState(null) const [imageFile, setImageFile] = useState(null) const [loadingImage, setLoadingImage] = useState(false) const [imageLoaded, setImageLoaded] = useState(false) const [isUpdating, setIsUpdating] = useState(false) // Flag para prevenir race conditions const loadProfileImage = useCallback(async () => { if (!session?.user?.id || imageLoaded) return setLoadingImage(true) try { const response = await fetch("/api/account/profile-image", { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) if (response.ok) { const data = await response.json() setProfileImage(data.profileImage) } else { console.log(`Error HTTP: ${response.status}`) setProfileImage(null) } } catch (error) { console.error("Error cargando imagen de perfil:", error) setProfileImage(null) } finally { setLoadingImage(false) setImageLoaded(true) } }, [session?.user?.id, imageLoaded]) // Cargar datos del usuario cuando la sesión esté disponible useEffect(() => { // No actualizar formData si estamos en medio de una actualización manual if (session?.user && !isUpdating) { setFormData(prev => ({ ...prev, name: session.user.name || "", lastname: session.user.lastname || "", email: session.user.email || "", identificacion: session.user.identificacion || "", phone: session.user.phone || "", dateOfBirth: session.user.dateOfBirth ? new Date(session.user.dateOfBirth).toISOString().split('T')[0] : "", gender: session.user.gender || "", address: session.user.address || "", emergencyContact: session.user.emergencyContact || "", medicalHistory: session.user.medicalHistory || "", allergies: session.user.allergies || "", currentMedications: session.user.currentMedications || "" })) } }, [session, isUpdating]) // Cargar imagen de perfil cuando el usuario esté autenticado useEffect(() => { if (session?.user?.id && !imageLoaded) { loadProfileImage() } }, [session?.user?.id, imageLoaded, loadProfileImage]) const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target setFormData(prev => ({ ...prev, [name]: value })) } const handleImageChange = (file: File | null) => { setImageFile(file) if (file) { // Crear preview const reader = new FileReader() reader.onload = (e) => { setProfileImage(e.target?.result as string) } reader.readAsDataURL(file) } else { setImageLoaded(false) } } const handleImageRemove = async () => { if (!profileImage) return setLoadingImage(true) try { const response = await fetch("/api/account/profile-image", { method: 'DELETE', headers: { 'Content-Type': 'application/json', }, }) if (response.ok) { setProfileImage(null) setImageFile(null) setImageLoaded(false) // Actualizar el contexto global updateProfileImage(null) // Actualizar la sesión await update({ profileImage: null }) notifications.profile.imageRemoved() } else { const data = await response.json() notifications.profile.imageRemoveError(data.error) } } catch (error) { console.error("Error eliminando imagen:", error) notifications.profile.imageRemoveError() } finally { setLoadingImage(false) } } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setLoading(true) setIsUpdating(true) // Activar flag para prevenir race condition try { // Validar información médica const medicalValidation = validateMedicalInfo({ phone: formData.phone, gender: formData.gender, address: formData.address, emergencyContact: formData.emergencyContact, medicalHistory: formData.medicalHistory, allergies: formData.allergies, currentMedications: formData.currentMedications }) if (!medicalValidation.isValid) { const errorMessages = Object.values(medicalValidation.errors).join(', ') notifications.profile.updateError(`Errores de validación: ${errorMessages}`) setLoading(false) return } // Validaciones de contraseña if (formData.newPassword && formData.newPassword !== formData.confirmPassword) { notifications.auth.passwordMismatch() setLoading(false) return } if (formData.newPassword && formData.newPassword.length < 6) { notifications.auth.passwordTooShort() setLoading(false) return } const formDataToSend = new FormData() formDataToSend.append('name', formData.name) formDataToSend.append('lastname', formData.lastname) formDataToSend.append('email', formData.email) if (formData.currentPassword) { formDataToSend.append('currentPassword', formData.currentPassword) } if (formData.newPassword) { formDataToSend.append('newPassword', formData.newPassword) } // Agregar campos médicos y personales if (formData.phone) { formDataToSend.append('phone', formData.phone) } // dateOfBirth NO se envía - es provisto por la API UTB y no es editable if (formData.gender) { formDataToSend.append('gender', formData.gender) } if (formData.address) { formDataToSend.append('address', formData.address) } if (formData.emergencyContact) { formDataToSend.append('emergencyContact', formData.emergencyContact) } if (formData.medicalHistory) { formDataToSend.append('medicalHistory', formData.medicalHistory) } if (formData.allergies) { formDataToSend.append('allergies', formData.allergies) } if (formData.currentMedications) { formDataToSend.append('currentMedications', formData.currentMedications) } if (imageFile) { formDataToSend.append('profileImage', imageFile) } const response = await fetch("/api/account/update", { method: "POST", body: formDataToSend }) const data = await response.json() if (response.ok) { notifications.profile.updated() // Actualizar formData local con los datos guardados setFormData(prev => ({ ...prev, name: data.user.name || "", lastname: data.user.lastname || "", email: data.user.email || "", phone: data.user.phone || "", dateOfBirth: data.user.dateOfBirth ? new Date(data.user.dateOfBirth).toISOString().split('T')[0] : "", gender: data.user.gender || "", address: data.user.address || "", emergencyContact: data.user.emergencyContact || "", medicalHistory: data.user.medicalHistory || "", allergies: data.user.allergies || "", currentMedications: data.user.currentMedications || "", // Limpiar contraseñas currentPassword: "", newPassword: "", confirmPassword: "" })) // Actualizar la sesión de NextAuth con todos los datos nuevos await update({ name: data.user.name, lastname: data.user.lastname, email: data.user.email, profileImage: data.user.profileImage, phone: data.user.phone, dateOfBirth: data.user.dateOfBirth, gender: data.user.gender, address: data.user.address, emergencyContact: data.user.emergencyContact, medicalHistory: data.user.medicalHistory, allergies: data.user.allergies, currentMedications: data.user.currentMedications }) // Actualizar la imagen de perfil en el contexto global if (data.user.profileImage) { updateProfileImage(data.user.profileImage) } // Recargar imagen de perfil si se actualizó if (imageFile) { setImageLoaded(false) setTimeout(() => { loadProfileImage() }, 500) } // Desactivar flag después de que la sesión se haya actualizado setTimeout(() => { setIsUpdating(false) }, 500) } else { notifications.profile.updateError(data.error) setIsUpdating(false) } } catch (error) { console.error("Error updating profile:", error) notifications.profile.updateError() setIsUpdating(false) } finally { setLoading(false) } } return { formData, loading, profileImage, loadingImage, imageLoaded, handleInputChange, handleImageChange, handleImageRemove, handleSubmit, loadProfileImage } }