import {
  listPeerDeliveriesForMessages,
  markMessagesDelivered,
} from '@chat-app/shared/chat';
import { useCallback, useEffect, useMemo, useState } from 'react';

import { supabase } from './supabase';

// Tracks peer delivery acknowledgements for our own messages. Single peer
// (DM). For groups this would need a per-user map; keep parity with
// `useMessageReads` for now.
export function useMessageDeliveries(
  messageIds: string[],
  peerUserId: string | undefined,
): { peerDeliveredSet: Set<string>; refresh: () => Promise<void> } {
  const idsKey = useMemo(() => messageIds.join(','), [messageIds]);
  const [peerDeliveredSet, setPeerDeliveredSet] = useState<Set<string>>(new Set());

  const refresh = useCallback(async () => {
    if (!peerUserId || messageIds.length === 0) {
      setPeerDeliveredSet(new Set());
      return;
    }
    try {
      const s = await listPeerDeliveriesForMessages(supabase, messageIds, peerUserId);
      setPeerDeliveredSet(s);
    } catch (err: unknown) {
      console.error('listPeerDeliveriesForMessages failed', err);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [peerUserId, idsKey]);

  useEffect(() => {
    void refresh();
    if (!peerUserId) return;
    const channel = supabase
      .channel('deliveries:' + peerUserId)
      .on(
        'postgres_changes',
        {
          event: 'INSERT',
          schema: 'public',
          table: 'message_deliveries',
          filter: 'user_id=eq.' + peerUserId,
        },
        () => {
          void refresh();
        },
      )
      .subscribe();
    return () => {
      void supabase.removeChannel(channel);
    };
  }, [peerUserId, refresh]);

  return { peerDeliveredSet, refresh };
}

export async function markDelivered(messageIds: string[]): Promise<void> {
  await markMessagesDelivered(supabase, messageIds);
}
