/**
 * NotificationBell Component
 * 
 * Displays a bell icon with unread count badge.
 * Clicking opens a dropdown with recent notifications.
 */

import React, { useState, useEffect, useRef, useCallback } from 'react';
import { FaBell, FaCheck, FaTimes, FaEnvelope, FaCog, FaExclamationTriangle, FaCheckCircle } from 'react-icons/fa';
import { useNotifications, UserNotification } from '../../hooks/useNotifications';
import styles from './NotificationBell.module.css';

import { useLanguage } from '../../providers/language/LanguageContext';

// Icon mapping for notification types
const typeIcons: Record<string, React.ReactNode> = {
  invitation: <FaEnvelope />,
  system: <FaCog />,
  workflow: <FaCog />,
  mention: <FaExclamationTriangle />
};

// Format timestamp to relative time (Unix seconds)
function formatRelativeTime(timestamp: number): string {
  if (!Number.isFinite(timestamp) || timestamp <= 0) {
    return '';
  }
  const now = Date.now() / 1000;
  const diff = now - timestamp;
  
  if (diff < 60) return 'Gerade eben';
  if (diff < 3600) return `vor ${Math.floor(diff / 60)} Min.`;
  if (diff < 86400) return `vor ${Math.floor(diff / 3600)} Std.`;
  if (diff < 604800) return `vor ${Math.floor(diff / 86400)} Tagen`;
  
  const date = new Date(timestamp * 1000);
  if (Number.isNaN(date.getTime())) {
    return '';
  }
  return date.toLocaleDateString('de-DE');
}

interface NotificationBellProps {
  className?: string;
}

