import {
  useEffect,
  useMemo,
  useRef,
  useState,
  type CSSProperties,
  type ReactNode,
} from 'react';
import { InboxItem } from './InboxItem.js';
import type { NotificationItem } from './types.js';

export interface NotificationCenterProps {
  items: NotificationItem[];
  /** Cap the badge to "9+" once unread count exceeds this. Default 9. */
  badgeCap?: number;
  /** Filter tabs to render. Default ['all', 'unread', 'mentions']. */
  tabs?: Array<'all' | 'unread' | 'mentions'>;
  /** Called when the user clicks an item. */
  onSelect?: (item: NotificationItem) => void;
  /** Called when the user marks ONE item read. */
  onMarkRead?: (id: string) => void;
  /** Called when the user marks ALL read. */
  onMarkAllRead?: () => void;
  /** Render slot at the bottom — typically a "Settings" link. */
  footer?: ReactNode;
  /** Override the bell trigger glyph. Default '🔔'. */
  triggerGlyph?: ReactNode;
  ariaLabel?: string;
  className?: string;
  style?: CSSProperties;
}

/**
 * `<NotificationCenter>` — bell trigger + dropdown inbox with tabs.
 * Drop it next to your user menu; pass `items` + handlers and you're
 * done. Closes on outside click and Escape.
 */
