<template>
  <div>
    <!-- SearchBar teleported to layout -->
    <Teleport to="#catalog-searchbar">
      <div class="px-4 lg:px-6 py-2">
        <CatalogSearchBar
          v-model:search-query="searchQuery"
          :active-filters="activeFilterBadges"
          :displayed-count="displayItems.length"
          :total-count="total"
          @remove-filter="onRemoveFilter"
          @search="onSearch"
        >
          <template #filters>
            <div class="p-2 space-y-3">
              <div>
                <div class="text-xs font-semibold mb-1 text-base-content/70">{{ t('catalogHubsSection.filters.transport') }}</div>
                <ul class="menu menu-compact">
                  <li v-for="filter in filters" :key="filter.id">
                    <a
                      :class="{ active: selectedFilter === filter.id }"
                      @click="selectedFilter = filter.id"
                    >
                      {{ filter.label }}
                    </a>
                  </li>
                </ul>
              </div>
              <div class="divider my-0"></div>
              <div>
                <div class="text-xs font-semibold mb-1 text-base-content/70">{{ t('catalogHubsSection.filters.country') }}</div>
                <ul class="menu menu-compact max-h-48 overflow-y-auto">
                  <li v-for="filter in countryFilters" :key="filter.id">
                    <a
                      :class="{ active: selectedCountry === filter.id }"
                      @click="selectedCountry = filter.id"
                    >
                      {{ filter.label }}
                    </a>
                  </li>
                </ul>
              </div>
            </div>
          </template>
        </CatalogSearchBar>
      </div>
    </Teleport>

    <!-- Map teleported to layout -->
    <Teleport to="#catalog-map">
      <div class="h-full w-full relative">
        <!-- Search with map checkbox -->
        <label class="absolute top-4 left-4 z-10 bg-white/90 backdrop-blur px-3 py-2 rounded-lg shadow flex items-center gap-2 cursor-pointer">
          <input type="checkbox" v-model="searchWithMap" class="checkbox checkbox-sm" />
          <span class="text-sm">{{ t('catalogMap.searchWithMap') }}</span>
        </label>
        <ClientOnly>
          <CatalogMap
            ref="mapRef"
            map-id="hubs-map"
            :items="useServerClustering ? [] : itemsWithCoords"
            :clustered-points="useServerClustering ? clusteredNodes : []"
            :use-server-clustering="useServerClustering"
            point-color="#10b981"
            :hovered-item-id="hoveredHubId"
            :hovered-item="hoveredItem"
            @select-item="onMapSelect"
            @bounds-change="onBoundsChange"
          />
        </ClientOnly>
      </div>
    </Teleport>

    <!-- List content -->
    <div v-if="isLoading" class="flex items-center justify-center py-8">
    <Card padding="lg">
      <Stack align="center" justify="center" gap="3">
        <Spinner />
        <Text tone="muted">{{ t('catalogLanding.states.loading') }}</Text>
      </Stack>
    </Card>
  </div>

  <template v-else>
    <Stack gap="3">
      <div
        v-for="item in displayItems"
        :key="item.uuid"
        :class="{ 'ring-2 ring-primary rounded-lg': item.uuid === selectedHubId }"
        @click="onSelectHub(item)"
        @mouseenter="hoveredHubId = item.uuid"
        @mouseleave="hoveredHubId = undefined"
      >
        <template v-for="country in getCountryForHub(item)" :key="country.name">
          <Text v-if="isFirstInCountry(item)" weight="semibold" class="mb-2">{{ country.name }}</Text>
        </template>
        <HubCard :hub="item" />
      </div>
    </Stack>

    <PaginationLoadMore
      v-if="displayItems.length > 0"
      :shown="displayItems.length"
      :total="total"
      :can-load-more="canLoadMore"
      :loading="isLoadingMore"
      hide-counter
      @load-more="loadMore"
      class="mt-4"
    />

    <Stack v-if="displayItems.length === 0" align="center" gap="2" class="py-8">
      <Text tone="muted">{{ t('catalogHubsSection.empty.no_hubs') }}</Text>
    </Stack>
  </template>
  </div>
</template>

<script setup lang="ts">
import type { MapBounds } from '~/components/catalog/CatalogMap.vue'

