<template>
  <CatalogPage
    :loading="isLoading"
    :use-server-clustering="true"
    :cluster-node-type="clusterNodeType"
    map-id="unified-catalog-map"
    :point-color="mapPointColor"
    :items="[]"
    :show-panel="showPanel"
    @select="onMapSelect"
  >
    <!-- Panel slot - shows selection list OR quote results -->
    <template #panel>
      <!-- Selection mode: show list for picking product/hub/supplier -->
      <SelectionPanel
        v-if="selectMode"
        :select-mode="selectMode"
        :products="products"
        :hubs="hubs"
        :suppliers="suppliers"
        :loading="selectionLoading"
        :loading-more="selectionLoadingMore"
        :has-more="selectionHasMore"
        @select="onSelectItem"
        @close="cancelSelect"
        @load-more="onLoadMore"
      />

      <!-- Quote results: show offers after search -->
      <QuotePanel
        v-else-if="showQuoteResults"
        :loading="offersLoading"
        :offers="offers"
        @select-offer="onSelectOffer"
      />
    </template>
  </CatalogPage>
</template>

<script setup lang="ts">
import { GetOffersDocument } from '~/composables/graphql/public/exchange-generated'

definePageMeta({
  layout: 'topnav'
})

const { t } = useI18n()
const { execute } = useGraphQL()
const router = useRouter()
const localePath = useLocalePath()

const {
  catalogMode,
  selectMode,
  productId,
  supplierId,
  hubId,
  canSearch,
  mapViewMode,
  setMapViewMode,
  entityColors,
  selectItem,
  cancelSelect,
  setLabel
} = useCatalogSearch()

// Composables for data (initialize immediately when selectMode changes)
const { items: products, isLoading: productsLoading, isLoadingMore: productsLoadingMore, canLoadMore: productsCanLoadMore, loadMore: loadMoreProducts, init: initProducts } = useCatalogProducts()
const { items: hubs, isLoading: hubsLoading, isLoadingMore: hubsLoadingMore, canLoadMore: hubsCanLoadMore, loadMore: loadMoreHubs, init: initHubs } = useCatalogHubs()
const { items: suppliers, isLoading: suppliersLoading, isLoadingMore: suppliersLoadingMore, canLoadMore: suppliersCanLoadMore, loadMore: loadMoreSuppliers, init: initSuppliers } = useCatalogSuppliers()

// Selection loading state
const selectionLoading = computed(() => {
  if (selectMode.value === 'product') return productsLoading.value
  if (selectMode.value === 'hub') return hubsLoading.value
  if (selectMode.value === 'supplier') return suppliersLoading.value
  return false
})

// Selection loading more state
const selectionLoadingMore = computed(() => {
  if (selectMode.value === 'product') return productsLoadingMore.value
  if (selectMode.value === 'hub') return hubsLoadingMore.value
  if (selectMode.value === 'supplier') return suppliersLoadingMore.value
  return false
})

// Selection has more state
const selectionHasMore = computed(() => {
  if (selectMode.value === 'product') return productsCanLoadMore.value
  if (selectMode.value === 'hub') return hubsCanLoadMore.value
  if (selectMode.value === 'supplier') return suppliersCanLoadMore.value
  return false
})

// Load more handler
const onLoadMore = () => {
  if (selectMode.value === 'product') loadMoreProducts()
  if (selectMode.value === 'hub') loadMoreHubs()
  if (selectMode.value === 'supplier') loadMoreSuppliers()
}

// Initialize data and sync map view when selectMode changes
watch(selectMode, async (mode) => {
  if (mode === 'product') {
    await initProducts()
    setMapViewMode('offers')
  }
  if (mode === 'hub') {
    await initHubs()
    setMapViewMode('hubs')
  }
  if (mode === 'supplier') {
    await initSuppliers()
    setMapViewMode('suppliers')
  }
}, { immediate: true })

// Offers data for quote results
const offers = ref<any[]>([])
const offersLoading = ref(false)
const showQuoteResults = ref(false)

