import React, { useState, useEffect, useRef } from 'react';
import { Bell } from 'lucide-react';
import { toast } from 'react-toastify';
import notificationService, { Notification } from '../services/notificationService';
import { formatDate } from '../../../shared/utils/format';
import useAuthStore from '../../../store/useAuthStore';
import { getUserFriendlyError } from '../../../shared/utils/errorSanitizer';

const InAppNotificationBell: React.FC = () => {
  const { isAuthenticated, token, isLoading } = useAuthStore();
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);
  const [showDropdown, setShowDropdown] = useState(false);
  const [loading, setLoading] = useState(false);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const [isInitialized, setIsInitialized] = useState(false);

  // Wait for auth to initialize before checking
  React.useEffect(() => {
    // Small delay to ensure auth store is initialized
    const timer = setTimeout(() => {
      setIsInitialized(true);
    }, 100);
    return () => clearTimeout(timer);
  }, []);

  // Helper to check if user is actually authenticated (has valid token)
  const isUserAuthenticated = (): boolean => {
    // Don't check if still initializing
    if (isLoading || !isInitialized) {
      return false;
    }
    // Tokens are stored in httpOnly cookies, not localStorage
    // Only check authentication state from store
    return !!isAuthenticated;
  };

  useEffect(() => {
    // Clear any existing interval first
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }

    // Early return if not authenticated - don't set up polling at all
    if (!isUserAuthenticated()) {
      setNotifications([]);
      setUnreadCount(0);
      return;
    }

    // Tokens are in httpOnly cookies, so we only check authentication state
    // No need to check for token in localStorage

    // Load notifications immediately
    loadNotifications();
    
    // Poll for new notifications every 30 seconds, but only if authenticated
    intervalRef.current = setInterval(() => {
      // Re-check authentication on each poll
      const stillAuthenticated = isUserAuthenticated();
      
      if (stillAuthenticated) {
        loadNotifications();
      } else {
        // Clear interval and state if user becomes unauthenticated
        if (intervalRef.current) {
          clearInterval(intervalRef.current);
          intervalRef.current = null;
        }
        setNotifications([]);
        setUnreadCount(0);
      }
    }, 30000);

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isAuthenticated, token]);

  const loadNotifications = async () => {
    // Don't make API call if user is not authenticated
    // Tokens are in httpOnly cookies, so we only check authentication state
    if (!isAuthenticated) {
      // Clear state if not authenticated
      setNotifications([]);
      setUnreadCount(0);
      return;
    }

    try {
      const response = await notificationService.getMyNotifications({
        status: 'delivered',
        limit: 10,
      });
      const notifs = response.data.data || [];
      setNotifications(notifs);
      setUnreadCount(notifs.filter(n => !n.read_at).length);
    } catch (error) {
      // Silently fail
    }
  };

  const handleMarkAsRead = async (notificationId: number) => {
    try {
      await notificationService.markAsRead(notificationId);
      setNotifications(notifications.map(n => 
        n.id === notificationId ? { ...n, status: 'read' as Notification['status'], read_at: new Date().toISOString() } : n
      ));
      setUnreadCount(Math.max(0, unreadCount - 1));
    } catch (error: unknown) {
      toast.error(getUserFriendlyError(error) || 'Failed to mark as read');
    }
  };

  const handleMarkAllAsRead = async () => {
    try {
      setLoading(true);
      const unread = notifications.filter(n => !n.read_at);
      await Promise.all(unread.map(n => notificationService.markAsRead(n.id)));
      setNotifications(notifications.map(n => ({ ...n, status: 'read' as Notification['status'], read_at: new Date().toISOString() })));
      setUnreadCount(0);
    } catch (error: unknown) {
      toast.error(getUserFriendlyError(error) || 'Failed to mark all as read');
    } finally {
      setLoading(false);
    }
  };

  // Don't render if still initializing, not authenticated, or doesn't have a token
  if (isLoading || !isInitialized || !isUserAuthenticated()) {
    return null;
  }

  return (
    <div className="relative">
      <button
        onClick={() => setShowDropdown(!showDropdown)}
        className="relative p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors"
      >
        <Bell className="w-6 h-6" />
        {unreadCount > 0 && (
          <span className="absolute top-0 right-0 w-5 h-5 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center">
            {unreadCount > 9 ? '9+' : unreadCount}
          </span>
        )}
      </button>

      {showDropdown && (
        <>
          <div
            className="fixed inset-0 z-40"
            onClick={() => setShowDropdown(false)}
          />
          <div className="absolute right-0 mt-2 w-80 bg-white rounded-xl shadow-2xl border border-gray-200 z-50 max-h-96 overflow-y-auto">
            <div className="p-4 border-b border-gray-200 flex items-center justify-between">
              <h3 className="font-semibold text-gray-900">Notifications</h3>
              {unreadCount > 0 && (
                <button
                  onClick={handleMarkAllAsRead}
                  disabled={loading}
                  className="text-xs text-indigo-600 hover:text-indigo-700 font-medium"
                >
                  Mark all read
                </button>
              )}
            </div>
            <div className="divide-y divide-gray-200">
              {notifications.length === 0 ? (
                <div className="p-4 text-center text-sm text-gray-500">
                  No notifications
                </div>
              ) : (
                notifications.map((notification) => (
                  <div
                    key={notification.id}
                    className={`p-4 hover:bg-gray-50 transition-colors cursor-pointer ${
                      !notification.read_at ? 'bg-blue-50' : ''
                    }`}
                    onClick={() => {
                      if (!notification.read_at) {
                        handleMarkAsRead(notification.id);
                      }
                    }}
                  >
                    <div className="flex items-start justify-between">
                      <div className="flex-1">
                        <p className="text-sm font-semibold text-gray-900">
                          {notification.subject || notification.notification_type.replace('_', ' ')}
                        </p>
                        <p className="text-xs text-gray-600 mt-1 line-clamp-2">
                          {notification.content}
                        </p>
                        <p className="text-xs text-gray-400 mt-2">
                          {formatDate(new Date(notification.created_at), 'short')}
                        </p>
                      </div>
                      {!notification.read_at && (
                        <div className="w-2 h-2 bg-blue-500 rounded-full ml-2 mt-1" />
                      )}
                    </div>
                  </div>
                ))
              )}
            </div>
          </div>
        </>
      )}
    </div>
  );
};

export default InAppNotificationBell;

