import { root } from '@repo/core' import { type ListTemplatesInput, type ListTemplatesResult, TemplateController, type TemplateDetail } from '@repo/sdk' import { useCallback, useRef, useState } from 'react' import { type ApiError } from '@/lib/types' import { OWNER_ID } from '@/lib/auth' import { handleError } from './use-error' type ListCategoryTemplatesParams = Partial> interface UseCategoryTemplatesOptions { categoryId?: string limit?: number sortBy?: 'createdAt' | 'updatedAt' sortOrder?: 'asc' | 'desc' } const DEFAULT_PARAMS = { limit: 20, sortBy: 'createdAt' as const, sortOrder: 'desc' as const, } export const useCategoryTemplates = ( categoryIdOrOptions?: string | UseCategoryTemplatesOptions, additionalOptions?: Omit ) => { // 支持多种调用方式: // useCategoryTemplates('category-id') // useCategoryTemplates('category-id', { limit: 50 }) // useCategoryTemplates({ categoryId: 'category-id', limit: 50 }) const options: UseCategoryTemplatesOptions | undefined = typeof categoryIdOrOptions === 'string' ? { categoryId: categoryIdOrOptions, ...additionalOptions } : categoryIdOrOptions const [loading, setLoading] = useState(false) const [loadingMore, setLoadingMore] = useState(false) const [error, setError] = useState(null) const [data, setData] = useState() const currentPageRef = useRef(1) const hasMoreRef = useRef(true) const currentCategoryIdRef = useRef(options?.categoryId) const execute = useCallback(async (params?: ListCategoryTemplatesParams) => { setLoading(true) setError(null) currentPageRef.current = params?.page || 1 // 确定要使用的 categoryId:params > options(来自 props)> currentCategoryIdRef const categoryIdToUse = params?.categoryId ?? options?.categoryId ?? currentCategoryIdRef.current // 更新当前 categoryId ref if (categoryIdToUse !== undefined) { currentCategoryIdRef.current = categoryIdToUse } const template = root.get(TemplateController) const requestParams: ListTemplatesInput = { ...DEFAULT_PARAMS, ...options, ...params, page: params?.page ?? 1, categoryId: categoryIdToUse, ownerId: OWNER_ID, } const { data, error } = await handleError( async () => await template.list(requestParams), ) if (error) { setError(error) setLoading(false) return { data: undefined, error } } const templates = data?.templates || [] const currentPage = requestParams.page || 1 const totalPages = data?.totalPages || 1 hasMoreRef.current = currentPage < totalPages setData(data) setLoading(false) return { data, error: null } }, [options]) const loadMore = useCallback(async () => { if (loadingMore || loading || !hasMoreRef.current) return { data: undefined, error: null } setLoadingMore(true) const nextPage = currentPageRef.current + 1 // 使用最新的 categoryId:options(来自 props)> currentCategoryIdRef const categoryIdToUse = options?.categoryId ?? currentCategoryIdRef.current const template = root.get(TemplateController) const requestParams: ListTemplatesInput = { ...DEFAULT_PARAMS, ...options, page: nextPage, categoryId: categoryIdToUse, ownerId: OWNER_ID, } const { data: newData, error } = await handleError( async () => await template.list(requestParams), ) if (error) { setLoadingMore(false) return { data: undefined, error } } const newTemplates = newData?.templates || [] const totalPages = newData?.totalPages || 1 hasMoreRef.current = nextPage < totalPages currentPageRef.current = nextPage setData((prev) => ({ ...newData, templates: [...(prev?.templates || []), ...newTemplates], })) setLoadingMore(false) return { data: newData, error: null } }, [loading, loadingMore, options]) const refetch = useCallback(() => { hasMoreRef.current = true return execute() }, [execute]) return { data, templates: data?.templates || [], loading, loadingMore, error, execute, refetch, loadMore, hasMore: hasMoreRef.current, } } export type { TemplateDetail }