import type { GetOffersQueryResult } from '~/composables/graphql/public/exchange-generated'
import { GetOffersDocument } from '~/composables/graphql/public/exchange-generated'

const PAGE_SIZE = 24

// Type from codegen
type OfferItem = NonNullable<NonNullable<GetOffersQueryResult['getOffers']>[number]>

// Shared state across list and map views
const items = ref<OfferItem[]>([])
const total = ref(0)
const selectedProductUuid = ref<string | null>(null)
const isLoading = ref(false)
const isLoadingMore = ref(false)
const isInitialized = ref(false)

export function useCatalogOffers() {
  const { execute } = useGraphQL()

  const itemsWithCoords = computed(() =>
    items.value
      .filter(offer => offer.locationLatitude && offer.locationLongitude)
      .map(offer => ({
        uuid: offer.uuid,
        name: offer.productName || offer.locationName,
        latitude: offer.locationLatitude,
        longitude: offer.locationLongitude,
        country: offer.locationCountry
      }))
  )

  const canLoadMore = computed(() => items.value.length < total.value)

  const fetchPage = async (offset: number, replace = false) => {
    if (replace) isLoading.value = true
    try {
      const data = await execute(
        GetOffersDocument,
        {
          limit: PAGE_SIZE,
          offset,
          productUuid: selectedProductUuid.value
        },
        'public',
        'exchange'
      )
      const next = (data?.getOffers || []).filter((o): o is OfferItem => o !== null)
      items.value = replace ? next : items.value.concat(next)
      total.value = data?.getOffersCount ?? total.value
      isInitialized.value = true
    } finally {
      isLoading.value = false
    }
  }

  const setProductUuid = (uuid: string | null) => {
    if (selectedProductUuid.value !== uuid) {
      selectedProductUuid.value = uuid
      if (isInitialized.value) {
        fetchPage(0, true)
      }
    }
  }

  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)
    }
  }

  return {
    items,
    total,
    selectedProductUuid,
    isLoading,
    isLoadingMore,
    itemsWithCoords,
    canLoadMore,
    fetchPage,
    loadMore,
    init,
    setProductUuid
  }
}
