class ModernNotificationManager{constructor(){this.notificationToggle=document.getElementById('notificationToggle');this.notificationDropdown=document.getElementById('notificationDropdown');this.notificationBadge=document.getElementById('notificationBadge');this.notificationList=document.getElementById('notificationList');this.markAllReadBtn=document.getElementById('markAllRead');this.isOpen=false;this.notifications=[];this.activeToasts=new Map();this.toastCounter=0;this.csrfToken=this.getCSRFToken();this.init();this.setupGlobalNotificationSystem();} getCSRFToken(){const metaTag=document.querySelector('meta[name="csrf-token"]');return metaTag?metaTag.getAttribute('content'):'';} getAPIHeaders(){const headers={'Content-Type':'application/json',};if(this.csrfToken){headers['X-CSRFToken']=this.csrfToken;} return headers;} init(){if(!this.notificationToggle)return;this.notificationToggle.addEventListener('click',(e)=>{e.stopPropagation();this.toggleDropdown();});if(this.markAllReadBtn){this.markAllReadBtn.addEventListener('click',()=>{this.markAllAsRead();});} document.addEventListener('click',(e)=>{if(!this.notificationDropdown.contains(e.target)&&!this.notificationToggle.contains(e.target)){this.closeDropdown();}});this.loadNotifications();setInterval(()=>{this.loadNotifications();},30000);} toggleDropdown(){if(this.isOpen){this.closeDropdown();}else{this.openDropdown();}} openDropdown(){this.notificationDropdown.classList.remove('hidden');this.notificationToggle.setAttribute('aria-expanded','true');this.isOpen=true;this.notificationDropdown.style.opacity='0';this.notificationDropdown.style.transform='translateY(-10px)';requestAnimationFrame(()=>{this.notificationDropdown.style.transition='opacity 0.2s ease, transform 0.2s ease';this.notificationDropdown.style.opacity='1';this.notificationDropdown.style.transform='translateY(0)';});} closeDropdown(){this.notificationDropdown.style.transition='opacity 0.2s ease, transform 0.2s ease';this.notificationDropdown.style.opacity='0';this.notificationDropdown.style.transform='translateY(-10px)';setTimeout(()=>{this.notificationDropdown.classList.add('hidden');this.notificationToggle.setAttribute('aria-expanded','false');this.isOpen=false;},200);} async loadNotifications(){try{const response=await fetch('/api/notifications');if(response.ok){const data=await response.json();this.notifications=data.notifications||[];this.updateUI();}}catch(error){console.error('Fehler beim Laden der Benachrichtigungen:',error);}} updateUI(){this.updateBadge();this.updateNotificationList();} updateBadge(){const unreadCount=this.notifications.filter(n=>!n.read).length;if(unreadCount>0){this.notificationBadge.textContent=unreadCount>99?'99+':unreadCount.toString();this.notificationBadge.classList.remove('hidden');}else{this.notificationBadge.classList.add('hidden');}} updateNotificationList(){if(this.notifications.length===0){this.notificationList.innerHTML=`
Keine neuen Benachrichtigungen
`;return;} const notificationHTML=this.notifications.map(notification=>{const isUnread=!notification.read;const timeAgo=this.formatTimeAgo(new Date(notification.created_at));return`
${this.getNotificationIcon(notification.type)}

${this.getNotificationTitle(notification.type)}

${isUnread?'
':''}

${this.getNotificationMessage(notification)}

${timeAgo}

`;}).join('');this.notificationList.innerHTML=notificationHTML;this.notificationList.querySelectorAll('.notification-item').forEach(item=>{item.addEventListener('click',(e)=>{const notificationId=item.dataset.notificationId;this.markAsRead(notificationId);});});} getNotificationIcon(type){const icons={'guest_request':`
`,'job_completed':`
`,'system':`
`};return icons[type]||icons['system'];} getNotificationTitle(type){const titles={'guest_request':'Neue Gastanfrage','job_completed':'Druckauftrag abgeschlossen','system':'System-Benachrichtigung'};return titles[type]||'Benachrichtigung';} getNotificationMessage(notification){try{const payload=JSON.parse(notification.payload||'{}');switch(notification.type){case'guest_request':return`${payload.guest_name||'Ein Gast'}hat eine neue Druckanfrage gestellt.`;case'job_completed':return`Der Druckauftrag"${payload.job_name || 'Unbekannt'}"wurde erfolgreich abgeschlossen.`;default:return payload.message||'Neue Benachrichtigung erhalten.';}}catch(error){return'Neue Benachrichtigung erhalten.';}} formatTimeAgo(date){const now=new Date();const diffInSeconds=Math.floor((now-date)/1000);if(diffInSeconds<60){return'Gerade eben';}else if(diffInSeconds<3600){const minutes=Math.floor(diffInSeconds/60);return`vor ${minutes}Minute${minutes!==1?'n':''}`;}else if(diffInSeconds<86400){const hours=Math.floor(diffInSeconds/3600);return`vor ${hours}Stunde${hours!==1?'n':''}`;}else{const days=Math.floor(diffInSeconds/86400);return`vor ${days}Tag${days!==1?'en':''}`;}} async markAsRead(notificationId){try{const response=await fetch(`/api/notifications/${notificationId}/read`,{method:'POST',headers:this.getAPIHeaders()});if(response.ok){const notification=this.notifications.find(n=>n.id==notificationId);if(notification){notification.read=true;this.updateUI();}}else{console.error('Fehler beim Markieren als gelesen:',response.status,response.statusText);}}catch(error){console.error('Fehler beim Markieren als gelesen:',error);}} async markAllAsRead(){try{const response=await fetch('/api/notifications/mark-all-read',{method:'POST',headers:this.getAPIHeaders()});if(response.ok){this.notifications.forEach(notification=>{notification.read=true;});this.updateUI();}else{console.error('Fehler beim Markieren aller als gelesen:',response.status,response.statusText);}}catch(error){console.error('Fehler beim Markieren aller als gelesen:',error);}} setupGlobalNotificationSystem(){window.showFlashMessage=this.showGlassToast.bind(this);window.showToast=this.showGlassToast.bind(this);window.showNotification=this.showGlassToast.bind(this);window.showSuccessMessage=(message)=>this.showGlassToast(message,'success');window.showErrorMessage=(message)=>this.showGlassToast(message,'error');window.showWarningMessage=(message)=>this.showGlassToast(message,'warning');window.showInfoMessage=(message)=>this.showGlassToast(message,'info');} showGlassToast(message,type='info',duration=5000,options={}){if(window.dndManager&&window.dndManager.isEnabled){window.dndManager.suppressNotification(message,type);return;} const toastId=`toast-${++this.toastCounter}`;const toast=document.createElement('div');toast.id=toastId;toast.className=`glass-toast notification notification-${type}show`;const iconMap={success:``,error:``,warning:``,info:``};toast.innerHTML=`
${iconMap[type]||iconMap.info}
${options.title?`
${options.title}
`:''}
${message}
`;let container=document.getElementById('toast-container');if(!container){container=document.createElement('div');container.id='toast-container';container.className='notifications-container';document.body.appendChild(container);} const existingToasts=container.children.length;toast.style.top=`${1+existingToasts*5}rem`;container.appendChild(toast);this.activeToasts.set(toastId,toast);let isPaused=false;let timeoutId;const startTimer=()=>{if(!isPaused&&duration>0){timeoutId=setTimeout(()=>{this.closeToast(toastId);},duration);}};toast.addEventListener('mouseenter',()=>{isPaused=true;clearTimeout(timeoutId);toast.style.transform='translateY(-2px) scale(1.02)';});toast.addEventListener('mouseleave',()=>{isPaused=false;toast.style.transform='translateY(0) scale(1)';startTimer();});setTimeout(startTimer,100);if(options.playSound!==false){this.playNotificationSound(type);} return toastId;} closeToast(toastId){const toast=this.activeToasts.get(toastId);if(!toast)return;toast.classList.add('hiding');setTimeout(()=>{if(toast.parentNode){toast.parentNode.removeChild(toast);} this.activeToasts.delete(toastId);this.repositionToasts();},400);} repositionToasts(){let index=0;this.activeToasts.forEach((toast)=>{if(toast.parentNode){toast.style.top=`${1+index*5}rem`;index++;}});} playNotificationSound(type){try{if(typeof AudioContext!=='undefined'||typeof webkitAudioContext!=='undefined'){const audioContext=new(window.AudioContext||window.webkitAudioContext)();const oscillator=audioContext.createOscillator();const gainNode=audioContext.createGain();oscillator.connect(gainNode);gainNode.connect(audioContext.destination);const frequencies={success:[523.25,659.25,783.99],error:[440,415.3],warning:[493.88,523.25],info:[523.25]};const freq=frequencies[type]||frequencies.info;freq.forEach((f,i)=>{setTimeout(()=>{const osc=audioContext.createOscillator();const gain=audioContext.createGain();osc.connect(gain);gain.connect(audioContext.destination);osc.frequency.setValueAtTime(f,audioContext.currentTime);gain.gain.setValueAtTime(0.1,audioContext.currentTime);gain.gain.exponentialRampToValueAtTime(0.01,audioContext.currentTime+0.1);osc.start(audioContext.currentTime);osc.stop(audioContext.currentTime+0.1);},i*100);});}}catch(error){}} showBrowserNotification(title,message,options={}){if('Notification'in window){if(Notification.permission==='granted'){const notification=new Notification(title,{body:message,icon:options.icon||'/static/icons/static/icons/notification-icon.png',badge:options.badge||'/static/icons/static/icons/badge-icon.png',tag:options.tag||'myp-notification',requireInteraction:options.requireInteraction||false,...options});notification.onclick=options.onClick||(()=>{window.focus();notification.close();});return notification;}else if(Notification.permission==='default'){Notification.requestPermission().then(permission=>{if(permission==='granted'){this.showBrowserNotification(title,message,options);}});}} return null;} showAlert(message,type='info',options={}){const alertId=`alert-${Date.now()}`;const alert=document.createElement('div');alert.id=alertId;alert.className=`alert alert-${type}`;alert.innerHTML=`
${this.getIconForType(type)}
${options.title?`

${options.title}

`:''}

${message}

${options.dismissible!==false?``:''}
`;const container=options.container||document.querySelector('.flash-messages')||document.body;container.appendChild(alert);if(options.autoDismiss!==false){setTimeout(()=>{if(alert.parentNode){alert.style.opacity='0';alert.style.transform='translateY(-20px)';setTimeout(()=>alert.remove(),300);}},options.duration||7000);} return alertId;} getIconForType(type){const icons={success:``,error:``,warning:``,info:``};return icons[type]||icons.info;}} class NotificationManager extends ModernNotificationManager{constructor(){super();console.warn('NotificationManager ist deprecated. Verwenden Sie ModernNotificationManager.');}} const modernNotificationManager=new ModernNotificationManager();if(typeof window!=='undefined'){window.notificationManager=modernNotificationManager;window.modernNotificationManager=modernNotificationManager;} const toastStyles=``;if(typeof document!=='undefined'&&!document.getElementById('toast-styles')){const styleElement=document.createElement('div');styleElement.id='toast-styles';styleElement.innerHTML=toastStyles;document.head.appendChild(styleElement);}