definePageMeta({
  layout: 'catalog'
})

const { t } = useI18n()

const {
  items,
  total,
  selectedFilter,
  selectedCountry,
  filters,
  countryFilters,
  isLoading,
  isLoadingMore,
  itemsByCountry,
  canLoadMore,
  loadMore,
  init
} = useCatalogHubs()

// Selected/hovered hub for map highlighting
const selectedHubId = ref<string>()
const hoveredHubId = ref<string>()

// Search bar
const searchQuery = ref('')

// Map ref
const mapRef = ref<{ flyTo: (lat: number, lng: number, zoom?: number) => void } | null>(null)

// Server-side clustering
const useServerClustering = true
const { clusteredNodes, fetchClusters } = useClusteredNodes()

// Search with map checkbox
const searchWithMap = ref(false)
const currentBounds = ref<MapBounds | null>(null)

const onBoundsChange = (bounds: MapBounds) => {
  currentBounds.value = bounds
  if (useServerClustering) {
    fetchClusters(bounds)
  }
}

// Filter items with valid coordinates for map
const itemsWithCoords = computed(() =>
  items.value.filter(item =>
    item.latitude != null &&
    item.longitude != null &&
    !isNaN(Number(item.latitude)) &&
    !isNaN(Number(item.longitude))
  ).map(item => ({
    uuid: item.uuid,
    name: item.name || '',
    latitude: Number(item.latitude),
    longitude: Number(item.longitude),
    country: item.country
  }))
)

// Filtered items when searchWithMap is enabled
const displayItems = computed(() => {
  if (!searchWithMap.value || !currentBounds.value) return items.value
  return items.value.filter(item => {
    if (item.latitude == null || item.longitude == null) return false
    const { west, east, north, south } = currentBounds.value!
    const lng = Number(item.longitude)
    const lat = Number(item.latitude)
    return lng >= west && lng <= east && lat >= south && lat <= north
  })
})

// Hovered item with coordinates for map highlight
const hoveredItem = computed(() => {
  if (!hoveredHubId.value) return null
  const item = items.value.find(i => i.uuid === hoveredHubId.value)
  if (!item?.latitude || !item?.longitude) return null
  return { latitude: Number(item.latitude), longitude: Number(item.longitude) }
})

// Active filter badges (non-default filters shown as badges)
const activeFilterBadges = computed(() => {
  const badges: { id: string; label: string }[] = []
  if (selectedFilter.value !== 'all') {
    const filter = filters.value.find(f => f.id === selectedFilter.value)
    if (filter) badges.push({ id: `transport:${filter.id}`, label: filter.label })
  }
  if (selectedCountry.value !== 'all') {
    const filter = countryFilters.value.find(f => f.id === selectedCountry.value)
    if (filter) badges.push({ id: `country:${filter.id}`, label: filter.label })
  }
  return badges
})

// Remove filter badge
const onRemoveFilter = (id: string) => {
  if (id.startsWith('transport:')) {
    selectedFilter.value = 'all'
  } else if (id.startsWith('country:')) {
    selectedCountry.value = 'all'
  }
}

// Search handler (for future use)
const onSearch = () => {
  // TODO: Implement search by hub name
}

const onSelectHub = (hub: any) => {
  selectedHubId.value = hub.uuid
  // Fly to hub on map
  if (hub.latitude && hub.longitude) {
    mapRef.value?.flyTo(Number(hub.latitude), Number(hub.longitude), 8)
  }
}

// Handle selection from map
const onMapSelect = (uuid: string) => {
  const hub = items.value.find(i => i.uuid === uuid)
  if (hub) {
    selectedHubId.value = uuid
  }
}

// Helper to get country for hub
const getCountryForHub = (hub: any) => {
  return itemsByCountry.value.filter(c => c.hubs.some(h => h.uuid === hub.uuid))
}

// Check if this hub is first in its country group
const isFirstInCountry = (hub: any) => {
  for (const country of itemsByCountry.value) {
    if (country.hubs[0]?.uuid === hub.uuid) return true
  }
  return false
}

await init()

useHead(() => ({
  title: t('catalogHubsSection.header.title')
}))
</script>
