// ==========================================
// Shell — Notification Bell Component
// ==========================================
// Bell icon with unread count badge and dropdown panel.
// Fetches notifications on mount and listens for WS events.

const html = window.html;
const { useState, useEffect, useCallback, useRef } = window.hooks;

const BELL_SVG = html`
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
         stroke-width="2" stroke-linecap="round" stroke-linejoin="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>`;

export function NotificationBell({ onNavigate } = {}) {
    const [notifications, setNotifications] = useState([]);
    const [open, setOpen] = useState(false);
    const ref = useRef(null);

    const unreadCount = notifications.filter(n => !n.read_at).length;

    // ── Fetch notifications ─────────────
    const reload = useCallback(async () => {
        if (!window.sw?.api?.notifications?.list) return;
        try {
            const resp = await window.sw.api.notifications.list({ per_page: 20 });
            const items = Array.isArray(resp) ? resp
                        : Array.isArray(resp?.data) ? resp.data
                        : Array.isArray(resp?.notifications) ? resp.notifications
                        : [];
            setNotifications(items);
        } catch (_) {}
    }, []);

    useEffect(() => { reload(); }, [reload]);

    // ── WebSocket live updates ──────────
    useEffect(() => {
        if (!window.sw?.on) return;
        const handler = () => reload();
        window.sw.on('notification.created', handler);
        return () => window.sw.off?.('notification.created', handler);
    }, [reload]);

    // ── Close on outside click ──────────
    useEffect(() => {
        if (!open) return;
        function _close(e) {
            if (ref.current?.contains(e.target)) return;
            setOpen(false);
        }
        document.addEventListener('click', _close);
        return () => document.removeEventListener('click', _close);
    }, [open]);

    // ── Mark as read ────────────────────
    const _markRead = useCallback(async (id) => {
        if (!window.sw?.api?.notifications?.markRead) return;
        try {
            await window.sw.api.notifications.markRead(id);
            setNotifications(prev => prev.map(n =>
                n.id === id ? { ...n, read_at: new Date().toISOString() } : n
            ));
        } catch (_) {}
    }, []);

    const _markAllRead = useCallback(async () => {
        if (window.sw?.api?.notifications?.markAllRead) {
            try {
                await window.sw.api.notifications.markAllRead();
                setNotifications(prev => prev.map(n => ({ ...n, read_at: n.read_at || new Date().toISOString() })));
                return;
            } catch (_) {}
        }
        // Fallback: mark one by one
        const unread = notifications.filter(n => !n.read_at);
        for (const n of unread) {
            await _markRead(n.id);
        }
    }, [notifications, _markRead]);

    const _toggle = useCallback(() => {
        setOpen(v => !v);
    }, []);

    // ── Click-to-navigate ────────────────
    const _onClick = useCallback((n) => {
        if (!n.read_at) _markRead(n.id);
        if (n.resource_type === 'channel' && n.resource_id && onNavigate) {
            onNavigate(n.resource_id);
            setOpen(false);
        }
    }, [_markRead, onNavigate]);

    return html`
        <div class="sw-notification-bell" ref=${ref}>
            <button class="sw-notification-bell__trigger"
                    onClick=${_toggle}
                    title="Notifications"
                    aria-label="Notifications"
                    aria-expanded=${open}>
                ${BELL_SVG}
                ${unreadCount > 0 && html`
                    <span class="sw-notification-bell__badge">${unreadCount > 9 ? '9+' : unreadCount}</span>`}
            </button>
            ${open && html`
                <div class="sw-notification-bell__panel">
                    <div class="sw-notification-bell__header">
                        <span>Notifications</span>
                        ${unreadCount > 0 && html`
                            <button class="sw-notification-bell__mark-all"
                                    onClick=${_markAllRead}>
                                Mark all read
                            </button>`}
                    </div>
                    <div class="sw-notification-bell__list">
                        ${notifications.length === 0 && html`
                            <div class="sw-notification-bell__empty">No notifications</div>`}
                        ${notifications.map(n => {
                            const navigable = n.resource_type === 'channel' && n.resource_id && onNavigate;
                            return html`
                            <div key=${n.id}
                                 class=${'sw-notification-bell__item'
                                     + (n.read_at ? '' : ' sw-notification-bell__item--unread')
                                     + (navigable ? ' sw-notification-bell__item--navigable' : '')}
                                 onClick=${() => _onClick(n)}>
                                <div class="sw-notification-bell__item-text">${n.title || n.message || 'Notification'}</div>
                                ${n.body && html`<div class="sw-notification-bell__item-body">${n.body}</div>`}
                                <div class="sw-notification-bell__item-time">
                                    ${_timeAgo(n.created_at)}
                                    ${navigable && html`<span class="sw-notification-bell__item-action">Open</span>`}
                                </div>
                            </div>`;
                        })}
                    </div>
                </div>`}
        </div>`;
}

function _timeAgo(ts) {
    if (!ts) return '';
    const diff = Date.now() - new Date(ts).getTime();
    const mins = Math.floor(diff / 60000);
    if (mins < 1) return 'just now';
    if (mins < 60) return mins + 'm ago';
    const hrs = Math.floor(mins / 60);
    if (hrs < 24) return hrs + 'h ago';
    const days = Math.floor(hrs / 24);
    return days + 'd ago';
}