export function NotificationCenter({
  items,
  badgeCap = 9,
  tabs = ['all', 'unread', 'mentions'],
  onSelect,
  onMarkRead,
  onMarkAllRead,
  footer,
  triggerGlyph = '🔔',
  ariaLabel = 'Notifications',
  className,
  style,
}: NotificationCenterProps) {
  const [open, setOpen] = useState(false);
  const [tab, setTab] = useState<'all' | 'unread' | 'mentions'>(tabs[0] ?? 'all');
  const rootRef = useRef<HTMLDivElement>(null);

  const unread = useMemo(() => items.filter(i => !i.read).length, [items]);

  useEffect(() => {
    if (!open) return;
    const onDoc = (e: MouseEvent) => {
      if (!rootRef.current?.contains(e.target as Node)) setOpen(false);
    };
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onKey);
    };
  }, [open]);

  const filtered = useMemo(() => {
    if (tab === 'unread') return items.filter(i => !i.read);
    if (tab === 'mentions') return items.filter(i => i.kind === 'mention');
    return items;
  }, [items, tab]);

  return (
    <div
      ref={rootRef}
      data-testid="bl-notification-center"
      className={className}
      style={{ position: 'relative', display: 'inline-block', ...style }}
    >
      <button
        type="button"
        data-testid="bl-notification-trigger"
        aria-haspopup="dialog"
        aria-expanded={open}
        aria-label={ariaLabel}
        onClick={() => setOpen(o => !o)}
        style={{
          position: 'relative',
          width: 36,
          height: 36,
          display: 'inline-grid',
          placeItems: 'center',
          background: 'transparent',
          border: '1px solid var(--bl-border, rgba(0,0,0,0.08))',
          borderRadius: 'var(--bl-radius-pill, 999px)',
          color: 'var(--bl-text-primary, inherit)',
          fontSize: 16,
          cursor: 'pointer',
        }}
      >
        {triggerGlyph}
        {unread > 0 && (
          <span
            data-testid="bl-notification-badge"
            aria-hidden
            style={{
              position: 'absolute',
              top: -4,
              right: -4,
              minWidth: 18,
              height: 18,
              padding: '0 4px',
              borderRadius: 'var(--bl-radius-pill, 999px)',
              background: 'var(--bl-danger, #ef4444)',
              color: 'var(--bl-danger-foreground, #fff)',
              fontSize: 10,
              fontWeight: 700,
              display: 'inline-grid',
              placeItems: 'center',
              border: '2px solid var(--bl-surface-card, #fff)',
            }}
          >
            {unread > badgeCap ? `${badgeCap}+` : unread}
          </span>
        )}
      </button>

      {open && (
        <div
          role="dialog"
          aria-label={ariaLabel}
          data-testid="bl-notification-panel"
          style={{
            position: 'absolute',
            top: 'calc(100% + 8px)',
            right: 0,
            zIndex: 100,
            width: 360,
            maxHeight: 480,
            display: 'flex',
            flexDirection: 'column',
            background: 'var(--bl-surface-card, #fff)',
            border: '1px solid var(--bl-border, rgba(0,0,0,0.12))',
            borderRadius: 'var(--bl-radius-card, 12px)',
            boxShadow: '0 16px 40px rgba(0,0,0,0.25)',
            overflow: 'hidden',
          }}
        >
          {/* Header */}
          <div
            style={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'space-between',
              padding: 'var(--bl-space-3, 12px) var(--bl-space-4, 16px)',
              borderBottom: '1px solid var(--bl-border-subtle, rgba(0,0,0,0.06))',
            }}
          >
            <div style={{ fontSize: '0.95rem', fontWeight: 700 }}>Inbox</div>
            {unread > 0 && onMarkAllRead && (
              <button
                type="button"
                data-testid="bl-notification-mark-all"
                onClick={onMarkAllRead}
                style={{
                  fontSize: '0.75rem',
                  color: 'var(--bl-accent, #6366f1)',
                  background: 'transparent',
                  border: 'none',
                  cursor: 'pointer',
                  fontWeight: 600,
                }}
              >
                Mark all read
              </button>
            )}
          </div>

          {/* Tabs */}
          {tabs.length > 1 && (
            <div
              role="tablist"
              style={{
                display: 'flex',
                gap: 4,
                padding: 'var(--bl-space-2, 8px) var(--bl-space-3, 12px) 0',
              }}
            >
              {tabs.map(t => (
                <button
                  key={t}
                  type="button"
                  role="tab"
                  aria-selected={tab === t}
                  data-testid={`bl-notification-tab-${t}`}
                  onClick={() => setTab(t)}
                  style={{
                    padding: '4px 10px',
                    fontSize: '0.75rem',
                    borderRadius: 'var(--bl-radius-pill, 999px)',
                    border: 'none',
                    background:
                      tab === t
                        ? 'var(--bl-accent-muted, rgba(99,102,241,0.14))'
                        : 'transparent',
                    color:
                      tab === t
                        ? 'var(--bl-accent, #6366f1)'
                        : 'var(--bl-text-tertiary, #888)',
                    fontWeight: tab === t ? 700 : 500,
                    cursor: 'pointer',
                  }}
                >
                  {t === 'all' ? 'All' : t === 'unread' ? `Unread (${unread})` : 'Mentions'}
                </button>
              ))}
            </div>
          )}

          {/* List */}
          <div style={{ flex: 1, overflowY: 'auto', maxHeight: 360 }}>
            {filtered.length === 0 ? (
              <div
                data-testid="bl-notification-empty"
                style={{
                  padding: 'var(--bl-space-4, 16px)',
                  textAlign: 'center',
                  color: 'var(--bl-text-tertiary, #888)',
                  fontSize: '0.85rem',
                }}
              >
                {tab === 'unread' ? "You're all caught up." : 'Nothing here yet.'}
              </div>
            ) : (
              filtered.map(item => (
                <InboxItem
                  key={item.id}
                  item={item}
                  onSelect={onSelect}
                  onMarkRead={onMarkRead}
                />
              ))
            )}
          </div>

          {footer && (
            <div
              style={{
                padding: 'var(--bl-space-2, 8px) var(--bl-space-3, 12px)',
                borderTop: '1px solid var(--bl-border-subtle, rgba(0,0,0,0.06))',
                fontSize: '0.75rem',
                color: 'var(--bl-text-secondary, #555)',
              }}
            >
              {footer}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
