import { useState, useEffect, useRef, useCallback } from 'react';
import { useAuthStore } from '@/stores/auth.store';

export interface ChatNotification {
  id: string; // generated client-side
  type: 'chat_reply';
  videoId: number;
  videoTitle: string;
  commentId: number;
  commenterName: string;
  contentPreview: string;
  receivedAt: number;
}

export function useChatNotifications() {
  const { accessToken, isAuthenticated } = useAuthStore();
  const [notifications, setNotifications] = useState<ChatNotification[]>([]);
  const eventSourceRef = useRef<EventSource | null>(null);
  const notifCounterRef = useRef(0);

  const clearNotification = useCallback((id: string) => {
    setNotifications((prev) => prev.filter((n) => n.id !== id));
  }, []);

  const clearAll = useCallback(() => {
    setNotifications([]);
  }, []);

  useEffect(() => {
    if (!isAuthenticated || !accessToken) {
      if (eventSourceRef.current) {
        eventSourceRef.current.close();
        eventSourceRef.current = null;
      }
      return;
    }

    // Obtain a short-lived signed URL (2026-04-12). Previously we put the full
    // access-token JWT in the URL, which leaked via access logs / referer.
    let es: EventSource | null = null;
    let cancelled = false;

    const wire = (src: EventSource) => {
      src.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data);
          if (data.type === 'connected') return;
          if (data.type === 'chat_reply') {
            const notif: ChatNotification = {
              ...data,
              id: `notif-${++notifCounterRef.current}-${Date.now()}`,
              receivedAt: Date.now(),
            };
            setNotifications((prev) => [...prev, notif].slice(-10));
          }
        } catch { /* ignore parse errors */ }
      };
      src.onerror = () => { /* EventSource handles reconnect */ };
    };

    (async () => {
      try {
        const signRes = await fetch('/media/api/media/sign', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` },
          body: JSON.stringify({ path: '/api/media/notifications/stream', ttlSeconds: 300 }),
        });
        if (!signRes.ok || cancelled) return;
        const { url: signedPath } = await signRes.json();
        if (cancelled) return;
        es = new EventSource(`/media${signedPath}`);
        eventSourceRef.current = es;
        wire(es);
      } catch { /* notifications unavailable */ }
    })();

    return () => {
      cancelled = true;
      es?.close();
      eventSourceRef.current = null;
    };
  }, [isAuthenticated, accessToken]);

  return { notifications, clearNotification, clearAll };
}
