import { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { useNavigate } from 'react-router-dom';
import { api } from '../api.js';
import NotifTypeAvatar from './NotifTypeAvatar.jsx';

const POLL_INTERVAL = 30_000; // 30s

function timeAgo(dateStr) {
  const diff = (Date.now() - new Date(dateStr + 'Z').getTime()) / 1000;
  if (diff < 60) return 'À l\'instant';
  if (diff < 3600) return `Il y a ${Math.floor(diff / 60)} min`;
  if (diff < 86400) return `Il y a ${Math.floor(diff / 3600)} h`;
  if (diff < 86400 * 7) return `Il y a ${Math.floor(diff / 86400)} j`;
  return new Date(dateStr + 'Z').toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' });
}

export default function NotificationBell() {
  const [unread, setUnread]         = useState(0);
  const [open, setOpen]             = useState(false);
  const [notifs, setNotifs]         = useState([]);
  const [loading, setLoading]       = useState(false);
  const [dropPos, setDropPos]       = useState({ top: 0, right: 0 });
  const bellRef                     = useRef(null);
  const dropRef                     = useRef(null);
  const navigate                    = useNavigate();

  // ── Polling unread count ────────────────────────────────────────────────
  const fetchCount = useCallback(async () => {
    try {
      const data = await api.get('/notifications/count');
      setUnread(data.unread ?? 0);
    } catch { /* silencieux */ }
  }, []);

  useEffect(() => {
    fetchCount();
    const id = setInterval(fetchCount, POLL_INTERVAL);
    // Rafraîchissement immédiat sur demande (ex: après un seed)
    window.addEventListener('notif:refresh', fetchCount);
    return () => {
      clearInterval(id);
      window.removeEventListener('notif:refresh', fetchCount);
    };
  }, [fetchCount]);

  // ── Charger les notifs dans le dropdown ──────────────────────────────────
  const fetchNotifs = useCallback(async () => {
    setLoading(true);
    try {
      const data = await api.get('/notifications', { limit: 10 });
      setNotifs(data.notifications ?? []);
    } catch { /* silencieux */ }
    setLoading(false);
  }, []);

  const handleOpen = () => {
    if (open) { setOpen(false); return; }
    const rect = bellRef.current?.getBoundingClientRect();
    if (rect) {
      setDropPos({
        top:   rect.bottom + 8,
        right: window.innerWidth - rect.right,
      });
    }
    setOpen(true);
    fetchNotifs();
  };

  // ── Fermer au clic extérieur ─────────────────────────────────────────────
  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (
        !bellRef.current?.contains(e.target) &&
        !dropRef.current?.contains(e.target)
      ) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  // ── Actions ──────────────────────────────────────────────────────────────
  const markRead = async (id) => {
    try {
      await api.patch(`/notifications/${id}/read`);
      setNotifs(prev => prev.map(n => n.id === id ? { ...n, read: 1 } : n));
      setUnread(prev => Math.max(0, prev - 1));
    } catch { /* silencieux */ }
  };

  const markAll = async () => {
    try {
      await api.patch('/notifications/read-all');
      setNotifs(prev => prev.map(n => ({ ...n, read: 1 })));
      setUnread(0);
    } catch { /* silencieux */ }
  };

  const handleNotifClick = (n) => {
    if (!n.read) markRead(n.id);
    if (n.link) { setOpen(false); navigate(n.link); }
  };

  // ── Dropdown ─────────────────────────────────────────────────────────────
  const dropdown = open && createPortal(
    <div
      ref={dropRef}
      className="notif-dropdown"
      style={{ top: dropPos.top, right: dropPos.right }}
    >
      <div className="notif-dropdown-header">
        <span className="notif-dropdown-title">Notifications</span>
        {unread > 0 && (
          <button className="notif-mark-all-btn" onClick={markAll}>
            Tout marquer lu
          </button>
        )}
      </div>

      <div className="notif-dropdown-list">
        {loading && (
          <div className="notif-empty">Chargement…</div>
        )}
        {!loading && notifs.length === 0 && (
          <div className="notif-empty">Aucune notification</div>
        )}
        {!loading && notifs.map(n => (
          <div
            key={n.id}
            className={`notif-item${!n.read ? ' notif-item-unread' : ''}`}
            onClick={() => handleNotifClick(n)}
          >
            <NotifTypeAvatar type={n.type} size={36} />
            <div className="notif-item-body">
              <div className="notif-item-title">{n.title}</div>
              {n.body && <div className="notif-item-text">{n.body}</div>}
              <div className="notif-item-time">{timeAgo(n.created_at)}</div>
            </div>
            {!n.read && <span className="notif-unread-dot" />}
          </div>
        ))}
      </div>

      <div className="notif-dropdown-footer">
        <button
          className="notif-view-all-btn"
          onClick={() => { setOpen(false); navigate('/notifications'); }}
        >
          Voir toutes les notifications
        </button>
      </div>
    </div>,
    document.body
  );

  return (
    <>
      <button
        ref={bellRef}
        className={`notif-bell-btn${unread > 0 ? ' has-unread' : ''}`}
        onClick={handleOpen}
        title="Notifications"
        aria-label={`Notifications${unread > 0 ? ` (${unread} non lues)` : ''}`}
      >
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />
          <path d="M13.73 21a2 2 0 0 1-3.46 0" />
        </svg>
        {unread > 0 && (
          <span className="notif-badge">{unread > 99 ? '99+' : unread}</span>
        )}
      </button>
      {dropdown}
    </>
  );
}