// Watch for search trigger from topnav
const searchTrigger = useState<number>('catalog-search-trigger', () => 0)
watch(searchTrigger, () => {
  if (canSearch.value) {
    onSearch()
  }
})

// Loading state
const isLoading = computed(() => offersLoading.value || selectionLoading.value)

// Show panel when selecting OR when showing quote results
const showPanel = computed(() => {
  return selectMode.value !== null || showQuoteResults.value
})

// Cluster node type based on map view mode
const clusterNodeType = computed(() => {
  if (mapViewMode.value === 'offers') return 'offer'
  if (mapViewMode.value === 'hubs') return 'logistics'
  if (mapViewMode.value === 'suppliers') return 'supplier'
  return 'offer'
})

// Map point color based on map view mode
const mapPointColor = computed(() => {
  if (mapViewMode.value === 'offers') return entityColors.offer
  if (mapViewMode.value === 'hubs') return entityColors.hub
  if (mapViewMode.value === 'suppliers') return entityColors.supplier
  return entityColors.offer
})

// Handle map item selection
const onMapSelect = (item: any) => {
  // If in selection mode, use map click to fill the selector
  if (selectMode.value && item.uuid) {
    const itemName = item.name || item.uuid.slice(0, 8) + '...'

    // For hubs selection - click on hub fills hub selector
    if (selectMode.value === 'hub' && mapViewMode.value === 'hubs') {
      selectItem('hub', item.uuid, itemName)
      showQuoteResults.value = false
      offers.value = []
      return
    }

    // For supplier selection - click on supplier fills supplier selector
    if (selectMode.value === 'supplier' && mapViewMode.value === 'suppliers') {
      selectItem('supplier', item.uuid, itemName)
      showQuoteResults.value = false
      offers.value = []
      return
    }

    // For product selection viewing offers - try to find product in loaded list
    if (selectMode.value === 'product' && mapViewMode.value === 'offers') {
      // The offer has product info - we'll look it up from the products list if loaded
      // or just use the offer's product_uuid if available
      const product = products.value.find((p: any) => p.uuid === item.productUuid)
      if (product) {
        selectItem('product', product.uuid, product.name || itemName)
      } else if (item.productUuid) {
        selectItem('product', item.productUuid, item.productName || itemName)
      }
      showQuoteResults.value = false
      offers.value = []
      return
    }
  }

  // Default behavior for quote mode etc
  if (catalogMode.value === 'quote' && item.uuid) {
    console.log('Selected from map:', item)
  }
}

// Handle selection from SelectionPanel
const onSelectItem = (type: string, item: any) => {
  if (item.uuid && item.name) {
    selectItem(type, item.uuid, item.name)
    showQuoteResults.value = false
    offers.value = []
  }
}

// Search for offers
const onSearch = async () => {
  if (!canSearch.value) return

  offersLoading.value = true
  showQuoteResults.value = true

  try {
    const vars: any = {}
    if (productId.value) vars.productUuid = productId.value
    if (supplierId.value) vars.teamUuid = supplierId.value
    if (hubId.value) vars.locationUuid = hubId.value

    const data = await execute(GetOffersDocument, vars, 'public', 'exchange')
    offers.value = data?.getOffers || []

    // Update labels from response
    if (offers.value.length > 0) {
      const first = offers.value[0]
      if (productId.value && first.productName) {
        setLabel('product', productId.value, first.productName)
      }
      if (hubId.value && first.locationName) {
        setLabel('hub', hubId.value, first.locationName)
      }
      if (supplierId.value && first.teamName) {
        setLabel('supplier', supplierId.value, first.teamName)
      }
    }
  } finally {
    offersLoading.value = false
  }
}

// Select offer - navigate to detail page
const onSelectOffer = (offer: any) => {
  if (offer.uuid && offer.productUuid) {
    router.push(localePath(`/catalog/offers/${offer.productUuid}?offer=${offer.uuid}`))
  }
}

// SEO
useHead(() => ({
  title: t('catalog.hero.title')
}))
</script>
