import { useMutation, useQuery, useQueryClient, type QueryClient } from '@tanstack/react-query';
import {
  createManagedContentCatalog,
  deleteManagedContentCatalog,
  getContentCatalog,
  getManagedContentCatalog,
  updateManagedContentCatalog,
} from '@/shared/api/contentCatalog';
import { CONTENT_CATALOG_QUERY_KEYS } from '@/shared/constants/contentCatalog';

export function useContentCatalogPayload<TPayload>(
  contentType: string,
  emptyPayload: TPayload,
  options?: { readonly enabled?: boolean },
) {
  const query = useQuery({
    queryKey: [...CONTENT_CATALOG_QUERY_KEYS.content, contentType],
    queryFn: async () => {
      const response = await getContentCatalog<TPayload>(contentType);
      return response.payload;
    },
    enabled: options?.enabled ?? true,
  });

  return {
    payload: query.data ?? emptyPayload,
    isLoading: query.isLoading,
    error: query.error,
    refresh: query.refetch,
  };
}

export function useManagedContentCatalog<TPayload>(
  contentType: string,
  options?: { readonly enabled?: boolean },
) {
  return useQuery({
    queryKey: [...CONTENT_CATALOG_QUERY_KEYS.content, 'managed', contentType],
    queryFn: () => getManagedContentCatalog<TPayload>(contentType),
    enabled: options?.enabled ?? true,
  });
}

export function useSaveManagedContentCatalog<TPayload>(
  contentType: string,
  hasExistingContent: boolean,
  getPayload: () => TPayload,
) {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: () => (
      hasExistingContent
        ? updateManagedContentCatalog<TPayload>(contentType, { payload: getPayload() })
        : createManagedContentCatalog<TPayload>({
            content_type: contentType,
            payload: getPayload(),
          })
    ),
    onSuccess: async () => {
      await invalidateContentCatalogQueries(queryClient, contentType);
    },
  });
}

export function useDeleteManagedContentCatalog(contentType: string) {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: () => deleteManagedContentCatalog(contentType),
    onSuccess: async () => {
      await invalidateContentCatalogQueries(queryClient, contentType);
    },
  });
}

async function invalidateContentCatalogQueries(
  queryClient: QueryClient,
  contentType: string,
): Promise<void> {
  await Promise.all([
    queryClient.invalidateQueries({ queryKey: [...CONTENT_CATALOG_QUERY_KEYS.content, contentType] }),
    queryClient.invalidateQueries({ queryKey: [...CONTENT_CATALOG_QUERY_KEYS.content, 'managed', contentType] }),
  ]);
}