export const NotificationBell: React.FC<NotificationBellProps> = ({ className }) => {
  const { t } = useLanguage();
  const {
    notifications,
    unreadCount,
    loading,
    error,
    fetchNotifications,
    markAsRead,
    markAllAsRead,
    executeAction,
    dismissNotification,
    startPolling,
    stopPolling
  } = useNotifications();
  
  const [isOpen, setIsOpen] = useState(false);
  const [actionLoading, setActionLoading] = useState<string | null>(null);
  const [actionSuccess, setActionSuccess] = useState<string | null>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);

  // Start polling on mount
  useEffect(() => {
    startPolling(30000); // Poll every 30 seconds
    return () => stopPolling();
  }, [startPolling, stopPolling]);

  // Fetch notifications when dropdown opens
  useEffect(() => {
    if (isOpen) {
      fetchNotifications({ limit: 10 });
    }
  }, [isOpen, fetchNotifications]);

  // Close dropdown when clicking outside
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    }
    
    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
      return () => document.removeEventListener('mousedown', handleClickOutside);
    }
  }, [isOpen]);

  // Handle action button click
  const handleAction = useCallback(async (
    notification: UserNotification, 
    actionId: string,
    event: React.MouseEvent
  ) => {
    event.stopPropagation();
    setActionLoading(`${notification.id}-${actionId}`);
    
    const result = await executeAction(notification.id, actionId);
    
    setActionLoading(null);
    
    if (result) {
      setActionSuccess(notification.id);
      // Reload sidebar when accepting an invitation (grants new mandate/feature access)
      if (actionId === 'accept' && notification.referenceType === 'Invitation') {
        window.dispatchEvent(new CustomEvent('features-changed'));
      }
      // Clear success state after animation
      setTimeout(() => {
        setActionSuccess(null);
        fetchNotifications({ limit: 10 });
      }, 2000);
    }
  }, [executeAction, fetchNotifications]);

  // Handle dismiss
  const handleDismiss = useCallback(async (
    notification: UserNotification,
    event: React.MouseEvent
  ) => {
    event.stopPropagation();
    await dismissNotification(notification.id);
  }, [dismissNotification]);

  // Handle notification click (mark as read)
  const handleNotificationClick = useCallback(async (notification: UserNotification) => {
    if (notification.status === 'unread') {
      await markAsRead(notification.id);
    }
  }, [markAsRead]);

  // Filter out dismissed notifications
  const visibleNotifications = notifications.filter(n => n.status !== 'dismissed');

  return (
    <div className={`${styles.notificationBell} ${className || ''}`} ref={dropdownRef}>
      {/* Bell Button */}
      <button 
        className={styles.bellButton}
        onClick={() => setIsOpen(!isOpen)}
        aria-label={`Benachrichtigungen ${unreadCount > 0 ? `(${unreadCount} ungelesen)` : ''}`}
      >
        <FaBell className={styles.bellIcon} />
        {unreadCount > 0 && (
          <span className={styles.badge}>
            {unreadCount > 99 ? '99+' : unreadCount}
          </span>
        )}
      </button>

      {/* Dropdown */}
      {isOpen && (
        <div className={styles.dropdown}>
          {/* Header */}
          <div className={styles.header}>
            <h3>{t('notificationBell.benachrichtigungen')}</h3>
            {visibleNotifications.some(n => n.status === 'unread') && (
              <button 
                className={styles.markAllRead}
                onClick={() => markAllAsRead()}
              >
                Alle als gelesen markieren
              </button>
            )}
          </div>

          {/* Content */}
          <div className={styles.content}>
            {loading && visibleNotifications.length === 0 && (
              <div className={styles.loading}>{t('notificationBell.lade')}</div>
            )}
            
            {error && (
              <div className={styles.error}>{error}</div>
            )}
            
            {!loading && !error && visibleNotifications.length === 0 && (
              <div className={styles.empty}>
                <FaBell className={styles.emptyIcon} />
                <p>{t('notificationBell.keineBenachrichtigungen')}</p>
              </div>
            )}

            {visibleNotifications.map(notification => (
              <div 
                key={notification.id}
                className={`
                  ${styles.notification} 
                  ${notification.status === 'unread' ? styles.unread : ''}
                  ${actionSuccess === notification.id ? styles.success : ''}
                `}
                onClick={() => handleNotificationClick(notification)}
              >
                {/* Success overlay */}
                {actionSuccess === notification.id && (
                  <div className={styles.successOverlay}>
                    <FaCheckCircle />
                    <span>{notification.actionResult || 'Erfolgreich'}</span>
                  </div>
                )}
                
                {/* Icon */}
                <div className={`${styles.icon} ${styles[`icon_${notification.type}`]}`}>
                  {typeIcons[notification.type] || <FaBell />}
                </div>
                
                {/* Content */}
                <div className={styles.notificationContent}>
                  <div className={styles.title}>{notification.title}</div>
                  <div className={styles.message}>{notification.message}</div>
                  <div className={styles.time}>{formatRelativeTime(notification.createdAt)}</div>
                  
                  {/* Actions */}
                  {notification.actions && notification.status !== 'actioned' && (
                    <div className={styles.actions}>
                      {notification.actions.map(action => (
                        <button
                          key={action.actionId}
                          className={`${styles.actionButton} ${styles[`action_${action.style}`]}`}
                          onClick={(e) => handleAction(notification, action.actionId, e)}
                          disabled={actionLoading === `${notification.id}-${action.actionId}`}
                        >
                          {actionLoading === `${notification.id}-${action.actionId}` ? (
                            '...'
                          ) : action.actionId === 'accept' ? (
                            <><FaCheck /> {action.label}</>
                          ) : action.actionId === 'decline' ? (
                            <><FaTimes /> {action.label}</>
                          ) : (
                            action.label
                          )}
                        </button>
                      ))}
                    </div>
                  )}
                  
                  {/* Action result */}
                  {notification.actionTaken && (
                    <div className={styles.actionResult}>
                      {notification.actionResult}
                    </div>
                  )}
                </div>
                
                {/* Dismiss button */}
                {notification.status !== 'actioned' && (
                  <button 
                    className={styles.dismissButton}
                    onClick={(e) => handleDismiss(notification, e)}
                    aria-label={t('notificationBell.schliessen')}
                  >
                    <FaTimes />
                  </button>
                )}
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default NotificationBell;
