'use client'; import { shopifyFetch } from '@/services/shopify/client'; import { SEARCH_PRODUCTS_QUERY, SEARCH_SUGGESTIONS_QUERY, } from '@/graphql/search'; import type { Product } from '@/hooks/use-shopify-products'; export type SearchSortKey = 'RELEVANCE' | 'PRICE'; export interface SearchFilterValue { id: string; label: string; count: number; /** JSON string accepted back as a `ProductFilter` input. */ input: string; } export interface SearchFilter { id: string; label: string; type: 'LIST' | 'PRICE_RANGE' | 'BOOLEAN'; values: SearchFilterValue[]; } export interface SearchProductsResult { products: Product[]; totalCount: number; filters: SearchFilter[]; hasNextPage: boolean; endCursor: string | null; } export interface SearchSuggestion { id: string; title: string; handle: string; featuredImage?: { url: string; altText?: string; } | null; priceRange: { minVariantPrice: { amount: string; currencyCode: string; }; }; } interface SearchProductsOptions { query: string; first?: number; after?: string | null; sortKey?: SearchSortKey; reverse?: boolean; /** Raw `input` strings from the facets, parsed back into filter objects. */ filterInputs?: string[]; } function parseFilterInputs(inputs: string[]): unknown[] { return inputs.flatMap((input) => { try { return [JSON.parse(input)]; } catch { console.warn('Ignoring malformed product filter input:', input); return []; } }); } export async function searchProducts({ query, first = 24, after = null, sortKey = 'RELEVANCE', reverse = false, filterInputs = [], }: SearchProductsOptions): Promise { const response = await shopifyFetch({ query: SEARCH_PRODUCTS_QUERY, variables: { query, first, after, sortKey, reverse, productFilters: filterInputs.length ? parseFilterInputs(filterInputs) : null, }, }); const search = response.data.search; return { products: search.edges.map((edge: { node: Product }) => edge.node), totalCount: search.totalCount ?? 0, filters: search.productFilters ?? [], hasNextPage: Boolean(search.pageInfo?.hasNextPage), endCursor: search.pageInfo?.endCursor ?? null, }; } export async function searchSuggestions( query: string, first = 3 ): Promise<{ products: SearchSuggestion[]; totalCount: number }> { const response = await shopifyFetch({ query: SEARCH_SUGGESTIONS_QUERY, variables: { query, first }, }); const search = response.data.search; return { products: search.edges.map((edge: { node: SearchSuggestion }) => edge.node), totalCount: search.totalCount ?? 0, }; }