'use client';

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type { ZulipMessage, ZulipStream, ZulipUnreadCount } from '@/types/integrations';

/** Query key factory */
export const messagesKeys = {
  all: ['messages'] as const,
  list: (streamId?: number) => [...messagesKeys.all, 'list', streamId] as const,
  streams: ['messages', 'streams'] as const,
  unread: ['messages', 'unread'] as const,
};

/**
 * Fetch ZULIP messages
 */
async function fetchMessages(streamId?: number): Promise<ZulipMessage[]> {
  const params: Record<string, string | number | boolean | undefined> = {};
  if (streamId) params.streamId = streamId;

  const response = await api.get<{ messages: ZulipMessage[] } | ZulipMessage[]>(
    '/integrations/zulip/messages',
    { params },
  );
  return Array.isArray(response) ? response : response.messages;
}

/**
 * Fetch ZULIP streams
 */
async function fetchStreams(): Promise<ZulipStream[]> {
  const response = await api.get<{ streams: ZulipStream[] } | ZulipStream[]>(
    '/integrations/zulip/streams',
  );
  return Array.isArray(response) ? response : response.streams;
}

/**
 * Fetch unread counts
 */
async function fetchUnreadCounts(): Promise<ZulipUnreadCount[]> {
  const response = await api.get<{ unreads: ZulipUnreadCount[] } | ZulipUnreadCount[]>(
    '/integrations/zulip/unread',
  );
  return Array.isArray(response) ? response : response.unreads;
}

/**
 * Send a message to ZULIP
 */
async function sendMessage(params: {
  streamId: number;
  topic: string;
  content: string;
}): Promise<ZulipMessage> {
  return api.post<ZulipMessage>('/integrations/zulip/messages', params);
}

/**
 * Mark a message as read
 */
async function markAsRead(messageId: number): Promise<void> {
  await api.post(`/integrations/zulip/messages/${messageId}/read`);
}

/**
 * Hook to fetch ZULIP messages
 */
export function useMessages(streamId?: number) {
  return useQuery({
    queryKey: messagesKeys.list(streamId),
    queryFn: () => fetchMessages(streamId),
    staleTime: 30 * 1000,
    refetchOnWindowFocus: true,
  });
}

/**
 * Hook to fetch ZULIP streams
 */
export function useStreams() {
  return useQuery({
    queryKey: messagesKeys.streams,
    queryFn: fetchStreams,
    staleTime: 60 * 1000,
  });
}

/**
 * Hook to fetch unread counts
 */
export function useUnreadCounts() {
  return useQuery({
    queryKey: messagesKeys.unread,
    queryFn: fetchUnreadCounts,
    staleTime: 30 * 1000,
    refetchOnWindowFocus: true,
  });
}

/**
 * Hook to get total unread count
 */
export function useTotalUnreadCount() {
  const { data: counts } = useUnreadCounts();
  return counts?.reduce((sum, c) => sum + c.count, 0) ?? 0;
}

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

  return useMutation({
    mutationFn: sendMessage,
    onSuccess: (newMessage) => {
      queryClient.invalidateQueries({ queryKey: messagesKeys.list(newMessage.streamId) });
      queryClient.invalidateQueries({ queryKey: messagesKeys.list() });
    },
  });
}

/**
 * Hook to mark a message as read
 */
export function useMarkAsRead() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: markAsRead,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: messagesKeys.unread });
    },
  });
}
