import { ProductsListDocument, GetNodeDocument, NearestOffersDocument } from '~/composables/graphql/public/geo-generated' import { GetSupplierProfileDocument } from '~/composables/graphql/public/exchange-generated' // Shared state const items = ref([]) const isLoading = ref(false) const isLoadingMore = ref(false) const isInitialized = ref(false) // Filter state const filterSupplierUuid = ref(null) const filterHubUuid = ref(null) export function useCatalogProducts() { const { execute } = useGraphQL() // Products don't have server-side pagination yet, so we load all at once const canLoadMore = computed(() => false) const fetchProducts = async () => { if (isLoading.value) return isLoading.value = true try { let data if (filterSupplierUuid.value) { // Products from specific supplier - get supplier coordinates first const supplierData = await execute( GetSupplierProfileDocument, { uuid: filterSupplierUuid.value }, 'public', 'exchange' ) const supplier = supplierData?.getSupplierProfile if (!supplier?.latitude || !supplier?.longitude) { console.warn('Supplier has no coordinates') items.value = [] } else { // Get offers near supplier and group by product const offersData = await execute( NearestOffersDocument, { lat: supplier.latitude, lon: supplier.longitude, radius: 500 }, 'public', 'geo' ) // Group offers by product const productsMap = new Map() offersData?.nearestOffers?.forEach((offer: any) => { if (offer?.productUuid) { if (!productsMap.has(offer.productUuid)) { productsMap.set(offer.productUuid, { uuid: offer.productUuid, name: offer.productName, offersCount: 0 }) } productsMap.get(offer.productUuid)!.offersCount++ } }) items.value = Array.from(productsMap.values()) } } else if (filterHubUuid.value) { // Products near hub - get hub coordinates first const hubData = await execute( GetNodeDocument, { uuid: filterHubUuid.value }, 'public', 'geo' ) const hub = hubData?.node if (!hub?.latitude || !hub?.longitude) { console.warn('Hub has no coordinates') items.value = [] } else { // Get offers near hub and group by product const offersData = await execute( NearestOffersDocument, { lat: hub.latitude, lon: hub.longitude, radius: 500 }, 'public', 'geo' ) // Group offers by product const productsMap = new Map() offersData?.nearestOffers?.forEach((offer: any) => { if (offer?.productUuid) { if (!productsMap.has(offer.productUuid)) { productsMap.set(offer.productUuid, { uuid: offer.productUuid, name: offer.productName, offersCount: 0 }) } productsMap.get(offer.productUuid)!.offersCount++ } }) items.value = Array.from(productsMap.values()) } } else { // All products from graph data = await execute( ProductsListDocument, { limit: 500 }, 'public', 'geo' ) items.value = data?.productsList || [] } isInitialized.value = true } finally { isLoading.value = false } } const loadMore = async () => { // No-op: products don't support pagination yet } const init = async () => { if (!isInitialized.value && items.value.length === 0) { await fetchProducts() } } // Filter setters const setSupplierFilter = (uuid: string | null) => { if (filterSupplierUuid.value !== uuid) { filterSupplierUuid.value = uuid filterHubUuid.value = null // clear other filter isInitialized.value = false fetchProducts() } } const setHubFilter = (uuid: string | null) => { if (filterHubUuid.value !== uuid) { filterHubUuid.value = uuid filterSupplierUuid.value = null // clear other filter isInitialized.value = false fetchProducts() } } const clearFilters = () => { if (filterSupplierUuid.value || filterHubUuid.value) { filterSupplierUuid.value = null filterHubUuid.value = null isInitialized.value = false fetchProducts() } } // Products don't have coordinates directly (they're an aggregation of offers) // Bounds filtering would require a new backend query that filters by offer locations // For now, this is a no-op - products show all regardless of map bounds const setBoundsFilter = (_bounds: { west: number; south: number; east: number; north: number } | null) => { // No-op: products are not filterable by map bounds in current implementation } return { items, isLoading, isLoadingMore, isInitialized, canLoadMore, fetchProducts, loadMore, init, setSupplierFilter, setHubFilter, clearFilters, setBoundsFilter } }