import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useEffect, useRef } from "react";
import { useAuthToken } from "../hooks/use-root-data";
import { getApiBaseUrl } from "../utils/api-config";

/**
 * Records that the authenticated user viewed a product. Used as a signal for
 * the recommendation system (alongside bookmarks, follows, orders, semantic
 * proximity). Fire-and-forget: failures are swallowed so tracking never
 * disrupts the browsing experience.
 *
 * NOTE: this hits /api/engagement/v1/views/ via a direct fetch because the
 * endpoint is newer than the generated OpenAPI client. Swap to the generated
 * EngagementApi method once the client is regenerated.
 */
export function useTrackProductView() {
  const token = useAuthToken();
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (productId: string) => {
      if (!token || !productId) return { skipped: true };

      const res = await fetch(`${getApiBaseUrl()}/api/engagement/v1/views/`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({ productId }),
      });

      if (!res.ok) {
        throw new Error(`Failed to track view: ${res.status}`);
      }
      return res.json();
    },
    onSuccess: () => {
      // Keep "recently viewed" fresh if/when it's rendered.
      queryClient.invalidateQueries({ queryKey: ["recentlyViewedProducts"] });
    },
    // View tracking is best-effort; never surface errors to the user.
    onError: () => {},
  });
}

/**
 * Fires a single product-view event when a product page is opened. Dedupes per
 * productId so React strict-mode double-mounts / re-renders don't double-count
 * within the same mount, and skips when not authenticated.
 */
export function useRecordProductView(
  productId: string | undefined,
  options?: { enabled?: boolean }
) {
  const token = useAuthToken();
  const { mutate } = useTrackProductView();
  const lastTrackedRef = useRef<string | null>(null);
  const enabled = options?.enabled ?? true;

  useEffect(() => {
    if (!enabled) return;
    if (!token || !productId) return;
    if (lastTrackedRef.current === productId) return;

    lastTrackedRef.current = productId;
    mutate(productId);
  }, [productId, token, enabled, mutate]);
}
