import React, { useState, useRef, useEffect, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { Bell } from 'lucide-react';
import { useNotifications } from '../hooks/useNotifications';
import { useNavigate } from 'react-router-dom';
import { FaBell } from 'react-icons/fa';

const NotificationBell: React.FC = () => {
  const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotifications();
  const [isOpen, setIsOpen] = useState(false);
  const buttonRef = useRef<HTMLDivElement>(null);
  const panelRef = useRef<HTMLDivElement>(null);
  const navigate = useNavigate();

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      const target = event.target as Node;
      if (buttonRef.current?.contains(target) || panelRef.current?.contains(target)) {
        return;
      }
      setIsOpen(false);
    };

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [isOpen]);

  useEffect(() => {
    if (!isOpen) return;

    const mq = window.matchMedia('(max-width: 1023px)');
    if (!mq.matches) return;

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [isOpen]);

  const handleNotificationClick = async (notification: any) => {
    if (!notification.read) {
      try {
        await markAsRead(notification.name);
      } catch (error) {
        console.warn('[NotificationBell] Could not mark as read (permission issue):', error);
      }
    }

    if (notification.document_type && notification.document_name) {
      const docType = notification.document_type;
      const docName = notification.document_name;
      const normalizedType = docType.replace(/_/g, ' ').trim();

      if (normalizedType === 'Asset Maintenance Log' || normalizedType === 'Asset Maintenance') {
        navigate(`/maintenance/${docName}`);
      } else if (normalizedType === 'Work Order' || normalizedType === 'Asset Repair') {
        navigate(`/work-orders/${docName}`);
      } else if (normalizedType === 'Asset') {
        navigate(`/assets/${docName}`);
      } else if (normalizedType === 'PM Schedule Generator' || normalizedType === 'PM Schedule') {
        navigate(`/ppm-planner/${docName}`);
      } else if (normalizedType === 'PPM') {
        navigate(`/ppm/${docName}`);
      } else if (normalizedType === 'Item') {
        navigate(`/inventory/${docName}`);
      } else {
        const frappeRoute = docType.toLowerCase().replace(/\s+/g, '-').replace(/_/g, '-');
        window.open(`/app/${frappeRoute}/${docName}`, '_blank');
      }
    }

    setIsOpen(false);
  };

  const formatDate = (dateString: string) => {
    const date = new Date(dateString);
    const now = new Date();
    const diffMs = now.getTime() - date.getTime();
    const diffMins = Math.floor(diffMs / 60000);
    const diffHours = Math.floor(diffMs / 3600000);
    const diffDays = Math.floor(diffMs / 86400000);

    if (diffMins < 1) return 'Just now';
    if (diffMins < 60) return `${diffMins}m ago`;
    if (diffHours < 24) return `${diffHours}h ago`;
    if (diffDays < 7) return `${diffDays}d ago`;
    return date.toLocaleDateString();
  };

  const unreadNotifications = notifications.filter(n => !n.read);
  const readNotifications = notifications.filter(n => n.read).slice(0, 10);

  const renderPanel = () => (
    <div
      ref={panelRef}
      className="
        fixed z-[9999] flex flex-col overflow-hidden
        bg-white dark:bg-gray-800 rounded-xl shadow-2xl
        border border-gray-200 dark:border-gray-700
        left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2
        w-[calc(100vw-2rem)] max-w-md max-h-[75vh]
        lg:left-auto lg:top-[3.75rem] lg:right-4 lg:translate-x-0 lg:translate-y-0 lg:w-80 lg:max-h-96
      "
    >
      <div className="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between gap-2">
        <h3 className="font-semibold text-gray-800 dark:text-white flex items-center gap-2 min-w-0">
          <FaBell />
          <span className="truncate">Notifications</span>
          {unreadCount > 0 && (
            <span className="text-xs bg-red-500 text-white px-2 py-0.5 rounded-full shrink-0">
              {unreadCount} new
            </span>
          )}
        </h3>
        {unreadCount > 0 && (
          <button
            type="button"
            onClick={markAllAsRead}
            className="text-xs text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 shrink-0"
          >
            Mark all read
          </button>
        )}
      </div>

      <div className="overflow-y-auto flex-1 min-h-0">
        {notifications.length === 0 ? (
          <div className="p-8 text-center text-gray-500 dark:text-gray-400">
            <FaBell className="mx-auto text-3xl mb-2 opacity-50" />
            <p>No notifications</p>
          </div>
        ) : (
          <>
            {unreadNotifications.length > 0 && (
              <div className="p-2">
                <div className="text-xs font-semibold text-gray-500 dark:text-gray-400 px-2 mb-1">
                  NEW
                </div>
                {unreadNotifications.map(notif => (
                  <div
                    key={notif.name}
                    onClick={() => handleNotificationClick(notif)}
                    className="p-3 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer border-l-4 border-blue-500 bg-blue-50 dark:bg-blue-900/20"
                  >
                    <div className="flex items-start justify-between gap-2">
                      <div className="flex-1 min-w-0">
                        <p className="text-sm font-medium text-gray-900 dark:text-white truncate">
                          {(notif as any).subject || notif.document_type || 'Notification'}
                        </p>
                        {(notif as any).email_content && (
                          <p className="text-xs text-gray-600 dark:text-gray-400 mt-1 line-clamp-2">
                            {(notif as any).email_content}
                          </p>
                        )}
                        <p className="text-xs text-gray-500 dark:text-gray-500 mt-1">
                          {formatDate(notif.creation)}
                        </p>
                      </div>
                      <div className="w-2 h-2 bg-blue-500 rounded-full flex-shrink-0 mt-1" />
                    </div>
                  </div>
                ))}
              </div>
            )}

            {readNotifications.length > 0 && (
              <div className="p-2 border-t border-gray-200 dark:border-gray-700">
                {unreadNotifications.length > 0 && (
                  <div className="text-xs font-semibold text-gray-500 dark:text-gray-400 px-2 mb-1">
                    EARLIER
                  </div>
                )}
                {readNotifications.map(notif => (
                  <div
                    key={notif.name}
                    onClick={() => handleNotificationClick(notif)}
                    className="p-3 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer"
                  >
                    <div className="flex items-start justify-between gap-2">
                      <div className="flex-1 min-w-0">
                        <p className="text-sm font-medium text-gray-700 dark:text-gray-300 truncate">
                          {(notif as any).subject || notif.document_type || 'Notification'}
                        </p>
                        {(notif as any).email_content && (
                          <p className="text-xs text-gray-500 dark:text-gray-400 mt-1 line-clamp-2">
                            {(notif as any).email_content}
                          </p>
                        )}
                        <p className="text-xs text-gray-400 dark:text-gray-500 mt-1">
                          {formatDate(notif.creation)}
                        </p>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );

  const closePanel = useCallback(() => setIsOpen(false), []);

  return (
    <div className="relative" ref={buttonRef}>
      <button
        type="button"
        onClick={() => setIsOpen(prev => !prev)}
        className="relative p-2 min-h-[44px] min-w-[44px] flex items-center justify-center text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
        title="Notifications"
        aria-expanded={isOpen}
        aria-label="Notifications"
      >
        <Bell size={20} />
        {unreadCount > 0 && (
          <span className="absolute top-1 right-1 flex items-center justify-center w-5 h-5 text-xs font-bold text-white bg-red-500 rounded-full">
            {unreadCount > 9 ? '9+' : unreadCount}
          </span>
        )}
      </button>

      {isOpen &&
        createPortal(
          <>
            <button
              type="button"
              className="fixed inset-0 z-[9998] bg-black/40 lg:bg-black/20"
              onClick={closePanel}
              aria-label="Close notifications"
            />
            {renderPanel()}
          </>,
          document.body
        )}
    </div>
  );
};

export default NotificationBell;
