import PropTypes from 'prop-types' import { useState, useEffect, useContext, useRef, useCallback, useMemo, memo } from 'react' import { Button, message, Popover, Typography, Space, Flex } from 'antd' import { UserOutlined } from '@ant-design/icons' import BellIcon from '../../Icons/BellIcon' import MailCheckIcon from '../../Icons/MailCheckIcon' import MailIcon from '../../Icons/MailIcon' import { ApiServerContext } from '../context/ApiServerContext' import { AuthContext } from '../context/AuthContext' import { LoadingOutlined } from '@ant-design/icons' import InfoCircleIcon from '../../Icons/InfoCircleIcon' const { Text } = Typography const UserNotifierToggle = memo(({ type, objectData, size = 'middle', disabled = false, ...buttonProps }) => { const { toggleUserNotifier, editUserNotifier, fetchUserNotifiersForObject, fetchAllUserNotifiersForObject } = useContext(ApiServerContext) const { userProfile, token, authInitialized } = useContext(AuthContext) const [isNotifying, setIsNotifying] = useState(false) const [loading, setLoading] = useState(false) const [initialLoad, setInitialLoad] = useState(true) const [allNotifiers, setAllNotifiers] = useState([]) const [popoverOpen, setPopoverOpen] = useState(false) const [popoverLoading, setPopoverLoading] = useState(false) const [emailTogglingId, setEmailTogglingId] = useState(null) const objectId = objectData?._id const authReady = Boolean(token && authInitialized) const apiRef = useRef({ fetchUserNotifiersForObject, fetchAllUserNotifiersForObject }) apiRef.current = { fetchUserNotifiersForObject, fetchAllUserNotifiersForObject } useEffect(() => { if (!authReady || !objectId || !type) return const loadNotifierState = async () => { setInitialLoad(true) try { const { data } = await apiRef.current.fetchUserNotifiersForObject(objectId, type) setIsNotifying(data?.length > 0) } catch (error) { console.error('Error fetching user notifier state:', error) } finally { setInitialLoad(false) } } loadNotifierState() }, [authReady, objectId, type]) useEffect(() => { if (!authReady || !objectId || !type || !popoverOpen) return const loadAllNotifiers = async () => { setPopoverLoading(true) try { const { data } = await apiRef.current.fetchAllUserNotifiersForObject(objectId, type) setAllNotifiers(data || []) } catch (error) { console.error('Error fetching all user notifiers:', error) setAllNotifiers([]) } finally { setPopoverLoading(false) } } loadAllNotifiers() }, [authReady, objectId, type, popoverOpen]) const handleClick = useCallback(async () => { if (!authReady || !objectId || !type || loading) return setLoading(true) try { const enabled = await toggleUserNotifier(objectId, type) setIsNotifying(enabled) if (popoverOpen) { const { data } = await fetchAllUserNotifiersForObject(objectId, type) setAllNotifiers(data || []) } message.success( enabled ? 'Notifications enabled for this object' : 'Notifications disabled for this object' ) } catch (error) { console.error('Error toggling user notifier:', error) message.error('Failed to update notifications') } finally { setLoading(false) } }, [authReady, objectId, type, loading, popoverOpen, toggleUserNotifier, fetchAllUserNotifiersForObject]) const getUserDisplayName = useCallback((user) => { if (!user) return 'Unknown' return ( user.name || user.username || `${user.firstName || ''} ${user.lastName || ''}`.trim() || user.email || 'Unknown' ) }, []) const isCurrentUser = useCallback((user) => user?._id === userProfile?._id, [userProfile?._id]) const handleEmailToggle = useCallback(async (item) => { if (!isCurrentUser(item.user) || emailTogglingId) return setEmailTogglingId(item._id) const newEmail = !item.email try { const result = await editUserNotifier(item._id, { email: newEmail }) if (result) { setAllNotifiers((prev) => prev.map((n) => n._id === item._id ? { ...n, email: result.email ?? newEmail } : n ) ) message.success( (result.email ?? newEmail) ? 'Email notifications enabled' : 'Email notifications disabled' ) } } catch (error) { console.error('Error toggling email:', error) message.error('Failed to update email notifications') } finally { setEmailTogglingId(null) } }, [isCurrentUser, emailTogglingId, editUserNotifier]) const popoverContent = useMemo( () => ( {popoverLoading ? ( Loading, please wait... ) : allNotifiers.length === 0 ? ( No users subscribed. ) : ( <> {[...allNotifiers] .sort( (a, b) => (isCurrentUser(b.user) ? 1 : 0) - (isCurrentUser(a.user) ? 1 : 0) ) .map((item) => ( {getUserDisplayName(item.user)} {isCurrentUser(item.user) && ( (you) )}