<template>
  <CatalogPage
    :items="filteredProducts"
    :map-items="mapItems"
    :loading="isLoading"
    :total-count="products.length"
    with-map
    map-id="hub-products-map"
    point-color="#10b981"
    :hovered-id="hoveredId"
    @update:hovered-id="hoveredId = $event"
  >
    <template #searchBar="{ displayedCount, totalCount }">
      <CatalogSearchBar
        v-model:search-query="searchQuery"
        :active-filters="navigationFilters"
        :displayed-count="displayedCount"
        :total-count="totalCount"
        @remove-filter="handleRemoveFilter"
      />
    </template>

    <template #header>
      <Text v-if="!isLoading && !hub" tone="muted">Хаб не найден</Text>
      <Text v-else-if="!isLoading" tone="muted">Выберите товар</Text>
    </template>

    <template #card="{ item }">
      <ProductCard
        :product="item"
        :price-history="getMockPriceHistory(item.uuid)"
        selectable
        @select="goToProduct(item.uuid)"
      />
    </template>

    <template #empty>
      <Stack align="center" gap="2">
        <Icon name="lucide:package-x" size="32" class="text-base-content/40" />
        <Text tone="muted">{{ t('catalogHub.products.empty') }}</Text>
      </Stack>
    </template>
  </CatalogPage>
</template>

<script setup lang="ts">
import { GetNodeDocument, NearestOffersDocument, type OfferWithRouteType, type GetNodeQueryResult } from '~/composables/graphql/public/geo-generated'

type Hub = NonNullable<GetNodeQueryResult['node']>

definePageMeta({
  layout: 'topnav'
})

const route = useRoute()
const localePath = useLocalePath()
const { t } = useI18n()

const isLoading = ref(true)
const hoveredId = ref<string>()
const hub = ref<Hub | null>(null)
const products = ref<Array<{ uuid: string; name: string }>>([])

const hubId = computed(() => route.params.id as string)

// Navigation filters for search bar badges
const navigationFilters = computed(() => {
  const filters: Array<{ id: string; label: string; key: string }> = []

  if (hub.value?.name) {
    filters.push({
      id: 'hub',
      key: 'Хаб',
      label: hub.value.name
    })
  }

  return filters
})

// Handle removing navigation filter (navigate back)
const handleRemoveFilter = (filterId: string) => {
  if (filterId === 'hub') {
    navigateTo(localePath('/catalog?select=hub'))
  }
}

// Search
const searchQuery = ref('')

const filteredProducts = computed(() => {
  if (!searchQuery.value.trim()) return products.value
  const q = searchQuery.value.toLowerCase()
  return products.value.filter(item =>
    item.name?.toLowerCase().includes(q)
  )
})

// Map items - show the hub itself
const mapItems = computed(() => {
  if (!hub.value?.latitude || !hub.value?.longitude) return []
  return [{
    uuid: hub.value.uuid || hubId.value,
    name: hub.value.name || '',
    latitude: Number(hub.value.latitude),
    longitude: Number(hub.value.longitude),
    country: hub.value.country
  }]
})

// Navigate to unified catalog with hub + product = offers
const goToProduct = (productId: string) => {
  navigateTo(localePath(`/catalog?hub=${hubId.value}&product=${productId}`))
}

// Mock price history generator (seeded by uuid for consistent results)
const getMockPriceHistory = (uuid: string): number[] => {
  const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
  const basePrice = 100 + (seed % 200)
  return Array.from({ length: 7 }, (_, i) => {
    const variation = Math.sin(seed + i * 0.5) * 20 + Math.cos(seed * 0.3 + i) * 10
    return Math.round(basePrice + variation)
  })
}

// Initial load
try {
  // First load hub node to get coordinates
  const { data: hubData } = await useServerQuery(
    'hub-node',
    GetNodeDocument,
    { uuid: hubId.value },
    'public',
    'geo'
  )

  hub.value = hubData.value?.node || null

  // Load offers near hub and group by product
  if (hub.value?.latitude && hub.value?.longitude) {
    const { data: offersData } = await useServerQuery(
      'offers-near-hub',
      NearestOffersDocument,
      {
        lat: hub.value.latitude,
        lon: hub.value.longitude,
        radius: 500
      },
      'public',
      'geo'
    )

    // Group offers by product
    const productsMap = new Map<string, { uuid: string; name: string }>()
    offersData.value?.nearestOffers?.forEach((offer) => {
      if (offer?.productUuid) {
        if (!productsMap.has(offer.productUuid)) {
          productsMap.set(offer.productUuid, {
            uuid: offer.productUuid,
            name: offer.productName || ''
          })
        }
      }
    })
    products.value = Array.from(productsMap.values())
  }
} catch (error) {
  console.error('Error loading hub:', error)
} finally {
  isLoading.value = false
}

// SEO
useHead(() => ({
  title: hub.value?.name
    ? t('catalogHub.meta.title_with_name', { name: hub.value.name })
    : t('catalogHub.meta.title'),
  meta: [
    {
      name: 'description',
      content: t('catalogHub.meta.description', {
        name: hub.value?.name || '',
        country: hub.value?.country || '',
        products: products.value.length
      })
    }
  ]
}))
</script>
