import { useEffect, useState } from 'react';
import { useAtomValue } from 'jotai';
import {
  MatrixEvent,
  NotificationCountType,
  Room,
  RoomEvent,
  RoomEventHandlerMap,
  ThreadEvent,
} from 'matrix-js-sdk';
import { getThreadSummary, ThreadSummaryData } from '../features/room/thread/threadSummaryData';
import { threadNotificationsAtom } from '../state/threadNotifications';
import { getThreadNotificationMode, ThreadNotificationMode } from '../utils/threadNotifications';

/**
 * Reactive thread summary + unread count for a root event's "N replies" chip.
 *
 * Re-computes the summary on `ThreadEvent.Update` (the SDK re-emits this on the
 * root MatrixEvent) and the unread count on `RoomEvent.UnreadNotifications`.
 */
export const useThreadSummary = (
  rootEvent: MatrixEvent,
  room: Room,
): { summary: ThreadSummaryData | undefined; unread: number; mode: ThreadNotificationMode } => {
  const threadId = rootEvent.getId();

  const threadNotifications = useAtomValue(threadNotificationsAtom);
  const mode = threadId
    ? getThreadNotificationMode(threadNotifications, room.roomId, threadId)
    : ThreadNotificationMode.Default;

  const [summary, setSummary] = useState<ThreadSummaryData | undefined>(() =>
    getThreadSummary(rootEvent),
  );
  const [unread, setUnread] = useState<number>(() =>
    threadId
      ? (room.getThreadUnreadNotificationCount(threadId, NotificationCountType.Total) ?? 0)
      : 0,
  );

  useEffect(() => {
    const refreshSummary = () => setSummary(getThreadSummary(rootEvent));
    const refreshUnread = () => {
      if (!threadId) return;
      setUnread(room.getThreadUnreadNotificationCount(threadId, NotificationCountType.Total) ?? 0);
    };

    refreshSummary();
    refreshUnread();

    const handleUnread: RoomEventHandlerMap[RoomEvent.UnreadNotifications] = (_counts, tId) => {
      if (tId && tId !== threadId) return;
      refreshUnread();
    };

    rootEvent.on(ThreadEvent.Update, refreshSummary);
    room.on(RoomEvent.UnreadNotifications, handleUnread);
    return () => {
      rootEvent.removeListener(ThreadEvent.Update, refreshSummary);
      room.removeListener(RoomEvent.UnreadNotifications, handleUnread);
    };
  }, [rootEvent, room, threadId]);

  const muted = mode === ThreadNotificationMode.Mute;

  return { summary, unread: muted ? 0 : unread, mode };
};
