"use client";
import { createApiClient } from '@btst/stack/plugins/client';
import { useInfiniteQuery, useSuspenseInfiniteQuery, useQuery, useSuspenseQuery, useQueryClient, useMutation } from '@tanstack/react-query';
import { useDebounce } from './use-debounce.mjs';
import { useRef, useEffect } from 'react';
import { useInView } from 'react-intersection-observer';
import { createBlogQueryKeys } from '../../../../../../../plugins/blog/query-keys.mjs';
import { usePluginOverrides } from '@btst/stack/context';

const SHARED_QUERY_CONFIG = {
  retry: false,
  refetchOnWindowFocus: false,
  refetchOnMount: false,
  refetchOnReconnect: false,
  staleTime: 1e3 * 60 * 5,
  // 5 minutes
  gcTime: 1e3 * 60 * 10
  // 10 minutes
};
function usePosts(options = {}) {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const {
    tag,
    tagSlug,
    limit = 10,
    enabled = true,
    query,
    published
  } = options;
  const queries = createBlogQueryKeys(client, headers);
  const queryParams = {
    tag,
    tagSlug,
    limit,
    query,
    published
  };
  const basePosts = queries.posts.list(queryParams);
  const {
    data,
    isLoading,
    error,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    refetch
  } = useInfiniteQuery({
    ...basePosts,
    ...SHARED_QUERY_CONFIG,
    initialPageParam: 0,
    getNextPageParam: (lastPage, allPages) => {
      const posts2 = lastPage;
      if (posts2.length < limit) return void 0;
      return allPages.length * limit;
    },
    enabled: enabled && !!client
  });
  const posts = data?.pages?.flat() ?? [];
  return {
    posts,
    isLoading,
    error,
    loadMore: fetchNextPage,
    hasMore: !!hasNextPage,
    isLoadingMore: isFetchingNextPage,
    refetch
  };
}
function useSuspensePosts(options = {}) {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const {
    tag,
    tagSlug,
    limit = 10,
    enabled = true,
    query,
    published
  } = options;
  const queries = createBlogQueryKeys(client, headers);
  const queryParams = { tag, tagSlug, limit, query, published };
  const basePosts = queries.posts.list(queryParams);
  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    refetch,
    error,
    isFetching
  } = useSuspenseInfiniteQuery({
    ...basePosts,
    ...SHARED_QUERY_CONFIG,
    initialPageParam: 0,
    getNextPageParam: (lastPage, allPages) => {
      const posts2 = lastPage;
      if (posts2.length < limit) return void 0;
      return allPages.length * limit;
    }
  });
  if (error && !isFetching) {
    throw error;
  }
  const posts = data.pages?.flat() ?? [];
  return {
    posts,
    loadMore: fetchNextPage,
    hasMore: !!hasNextPage,
    isLoadingMore: isFetchingNextPage,
    refetch
  };
}
function usePost(slug) {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queries = createBlogQueryKeys(client, headers);
  const basePost = queries.posts.detail(slug ?? "");
  const { data, isLoading, error, refetch } = useQuery({
    ...basePost,
    ...SHARED_QUERY_CONFIG,
    enabled: !!client && !!slug
  });
  return {
    post: data || null,
    isLoading,
    error,
    refetch
  };
}
function useSuspensePost(slug) {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queries = createBlogQueryKeys(client, headers);
  const basePost = queries.posts.detail(slug);
  const { data, refetch, error, isFetching } = useSuspenseQuery({
    ...basePost,
    ...SHARED_QUERY_CONFIG
  });
  if (error && !isFetching) {
    throw error;
  }
  return { post: data || null, refetch };
}
function useTags() {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queries = createBlogQueryKeys(client, headers);
  const baseTags = queries.tags.list();
  const { data, isLoading, error, refetch } = useQuery({
    ...baseTags,
    ...SHARED_QUERY_CONFIG,
    enabled: !!client
  });
  return {
    tags: data ?? [],
    isLoading,
    error,
    refetch
  };
}
function useSuspenseTags() {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queries = createBlogQueryKeys(client, headers);
  const baseTags = queries.tags.list();
  const { data, refetch, error, isFetching } = useSuspenseQuery({
    ...baseTags,
    ...SHARED_QUERY_CONFIG
  });
  if (error && !isFetching) {
    throw error;
  }
  return {
    tags: data ?? [],
    refetch
  };
}
function useCreatePost() {
  const { refresh, apiBaseURL, apiBasePath } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queryClient = useQueryClient();
  const queries = createBlogQueryKeys(client);
  return useMutation({
    mutationKey: [...queries.posts._def, "create"],
    mutationFn: async (postData) => {
      const response = await client("@post/posts", {
        method: "POST",
        body: postData
      });
      return response.data;
    },
    onSuccess: async (created) => {
      if (created?.slug) {
        queryClient.setQueryData(
          queries.posts.detail(created.slug).queryKey,
          created
        );
      }
      await queryClient.invalidateQueries({
        queryKey: queries.posts.list._def
      });
      await queryClient.invalidateQueries({
        queryKey: queries.drafts.list._def
      });
      if (refresh) {
        await refresh();
      }
    }
  });
}
function useUpdatePost() {
  const { refresh, apiBaseURL, apiBasePath } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queryClient = useQueryClient();
  const queries = createBlogQueryKeys(client);
  return useMutation({
    mutationKey: [...queries.posts._def, "update"],
    mutationFn: async ({ id, data }) => {
      const response = await client(`@put/posts/:id`, {
        method: "PUT",
        params: { id },
        body: data
      });
      return response.data;
    },
    onSuccess: async (updated) => {
      if (updated?.slug) {
        queryClient.setQueryData(
          queries.posts.detail(updated.slug).queryKey,
          updated
        );
      }
      await queryClient.invalidateQueries({
        queryKey: queries.posts.list._def
      });
      await queryClient.invalidateQueries({
        queryKey: queries.drafts.list._def
      });
      if (refresh) {
        await refresh();
      }
    }
  });
}
function useDeletePost() {
  const { refresh, apiBaseURL, apiBasePath } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queryClient = useQueryClient();
  const queries = createBlogQueryKeys(client);
  return useMutation({
    mutationKey: [...queries.posts._def, "delete"],
    mutationFn: async ({ id }) => {
      const response = await client(`@delete/posts/:id`, {
        method: "DELETE",
        params: { id }
      });
      return response.data;
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({
        queryKey: queries.posts._def
      });
      await queryClient.invalidateQueries({
        queryKey: queries.drafts.list._def
      });
      if (refresh) {
        await refresh();
      }
    }
  });
}
function usePostSearch({
  query,
  enabled = true,
  debounceMs = 300,
  limit = 10,
  published = true
}) {
  const debouncedQuery = useDebounce(query, debounceMs);
  const shouldSearch = enabled && (query?.trim().length ?? 0) > 0;
  const lastResultsRef = useRef([]);
  const { posts, isLoading, error, refetch } = usePosts({
    query: debouncedQuery,
    limit,
    enabled: shouldSearch && debouncedQuery.trim() !== "",
    published
  });
  const effectivePosts = shouldSearch ? posts : [];
  useEffect(() => {
    if (!isLoading && posts && posts.length >= 0) {
      lastResultsRef.current = posts;
    }
  }, [posts, isLoading]);
  const isDebouncing = enabled && debounceMs > 0 && debouncedQuery !== query;
  const effectiveLoading = isLoading || isDebouncing;
  const dataToReturn = !shouldSearch ? [] : effectiveLoading ? lastResultsRef.current : effectivePosts;
  return {
    posts: dataToReturn,
    // compatibility alias similar to tanstack useQuery
    data: dataToReturn,
    isLoading: effectiveLoading,
    error,
    refetch,
    isSearching: effectiveLoading,
    searchQuery: debouncedQuery
  };
}
function useNextPreviousPosts(createdAt, options = {}) {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queries = createBlogQueryKeys(client, headers);
  const { ref, inView } = useInView({
    // start a little early so the data is ready as it scrolls in
    rootMargin: "200px 0px",
    // run once; keep data cached after
    triggerOnce: true
  });
  const dateValue = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
  const baseQuery = queries.posts.nextPrevious(dateValue);
  const { data, isLoading, error, refetch } = useQuery({
    ...baseQuery,
    ...SHARED_QUERY_CONFIG,
    enabled: (options.enabled ?? true) && inView && !!client
  });
  return {
    previousPost: data?.previous ?? null,
    nextPost: data?.next ?? null,
    isLoading,
    error,
    refetch,
    ref,
    inView
  };
}
function useRecentPosts(options = {}) {
  const { apiBaseURL, apiBasePath, headers } = usePluginOverrides("blog");
  const client = createApiClient({
    baseURL: apiBaseURL,
    basePath: apiBasePath
  });
  const queries = createBlogQueryKeys(client, headers);
  const { ref, inView } = useInView({
    // start a little early so the data is ready as it scrolls in
    rootMargin: "200px 0px",
    // run once; keep data cached after
    triggerOnce: true
  });
  const baseQuery = queries.posts.recent({
    limit: options.limit ?? 5,
    excludeSlug: options.excludeSlug
  });
  const { data, isLoading, error, refetch } = useQuery({
    ...baseQuery,
    ...SHARED_QUERY_CONFIG,
    enabled: (options.enabled ?? true) && inView && !!client
  });
  return {
    recentPosts: data ?? [],
    isLoading,
    error,
    refetch,
    ref,
    inView
  };
}

export { useCreatePost, useDeletePost, useNextPreviousPosts, usePost, usePostSearch, usePosts, useRecentPosts, useSuspensePost, useSuspensePosts, useSuspenseTags, useTags, useUpdatePost };
