/**
 * NotificationsBell — sidebar bell with unread badge + dropdown inbox.
 *
 * Sits inside the Nav sidebar (above the parent-view toggle). Pulls from
 * /api/notifications on mount, refreshes the unread counter when the
 * realtime store reports a `message:new` / `announcement:new` event, and
 * lets the user open the dropdown to see the latest 100 rows.
 *
 * Clicking a row navigates to the related resource where possible:
 *   - `message:<id>`     → /messages
 *   - `announcement:<id>`→ /messages (announcements tab)
 * Anything else stays in place; clicking still marks the row read.
 */
import React, { useEffect, useRef } from 'react';
import { Bell, CheckCheck, Inbox, ExternalLink, X } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { useNotificationsStore, type NotificationRow } from '../store/notifications';
import { useThemeStore } from '../store/theme';

const timeAgo = (iso: string | null): string => {
  if (!iso) return '';
  const then = new Date(iso).getTime();
  const diff = Date.now() - then;
  if (diff < 60_000) return 'just now';
  if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m ago`;
  if (diff < 86_400_000) return `${Math.floor(diff / 3_600_000)}h ago`;
  return new Date(iso).toLocaleDateString();
};

export const linkFor = (related: string | null, metadata?: any): string | null => {
  if (!related && !metadata) return null;
  if (related && related.startsWith('/')) return related;

  if (related?.startsWith('announcement:')) {
    return '/messages?chat=announcements';
  }

  if (
    related?.startsWith('message:') ||
    related?.startsWith('club_message:') ||
    related?.startsWith('group_message:')
  ) {
    if (metadata?.sender_id) {
      return `/messages?chat=${metadata.sender_id}`;
    }
    if (metadata?.groupId) {
      return `/messages?chat=g_${metadata.groupId}`;
    }
    if (metadata?.clubId) {
      return `/messages?chat=c_${metadata.clubId}`;
    }
    const parts = related.split(':');
    if (parts[1]) {
      return `/messages?chat=${parts[1]}`;
    }
    return '/messages';
  }

  if (related?.startsWith('exam_group:') || related?.startsWith('exam:')) {
    const parts = related.split(':');
    return parts[1] ? `/exams/review?id=${parts[1]}` : '/exams/review';
  }

  if (related?.startsWith('notice:') || related?.startsWith('notice_board:')) {
    const parts = related.split(':');
    return parts[1] ? `/notice-board?id=${parts[1]}` : '/notice-board';
  }

  if (related?.startsWith('event:')) {
    const parts = related.split(':');
    return parts[1] ? `/events?id=${parts[1]}` : '/events';
  }

  if (related?.startsWith('leave:')) {
    const parts = related.split(':');
    return parts[1] ? `/hr/leave-approval?id=${parts[1]}` : '/hr/leave-approval';
  }

  if (related?.startsWith('medical:') || related?.startsWith('sanatorium:')) {
    const parts = related.split(':');
    return parts[1] ? `/sanatorium?id=${parts[1]}` : '/sanatorium';
  }

  if (metadata?.resource && typeof metadata.resource === 'string' && metadata.resource.startsWith('/')) {
    return metadata.resource;
  }

  return null;
};

export const labelFor = (related: string | null): string => {
  if (!related) return 'Notification';
  if (related.startsWith('announcement:')) return 'Announcement';
  if (related.startsWith('message:') || related.startsWith('club_message:')) return 'Message';
  if (related.startsWith('exam_group:') || related.startsWith('exam:')) return 'Exam Review';
  if (related.startsWith('notice:') || related.startsWith('notice_board:')) return 'Notice';
  if (related.startsWith('event:')) return 'Event';
  if (related.startsWith('leave:')) return 'Leave Request';
  if (related.startsWith('medical:') || related.startsWith('sanatorium:')) return 'Sanatorium';
  if (related.startsWith('/')) return 'Direct Link';
  return 'Notification';
};

const NotificationsBell: React.FC = () => {
  const { resolvedTheme } = useThemeStore();
  const navigate = useNavigate();
  const dropdownRef = useRef<HTMLDivElement | null>(null);

  const items = useNotificationsStore((s) => s.items);
  const unread = useNotificationsStore((s) => s.unread);
  const inboxOpen = useNotificationsStore((s) => s.inboxOpen);
  const loading = useNotificationsStore((s) => s.loading);
  const fetchInbox = useNotificationsStore((s) => s.fetchInbox);
  const fetchUnreadCount = useNotificationsStore((s) => s.fetchUnreadCount);
  const markRead = useNotificationsStore((s) => s.markRead);
  const markAllRead = useNotificationsStore((s) => s.markAllRead);
  const setInboxOpen = useNotificationsStore((s) => s.setInboxOpen);

  useEffect(() => {
    fetchUnreadCount();
    // Refresh on focus as a safety net
    const onFocus = () => fetchUnreadCount();
    window.addEventListener('focus', onFocus);
    return () => window.removeEventListener('focus', onFocus);
  }, [fetchUnreadCount]);

  useEffect(() => {
    if (inboxOpen) {
      fetchInbox();
    }
  }, [inboxOpen, fetchInbox]);

  // Close dropdown when clicking outside
  useEffect(() => {
    if (!inboxOpen) return;
    const onClick = (e: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setInboxOpen(false);
      }
    };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, [inboxOpen, setInboxOpen]);

  const onRowClick = (n: NotificationRow) => {
    markRead(n.id);
    setInboxOpen(false);
    const dest = linkFor(n.related_resource, n.metadata);
    if (dest) {
      navigate(dest);
    }
  };

  const buttonClass = `relative w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-bold transition-colors ${
    unread > 0
      ? 'bg-amber-500/10 text-amber-700 dark:text-amber-300 hover:bg-amber-500/15'
      : 'text-text-secondary hover:bg-background-alt'
  }`;

  return (
    <div className="relative" ref={dropdownRef}>
      <button
        type="button"
        onClick={() => setInboxOpen(!inboxOpen)}
        className={buttonClass}
        aria-label={`Notifications (${unread} unread)`}
      >
        <Bell size={16} className={unread > 0 ? 'animate-pulse' : ''} />
        <span className="flex-1 text-left">Notifications</span>
        {unread > 0 && (
          <span
            className="min-w-[1.25rem] h-5 px-1.5 rounded-full bg-amber-500 text-white text-[0.65rem] font-black flex items-center justify-center shadow-sm"
            aria-hidden="true"
          >
            {unread > 99 ? '99+' : unread}
          </span>
        )}
      </button>

      {inboxOpen && (
        <div
          className={`absolute bottom-full left-0 right-0 mb-2 rounded-2xl border shadow-2xl z-50 overflow-hidden ${
            resolvedTheme === 'dark'
              ? 'bg-card border-border'
              : 'bg-white border-slate-200'
          }`}
          role="dialog"
          aria-label="Notifications inbox"
        >
          <div className="flex items-center justify-between px-4 py-3 border-b border-border/60">
            <div className="flex items-center gap-2">
              <Inbox size={14} className="text-text-muted" />
              <span className="text-[0.7rem] font-black uppercase tracking-widest text-text">
                Inbox
              </span>
              {unread > 0 && (
                <span className="text-[0.65rem] font-bold text-amber-500">
                  {unread} new
                </span>
              )}
            </div>
            <div className="flex items-center gap-1">
              {unread > 0 && (
                <button
                  type="button"
                  onClick={() => markAllRead()}
                  className="text-[0.65rem] font-bold uppercase tracking-wider text-primary hover:text-primary-dark inline-flex items-center gap-1"
                >
                  <CheckCheck size={12} /> Mark all read
                </button>
              )}
              <button
                type="button"
                onClick={() => setInboxOpen(false)}
                className="p-1 text-text-muted hover:text-text"
                aria-label="Close inbox"
              >
                <X size={14} />
              </button>
            </div>
          </div>

          <div className="max-h-80 overflow-y-auto custom-scrollbar">
            {loading && items.length === 0 ? (
              <div className="p-6 text-center text-text-muted text-xs">Loading…</div>
            ) : items.filter((n) => n.status !== 'read').length === 0 ? (
              <div className="p-6 text-center text-text-muted text-xs">
                No notifications yet.
              </div>
            ) : (
              items
                .filter((n) => n.status !== 'read')
                .map((n) => {
                  const dest = linkFor(n.related_resource, n.metadata);
                return (
                  <button
                    key={n.id}
                    type="button"
                    onClick={() => onRowClick(n)}
                    className="w-full text-left px-4 py-3 border-b border-border/40 hover:bg-muted/30 transition-colors flex flex-col gap-1 bg-amber-500/5"
                  >
                    <div className="flex items-center justify-between gap-2">
                      <span className="text-[0.85rem] font-semibold text-text truncate">
                        {n.subject || 'New message'}
                      </span>
                      <span className="text-[0.6rem] text-text-muted shrink-0">
                        {timeAgo(n.created_at)}
                      </span>
                    </div>
                    {n.body && (
                      <p className="text-[0.75rem] text-text-muted line-clamp-2">
                        {n.body}
                      </p>
                    )}
                    <div className="flex items-center justify-between mt-0.5">
                      <span className="text-[0.6rem] uppercase tracking-wider text-text-muted/70">
                        {labelFor(n.related_resource)}
                      </span>
                      {dest && (
                        <ExternalLink size={10} className="text-text-muted/60" />
                      )}
                    </div>
                  </button>
                );
              })
            )}
          </div>
        </div>
      )}
    </div>
  );
};

export default NotificationsBell;