import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '../lib/api';

export interface SignalMessage {
  id: string;
  driverId: string;
  direction: 'INBOUND' | 'OUTBOUND';
  content: string;
  timestamp: string;
  isRead: boolean;
}

export interface UnreadCounts {
  [driverId: string]: number;
}

/**
 * Fetch messages for a specific driver
 */
export function useDriverMessages(driverId: string | null, enabled = true) {
  return useQuery({
    queryKey: ['signal-messages', driverId],
    queryFn: async () => {
      if (!driverId) return [];
      const { data } = await api.get<SignalMessage[]>(`/signal/messages/driver/${driverId}`);
      return data;
    },
    enabled: enabled && !!driverId,
    refetchInterval: 5000, // Poll for new messages every 5 seconds
  });
}

/**
 * Fetch unread message counts for all drivers
 */
export function useUnreadCounts() {
  return useQuery({
    queryKey: ['signal-unread-counts'],
    queryFn: async () => {
      const { data } = await api.get<UnreadCounts>('/signal/messages/unread');
      return data;
    },
    refetchInterval: 10000, // Poll every 10 seconds
  });
}

/**
 * Check which events have driver responses since the event started
 * @param events Array of events with id, driverId, and startTime
 */
export function useDriverResponseCheck(
  events: Array<{ id: string; driver?: { id: string } | null; startTime: string }>
) {
  // Only include events that have a driver
  const eventsWithDrivers = events.filter((e) => e.driver?.id);

  return useQuery({
    queryKey: ['signal-driver-responses', eventsWithDrivers.map((e) => e.id).join(',')],
    queryFn: async () => {
      if (eventsWithDrivers.length === 0) {
        return new Set<string>();
      }

      const payload = {
        events: eventsWithDrivers.map((e) => ({
          eventId: e.id,
          driverId: e.driver!.id,
          startTime: e.startTime,
        })),
      };

      const { data } = await api.post<{ respondedEventIds: string[] }>(
        '/signal/messages/check-responses',
        payload
      );
      return new Set(data.respondedEventIds);
    },
    enabled: eventsWithDrivers.length > 0,
    refetchInterval: 10000, // Poll every 10 seconds
  });
}

/**
 * Send a message to a driver
 */
export function useSendMessage() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ driverId, content }: { driverId: string; content: string }) => {
      const { data } = await api.post<SignalMessage>('/signal/messages/send', {
        driverId,
        content,
      });
      return data;
    },
    onSuccess: (data, variables) => {
      // Add the new message to the cache immediately
      queryClient.setQueryData<SignalMessage[]>(
        ['signal-messages', variables.driverId],
        (old) => [...(old || []), data]
      );
      // Also invalidate to ensure consistency
      queryClient.invalidateQueries({ queryKey: ['signal-messages', variables.driverId] });
    },
  });
}

/**
 * Mark messages as read for a driver
 */
export function useMarkMessagesAsRead() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (driverId: string) => {
      const { data } = await api.post(`/signal/messages/driver/${driverId}/read`);
      return data;
    },
    onSuccess: (_, driverId) => {
      // Update the unread counts cache
      queryClient.setQueryData<UnreadCounts>(
        ['signal-unread-counts'],
        (old) => {
          if (!old) return {};
          const updated = { ...old };
          delete updated[driverId];
          return updated;
        }
      );
      // Mark messages as read in the messages cache
      queryClient.setQueryData<SignalMessage[]>(
        ['signal-messages', driverId],
        (old) => old?.map((msg) => ({ ...msg, isRead: true })) || []
      );
    },
  });
}
