<template>
  <div class="flex flex-col flex-1 min-h-0">
    <!-- Loading state -->
    <div v-if="loading" class="flex-1 flex items-center justify-center">
      <Card padding="lg">
        <Stack align="center" justify="center" gap="3">
          <Spinner />
          <Text tone="muted">{{ $t('catalogLanding.states.loading') }}</Text>
        </Stack>
      </Card>
    </div>

    <!-- Content -->
    <template v-else>
      <!-- Search bar slot (sticky third bar - like navigation) -->
      <div v-if="$slots.searchBar" class="sticky z-20 h-16 -mx-3 lg:-mx-6 px-3 lg:px-6 bg-base-100 border-b border-base-300" :style="searchBarStyle">
        <div class="flex items-center gap-2 h-full">
          <!-- Expand button - appears when header collapsed -->
          <button
            v-if="isCollapsed"
            class="btn btn-ghost btn-sm gap-1 flex-shrink-0"
            @click="expand"
          >
            <span class="font-bold text-primary text-lg">O</span>
            <Icon name="lucide:chevron-up" size="14" />
          </button>
          <div class="flex-1">
            <slot name="searchBar" :displayed-count="displayItems.length" :total-count="totalCount" />
          </div>
        </div>
      </div>

      <!-- With Map: Split Layout -->
      <template v-if="withMap">
        <!-- Desktop: side-by-side -->
        <div class="hidden lg:flex flex-1 gap-4 min-h-0 py-4">
          <!-- Left: List (scrollable) -->
          <div class="w-2/5 overflow-y-auto pr-2">
            <Stack gap="4">
              <slot name="header" />
              <slot name="filters" />

              <Stack gap="3">
                <div
                  v-for="item in displayItems"
                  :key="item.uuid"
                  :class="{ 'ring-2 ring-primary rounded-lg': item.uuid === selectedId }"
                  @click="onItemClick(item)"
                  @mouseenter="emit('update:hoveredId', item.uuid)"
                  @mouseleave="emit('update:hoveredId', undefined)"
                >
                  <slot name="card" :item="item" />
                </div>
              </Stack>

              <slot name="pagination" />

              <Stack v-if="displayItems.length === 0" align="center" gap="2">
                <slot name="empty">
                  <Text tone="muted">{{ $t('common.values.not_available') }}</Text>
                </slot>
              </Stack>
            </Stack>
          </div>

          <!-- Right: Map (fixed position) -->
          <div class="w-3/5 relative">
            <div class="fixed right-0 w-3/5 overflow-hidden" :style="mapStyle">
              <!-- 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="mapId"
                  :items="useServerClustering ? [] : itemsWithCoords"
                  :clustered-points="useServerClustering ? clusteredNodes : []"
                  :use-server-clustering="useServerClustering"
                  :point-color="pointColor"
                  :hovered-item-id="hoveredId"
                  :hovered-item="hoveredItem"
                  @select-item="onMapSelect"
                  @bounds-change="onBoundsChange"
                />
              </ClientOnly>
            </div>
          </div>
        </div>

        <!-- Mobile: toggle between list and map -->
        <div class="lg:hidden flex-1 flex flex-col min-h-0">
          <div class="flex-1 overflow-y-auto py-4" v-show="mobileView === 'list'">
            <Stack gap="4">
              <slot name="header" />
              <slot name="filters" />

              <Stack gap="3">
                <div
                  v-for="item in displayItems"
                  :key="item.uuid"
                  :class="{ 'ring-2 ring-primary rounded-lg': item.uuid === selectedId }"
                  @click="onItemClick(item)"
                  @mouseenter="emit('update:hoveredId', item.uuid)"
                  @mouseleave="emit('update:hoveredId', undefined)"
                >
                  <slot name="card" :item="item" />
                </div>
              </Stack>

              <slot name="pagination" />

              <Stack v-if="displayItems.length === 0" align="center" gap="2">
                <slot name="empty">
                  <Text tone="muted">{{ $t('common.values.not_available') }}</Text>
                </slot>
              </Stack>
            </Stack>
          </div>

          <div class="flex-1 relative" v-show="mobileView === 'map'">
            <!-- Search with map checkbox (mobile) -->
            <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="mobileMapRef"
                :map-id="`${mapId}-mobile`"
                :items="useServerClustering ? [] : itemsWithCoords"
                :clustered-points="useServerClustering ? clusteredNodes : []"
                :use-server-clustering="useServerClustering"
                :point-color="pointColor"
                :hovered-item-id="hoveredId"
                :hovered-item="hoveredItem"
                @select-item="onMapSelect"
                @bounds-change="onBoundsChange"
              />
            </ClientOnly>
          </div>

          <!-- Mobile toggle -->
          <div class="fixed bottom-4 left-1/2 -translate-x-1/2 z-30">
            <div class="btn-group shadow-lg">
              <button
                class="btn btn-sm"
                :class="{ 'btn-active': mobileView === 'list' }"
                @click="mobileView = 'list'"
              >
                {{ $t('common.list') }}
              </button>
              <button
                class="btn btn-sm"
                :class="{ 'btn-active': mobileView === 'map' }"
                @click="mobileView = 'map'"
              >
                {{ $t('common.map') }}
              </button>
            </div>
          </div>
        </div>
      </template>

      <!-- Without Map: Simple List -->
      <div v-else class="flex-1 overflow-y-auto py-4">
        <Stack gap="4">
          <slot name="header" />
          <slot name="filters" />

          <Stack gap="3">
            <div
              v-for="item in items"
              :key="item.uuid"
              @click="onItemClick(item)"
            >
              <slot name="card" :item="item" />
            </div>
          </Stack>

          <slot name="pagination" />

          <Stack v-if="items.length === 0" align="center" gap="2">
            <slot name="empty">
              <Text tone="muted">{{ $t('common.values.not_available') }}</Text>
            </slot>
          </Stack>
        </Stack>
      </div>
    </template>
  </div>
