import { useMutation, useQueryClient } from '@tanstack/react-query';
import { addUrlToLibrary } from '../dal';
import { cardKeys } from '../cardKeys';
import { collectionKeys } from '@/features/collections/lib/collectionKeys';
import { feedKeys } from '@/features/feeds/lib/feedKeys';
import { noteKeys } from '@/features/notes/lib/noteKeys';
import { sembleKeys } from '@/features/semble/lib/sembleKeys';
import posthog from 'posthog-js';
import {
  CardSaveAnalyticsContext,
  CardSaveEventProperties,
} from '@/features/analytics/types';
import { shouldCaptureAnalytics } from '@/features/analytics/utils';

export default function useAddCard(
  analyticsContext?: CardSaveAnalyticsContext,
) {
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: (newCard: {
      url: string;
      note?: string;
      collectionIds?: string[];
      viaCardId?: string;
    }) => {
      return addUrlToLibrary(newCard.url, {
        note: newCard.note,
        collectionIds: newCard.collectionIds,
        viaCardId: newCard.viaCardId,
      });
    },

    // Do things that are absolutely necessary and logic related (like query invalidation) in the useMutation callbacks
    // Do UI related things like redirects or showing toast notifications in mutate callbacks. If the user navigated away from the current screen before the mutation finished, those will purposefully not fire
    // https://tkdodo.eu/blog/mastering-mutations-in-react-query#some-callbacks-might-not-fire
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: cardKeys.all() });
      queryClient.invalidateQueries({ queryKey: noteKeys.all() });
      queryClient.invalidateQueries({ queryKey: feedKeys.all() });
      queryClient.invalidateQueries({ queryKey: sembleKeys.all() });
      queryClient.invalidateQueries({ queryKey: collectionKeys.mine() });
      queryClient.invalidateQueries({ queryKey: collectionKeys.infinite() });
      queryClient.invalidateQueries({ queryKey: collectionKeys.all() });
      queryClient.invalidateQueries({
        queryKey: collectionKeys.bySembleUrl(variables.url),
      });
      // Invalidate URL metadata with stats to update tab counts
      queryClient.invalidateQueries({
        queryKey: cardKeys.urlMetadata(variables.url, { includeStats: true }),
      });

      // invalidate each collection query individually
      variables.collectionIds?.forEach((id) => {
        queryClient.invalidateQueries({
          queryKey: collectionKeys.collection(id),
        });
        queryClient.invalidateQueries({
          queryKey: collectionKeys.infinite(id),
        });
      });

      // Track card save event in PostHog
      if (shouldCaptureAnalytics() && analyticsContext) {
        const eventProperties: CardSaveEventProperties = {
          save_source: analyticsContext.saveSource,
          is_new_card: true,
          has_note: !!variables.note,
          collection_count: variables.collectionIds?.length || 0,
          active_filters: analyticsContext.activeFilters
            ? {
                url_type: analyticsContext.activeFilters.urlType,
                sort: analyticsContext.activeFilters.sort,
                search_query: analyticsContext.activeFilters.searchQuery,
                profile_filter: analyticsContext.activeFilters.profileFilter,
              }
            : undefined,
          via_card_id: variables.viaCardId,
          page_path: analyticsContext.pagePath,
        };

        posthog.capture('card_saved', eventProperties);

        // Clear super properties after capture
        posthog.unregister('original_save_source');
        posthog.unregister('original_active_filters');
      }
    },
  });

  return mutation;
}
