import { useMutation, useQuery } from "@tanstack/react-query";
import { useCallback, useEffect, useRef, useState } from "react";
import * as api from "../service/CatalogueService";

export const useCreateCatalog = () => {
  return useMutation({
    mutationFn: api.createCatalog,
  });
};

export const useDleteCatalog = () => {
  return useMutation({
    mutationFn: (id: string) => api.deleteCatalogById(id),
  });
};

export const useGetCatalog = () => {
  return useQuery({
    queryKey: ["catalogs"],
    queryFn: api.getCatalogs,
  });
};

const catalogMongoIdPattern = /^[a-f\d]{24}$/i;

export const isCatalogMongoId = (value: string) =>
  catalogMongoIdPattern.test(value);

export const useGetCatalogById = (id: string) => {
  return useQuery({
    queryKey: ["catalog", id],
    queryFn: () => api.getCatalogById(id),
    enabled: !!id,
    // جلوگیری از بازنویسی state محلی با refetch هنگام فوکوس پنجره (مثلاً دو کاربر همزمان)
    refetchOnWindowFocus: false,
    staleTime: 5 * 60 * 1000,
  });
};

/** Route param may be Mongo id (editor/admin) or slug (public viewer-style URLs). */
export const useGetCatalogByIdOrSlug = (
  param: string,
  businessSlug = "",
) => {
  const isId = isCatalogMongoId(param);
  const byId = useGetCatalogById(isId ? param : "");
  const bySlug = useGetCatalogBySlug(
    isId ? "" : businessSlug,
    isId ? "" : param,
  );
  return isId ? byId : bySlug;
};

export const useGetCatalogBySlug = (businessSlug: string, slug: string) => {
  return useQuery({
    queryKey: ["catalog", businessSlug, slug],
    queryFn: () => api.getCatalogBySlug(businessSlug, slug),
    enabled: !!businessSlug && !!slug,
    // جلوگیری از بازنویسی state محلی با refetch هنگام فوکوس پنجره (مثلاً دو کاربر همزمان)
    refetchOnWindowFocus: false,
    staleTime: 5 * 60 * 1000,
  });
};

export const useUpdateCatalog = () => {
  const mutation = useMutation({
    mutationFn: api.updateCatalog,
  });

  // Ref to always hold the latest mutation without adding it to useCallback/useEffect deps.
  // React Query's useMutation returns a new object reference on every render, so
  // closing over `mutation` directly would cause scheduleUpdate and the cleanup effect
  // to be recreated/re-run on every render — firing mutation.mutate on each re-render
  // during drag (potentially 100+ times).
  const mutationRef = useRef(mutation);
  mutationRef.current = mutation;

  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const pendingParamsRef = useRef<
    Parameters<typeof api.updateCatalog>[0] | null
  >(null);
  const [isScheduledSaving, setIsScheduledSaving] = useState(false);

  const cancelPendingUpdate = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
    pendingParamsRef.current = null;
    setIsScheduledSaving(false);
  }, []);

  const scheduleUpdate = useCallback(
    (params: Parameters<typeof api.updateCatalog>[0], delayMs = 3000) => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
      pendingParamsRef.current = params;
      setIsScheduledSaving(true);

      timeoutRef.current = setTimeout(() => {
        const pendingParams = pendingParamsRef.current;
        timeoutRef.current = null;
        pendingParamsRef.current = null;
        setIsScheduledSaving(false);
        if (pendingParams) {
          mutationRef.current.mutate(pendingParams);
        }
      }, delayMs);
    },
    [],
  );

  useEffect(
    () => () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
        timeoutRef.current = null;
      }
      // اگر کاربر قبل از پایان debounce از ادیتور خارج شد،
      // آخرین تغییرات معلق را همان لحظه ذخیره کن.
      if (pendingParamsRef.current) {
        mutationRef.current.mutate(pendingParamsRef.current);
        pendingParamsRef.current = null;
      }
      setIsScheduledSaving(false);
    },
    [],
  );

  return {
    ...mutation,
    scheduleUpdate,
    cancelPendingUpdate,
    isSaving: isScheduledSaving || mutation.isPending,
  };
};

export const usePurchaseInitate = () => {
  return useMutation({
    mutationFn: api.purchaseInitate,
  });
};