</template>

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

interface MapItem {
  uuid: string
  latitude?: number | null
  longitude?: number | null
  name?: string
  country?: string
  [key: string]: any
}

const props = withDefaults(defineProps<{
  items: MapItem[]
  mapItems?: MapItem[]  // Optional separate items for map (if different from list items)
  loading?: boolean
  withMap?: boolean
  useServerClustering?: boolean  // Use server-side h3 clustering for ALL points
  mapId?: string
  pointColor?: string
  selectedId?: string
  hoveredId?: string
  hasSubNav?: boolean
  totalCount?: number  // Total count for search bar counter (can differ from items.length with pagination)
}>(), {
  loading: false,
  withMap: true,
  useServerClustering: false,
  mapId: 'catalog-map',
  pointColor: '#3b82f6',
  hasSubNav: true,
  totalCount: 0
})

// Smooth scroll collapse - pixel values for smooth animation
// MainNav: 64px, SubNav: 54px, Header total: 118px, SearchBar: 64px
const { searchBarTop, mapTop, isCollapsed, expand } = useScrollCollapse(118, 64)

const slots = useSlots()
const hasSearchBar = computed(() => !!slots.searchBar)

// SearchBar style - smooth pixel positioning
const searchBarStyle = computed(() => ({
  top: `${searchBarTop.value}px`
}))

// Map style - smooth pixel positioning
const mapStyle = computed(() => ({
  top: hasSearchBar.value ? `${mapTop.value}px` : `${searchBarTop.value}px`,
  height: `calc(100vh - ${hasSearchBar.value ? mapTop.value : searchBarTop.value}px)`
}))

const emit = defineEmits<{
  'select': [item: MapItem]
  'update:selectedId': [uuid: string]
  'update:hoveredId': [uuid: string | undefined]
}>()

// Server-side clustering
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 (props.useServerClustering) {
    fetchClusters(bounds)
  }
}

// Filtered items when searchWithMap is enabled
const displayItems = computed(() => {
  if (!searchWithMap.value || !currentBounds.value) return props.items
  return props.items.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 (!props.hoveredId) return null
  const item = props.items.find(i => i.uuid === props.hoveredId)
  if (!item?.latitude || !item?.longitude) return null
  return { latitude: Number(item.latitude), longitude: Number(item.longitude) }
})

// Use mapItems if provided, otherwise fall back to items
const itemsForMap = computed(() => props.mapItems || props.items)

// Filter items with valid coordinates for map (client-side mode only)
const itemsWithCoords = computed(() =>
  itemsForMap.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,
    orderUuid: item.orderUuid  // Preserve orderUuid for hover matching
  }))
)

// Mobile view toggle
const mobileView = ref<'list' | 'map'>('list')

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

// Handle item click from list
const onItemClick = (item: MapItem) => {
  emit('select', item)
  emit('update:selectedId', item.uuid)

  // Fly to item on map
  if (props.withMap && item.latitude && item.longitude) {
    mapRef.value?.flyTo(Number(item.latitude), Number(item.longitude), 8)
    mobileMapRef.value?.flyTo(Number(item.latitude), Number(item.longitude), 8)
  }
}

// Handle selection from map
const onMapSelect = (uuid: string) => {
  const item = props.items.find(i => i.uuid === uuid)
  if (item) {
    emit('select', item)
    emit('update:selectedId', uuid)
  }
}

// Watch selectedId and fly to it
watch(() => props.selectedId, (uuid) => {
  if (uuid && props.withMap) {
    const item = itemsWithCoords.value.find(i => i.uuid === uuid)
    if (item) {
      mapRef.value?.flyTo(item.latitude, item.longitude, 8)
      mobileMapRef.value?.flyTo(item.latitude, item.longitude, 8)
    }
  }
})


// Expose flyTo for external use
const flyTo = (lat: number, lng: number, zoom = 8) => {
  mapRef.value?.flyTo(lat, lng, zoom)
  mobileMapRef.value?.flyTo(lat, lng, zoom)
}

defineExpose({ flyTo })
</script>
