import { GetSupplierProfilesDocument } from '~/composables/graphql/public/exchange-generated' import { NearestSuppliersDocument } from '~/composables/graphql/public/geo-generated' const PAGE_SIZE = 24 // Shared state across list and map views const items = ref([]) const total = ref(0) const isLoading = ref(false) const isLoadingMore = ref(false) const isInitialized = ref(false) const filterProductUuid = ref(null) const filterBounds = ref<{ west: number; south: number; east: number; north: number } | null>(null) export function useCatalogSuppliers() { const { execute } = useGraphQL() const itemsWithCoords = computed(() => items.value.filter(s => s.latitude && s.longitude) ) const canLoadMore = computed(() => items.value.length < total.value) const fetchPage = async (offset: number, replace = false) => { if (replace) isLoading.value = true try { // If filtering by product, use nearestSuppliers with global search // (center point 0,0 with very large radius to cover entire globe) if (filterProductUuid.value) { const data = await execute( NearestSuppliersDocument, { lat: 0, lon: 0, radius: 20000, // 20000 km radius covers entire Earth productUuid: filterProductUuid.value, limit: 500 // Increased limit for global search }, 'public', 'geo' ) items.value = data?.nearestSuppliers || [] total.value = items.value.length isInitialized.value = true return } // Default: fetch all suppliers // If bounds filter is active, fetch more and filter client-side // TODO: Add bounds support to exchange backend for proper server-side filtering const bounds = filterBounds.value // Validate bounds coordinates const validBounds = bounds && typeof bounds.west === 'number' && isFinite(bounds.west) && typeof bounds.south === 'number' && isFinite(bounds.south) && typeof bounds.east === 'number' && isFinite(bounds.east) && typeof bounds.north === 'number' && isFinite(bounds.north) const fetchLimit = validBounds ? 500 : PAGE_SIZE const data = await execute( GetSupplierProfilesDocument, { limit: fetchLimit, offset: validBounds ? 0 : offset }, 'public', 'exchange' ) let next = data?.getSupplierProfiles || [] // Client-side bounds filtering (until exchange backend supports it) if (validBounds) { next = next.filter((s: any) => { if (!s.latitude || !s.longitude) return false const lat = Number(s.latitude) const lng = Number(s.longitude) return lat >= bounds.south && lat <= bounds.north && lng >= bounds.west && lng <= bounds.east }) } items.value = replace ? next : items.value.concat(next) total.value = validBounds ? next.length : (data?.getSupplierProfilesCount ?? total.value) isInitialized.value = true } finally { isLoading.value = false } } const loadMore = async () => { if (isLoadingMore.value) return isLoadingMore.value = true try { await fetchPage(items.value.length) } finally { isLoadingMore.value = false } } // Initialize data if not already loaded const init = async () => { if (!isInitialized.value && items.value.length === 0) { await fetchPage(0, true) } } const setProductFilter = (uuid: string | null) => { if (filterProductUuid.value === uuid) return // Early return if unchanged filterProductUuid.value = uuid if (isInitialized.value) { fetchPage(0, true) } } const setBoundsFilter = (bounds: { west: number; south: number; east: number; north: number } | null) => { filterBounds.value = bounds if (isInitialized.value) { fetchPage(0, true) } } return { items, total, isLoading, isLoadingMore, itemsWithCoords, canLoadMore, fetchPage, loadMore, init, setProductFilter, setBoundsFilter } }