<template>
  <div class="fixed inset-0 flex flex-col">
    <!-- Loading state -->
    <div v-if="loading" class="absolute inset-0 z-50 flex items-center justify-center bg-base-100/80">
      <Card padding="lg">
        <Stack align="center" justify="center" gap="3">
          <Spinner />
          <Text tone="muted">{{ $t('catalogLanding.states.loading') }}</Text>
        </Stack>
      </Card>
    </div>

    <!-- Fullscreen Map -->
    <div class="absolute inset-0">
      <ClientOnly>
        <CatalogMap
          ref="mapRef"
          :map-id="mapId"
          :items="isInfoMode ? [] : (useServerClustering ? [] : itemsWithCoords)"
          :clustered-points="isInfoMode ? [] : (useServerClustering ? clusteredNodes : [])"
          :use-server-clustering="useServerClustering && !isInfoMode"
          :point-color="activePointColor"
          :entity-type="activeEntityType"
          :hovered-item-id="hoveredId"
          :hovered-item="hoveredItem"
          :related-points="relatedPoints"
          @select-item="onMapSelect"
          @bounds-change="onBoundsChange"
        />
      </ClientOnly>
    </div>

    <!-- View mode loading indicator -->
    <div
      v-if="clusterLoading"
      class="absolute top-[116px] left-1/2 -translate-x-1/2 z-30 flex items-center gap-2 bg-black/50 backdrop-blur-md rounded-full px-4 py-2 border border-white/20"
    >
      <span class="loading loading-spinner loading-sm text-white" />
      <span class="text-white text-sm">{{ $t('common.loading') }}</span>
    </div>

    <!-- List button (LEFT, opens panel) - hide when panel is open -->
    <button
      v-if="!isPanelOpen"
      class="absolute top-[116px] left-4 z-20 hidden lg:flex items-center gap-2 bg-black/30 backdrop-blur-md rounded-lg px-3 py-1.5 border border-white/10 text-white text-sm hover:bg-black/40 transition-colors"
      @click="openPanel"
    >
      <Icon name="lucide:menu" size="16" />
      <span>{{ $t('catalog.list') }}</span>
    </button>

    <!-- Filter by bounds checkbox (LEFT, next to panel when open) - only in selection mode -->
    <label
      v-if="selectMode !== null"
      class="absolute top-[116px] left-[420px] z-20 hidden lg:flex items-center gap-2 bg-black/30 backdrop-blur-md rounded-lg px-3 py-1.5 border border-white/10 cursor-pointer text-white text-sm hover:bg-black/40 transition-colors"
    >
      <input
        type="checkbox"
        :checked="filterByBounds"
        class="checkbox checkbox-xs checkbox-primary"
        @change="$emit('update:filter-by-bounds', ($event.target as HTMLInputElement).checked)"
      />
      <span>{{ $t('catalog.search.filterByMap') }}</span>
    </label>


    <!-- View toggle (top RIGHT overlay, below header) -->
    <div class="absolute top-[116px] right-4 z-20 hidden lg:flex items-center gap-2">
      <!-- View mode toggle -->
      <div class="flex gap-1 bg-black/30 backdrop-blur-md rounded-lg p-1 border border-white/10">
        <button
          class="flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-colors"
          :class="mapViewMode === 'offers' ? 'bg-white/20 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'"
          @click="setMapViewMode('offers')"
        >
          <span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #f97316">
            <Icon name="lucide:shopping-bag" size="12" class="text-white" />
          </span>
          {{ $t('catalog.views.offers') }}
        </button>
        <button
          class="flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-colors"
          :class="mapViewMode === 'hubs' ? 'bg-white/20 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'"
          @click="setMapViewMode('hubs')"
        >
          <span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #22c55e">
            <Icon name="lucide:warehouse" size="12" class="text-white" />
          </span>
          {{ $t('catalog.views.hubs') }}
        </button>
        <button
          class="flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-colors"
          :class="mapViewMode === 'suppliers' ? 'bg-white/20 text-white' : 'text-white/70 hover:text-white hover:bg-white/10'"
          @click="setMapViewMode('suppliers')"
        >
          <span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
            <Icon name="lucide:factory" size="12" class="text-white" />
          </span>
          {{ $t('catalog.views.suppliers') }}
        </button>
      </div>
    </div>

    <!-- Left panel (slides from left when isPanelOpen is true) -->
    <Transition name="slide-left">
      <div
        v-if="isPanelOpen"
        class="absolute top-[116px] left-4 bottom-4 z-30 w-96 max-w-[calc(100vw-2rem)] hidden lg:block"
      >
        <div class="bg-black/50 backdrop-blur-md rounded-xl shadow-lg border border-white/10 h-full flex flex-col text-white">
          <slot name="panel" />
        </div>
      </div>
    </Transition>

    <!-- Mobile bottom sheet -->
    <div class="lg:hidden absolute bottom-0 left-0 right-0 z-20">
      <!-- Mobile controls: List button + view toggle -->
      <div class="flex justify-between px-4 mb-2">
        <!-- List button (mobile) -->
        <button
          class="flex items-center gap-2 bg-black/30 backdrop-blur-md rounded-lg px-3 py-2 border border-white/10 text-white text-sm"
          @click="openPanel"
        >
          <Icon name="lucide:menu" size="16" />
          <span>{{ $t('catalog.list') }}</span>
        </button>

        <!-- Mobile view toggle -->
        <div class="flex gap-1 bg-black/30 backdrop-blur-md rounded-lg p-1 border border-white/10">
          <button
            class="flex items-center justify-center w-8 h-8 rounded-md transition-colors"
            :class="mapViewMode === 'offers' ? 'bg-white/20' : 'hover:bg-white/10'"
            @click="setMapViewMode('offers')"
          >
            <span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #f97316">
              <Icon name="lucide:shopping-bag" size="12" class="text-white" />
            </span>
          </button>
          <button
            class="flex items-center justify-center w-8 h-8 rounded-md transition-colors"
            :class="mapViewMode === 'hubs' ? 'bg-white/20' : 'hover:bg-white/10'"
            @click="setMapViewMode('hubs')"
          >
            <span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #22c55e">
              <Icon name="lucide:warehouse" size="12" class="text-white" />
            </span>
          </button>
          <button
            class="flex items-center justify-center w-8 h-8 rounded-md transition-colors"
            :class="mapViewMode === 'suppliers' ? 'bg-white/20' : 'hover:bg-white/10'"
            @click="setMapViewMode('suppliers')"
          >
            <span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
              <Icon name="lucide:factory" size="12" class="text-white" />
            </span>
          </button>
        </div>
      </div>

      <!-- Mobile panel (collapsible) - only when panel is open -->
      <Transition name="slide-up">
        <div
          v-if="isPanelOpen"
          class="bg-black/50 backdrop-blur-md rounded-t-xl shadow-lg border border-white/10 transition-all duration-300 text-white h-[60vh]"
        >
          <!-- Drag handle / close -->
          <div
            class="flex justify-center py-2 cursor-pointer"
            @click="closePanel"
          >
            <div class="w-10 h-1 bg-white/30 rounded-full" />
          </div>

          <div class="px-4 pb-4 overflow-y-auto h-[calc(60vh-2rem)]">
            <slot name="panel" />
          </div>
        </div>
      </Transition>
    </div>
  </div>
</template>

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

const { mapViewMode, setMapViewMode, selectMode, startSelect, cancelSelect } = useCatalogSearch()

// Panel is open when selectMode is set OR when showPanel prop is true (info/quote)
const isPanelOpen = computed(() => props.showPanel || selectMode.value !== null)

// Open panel based on current mapViewMode
const openPanel = () => {
  const newSelectMode = mapViewMode.value === 'hubs' ? 'hub'
    : mapViewMode.value === 'suppliers' ? 'supplier'
    : 'product'
  startSelect(newSelectMode)
}

// Close panel
const closePanel = () => {
  cancelSelect()
}

// Point color based on map view mode
const VIEW_MODE_COLORS = {
  offers: '#f97316',   // orange
  hubs: '#22c55e',     // green
  suppliers: '#3b82f6' // blue
} as const

const activePointColor = computed(() => VIEW_MODE_COLORS[mapViewMode.value] || VIEW_MODE_COLORS.offers)

// Entity type for icons based on view mode
const VIEW_MODE_ENTITY_TYPES = {
  offers: 'offer',
  hubs: 'hub',
  suppliers: 'supplier'
} as const

const activeEntityType = computed(() => VIEW_MODE_ENTITY_TYPES[mapViewMode.value] || VIEW_MODE_ENTITY_TYPES.offers)

// Node type for server clustering based on view mode
const VIEW_MODE_NODE_TYPES = {
  offers: 'offer',
  hubs: 'logistics',
  suppliers: 'supplier'
} as const

const activeClusterNodeType = computed(() => VIEW_MODE_NODE_TYPES[mapViewMode.value] || VIEW_MODE_NODE_TYPES.offers)

// Store current bounds for refetching when view mode changes
const currentBounds = ref<MapBounds | null>(null)

interface MapItem {
  uuid?: string | null
  latitude?: number | null
  longitude?: number | null
  name?: string | null
  country?: string | null
}

const props = withDefaults(defineProps<{
  loading?: boolean
  useServerClustering?: boolean
  clusterNodeType?: string
  mapId?: string
  pointColor?: string
  hoveredId?: string
  items?: MapItem[]
  showPanel?: boolean
  filterByBounds?: boolean
  relatedPoints?: Array<{
    uuid: string
    name: string
    latitude: number
    longitude: number
    type: 'hub' | 'supplier' | 'offer'
  }>
}>(), {
  loading: false,
  useServerClustering: true,
  clusterNodeType: 'offer',
  mapId: 'catalog-map',
  pointColor: '#f97316',
  items: () => [],
  showPanel: false,
  filterByBounds: false,
  relatedPoints: () => []
})

const emit = defineEmits<{
  'select': [item: MapItem]
  'bounds-change': [bounds: MapBounds]
  'update:hoveredId': [uuid: string | undefined]
  'update:filter-by-bounds': [value: boolean]
}>()

// Server-side clustering - use computed node type based on view mode
const { clusteredNodes, fetchClusters, loading: clusterLoading, clearNodes } = useClusteredNodes(undefined, activeClusterNodeType)

// Refetch clusters when view mode changes
watch(mapViewMode, async () => {
  // Clear old data first
  clearNodes()
  // Refetch with current bounds if available
  if (currentBounds.value) {
    await fetchClusters(currentBounds.value)
  }
})

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

// Selected item from map click
const selectedMapItem = ref<MapItem | null>(null)

// Mobile panel state
const mobilePanelExpanded = ref(false)

// Info mode - when relatedPoints are present, hide clusters and show only related points
const isInfoMode = computed(() => props.relatedPoints && props.relatedPoints.length > 0)

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

// Filter items with valid coordinates for map (client-side mode only)
const itemsWithCoords = computed(() =>
  props.items.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
  }))
)

const onBoundsChange = (bounds: MapBounds) => {
  currentBounds.value = bounds
  emit('bounds-change', bounds)
  // Don't fetch clusters when in info mode
  if (props.useServerClustering && !isInfoMode.value) {
    fetchClusters(bounds)
  }
}

// Handle selection from map
const onMapSelect = (uuid: string, properties?: Record<string, any>) => {
  const item = props.items.find(i => i.uuid === uuid)
  if (item) {
    selectedMapItem.value = item
    emit('select', item)
  } else if (props.useServerClustering) {
    // For server clustering, include properties from cluster data
    const mapItem: MapItem = {
      uuid,
      name: properties?.name,
      ...properties
    }
    selectedMapItem.value = mapItem
    emit('select', mapItem)
  }
}

const onViewDetails = (item: MapItem) => {
  emit('select', item)
}

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

defineExpose({ flyTo, currentBounds })
</script>

<style scoped>
/* Drawer slide animation (desktop - left) */
.slide-left-enter-active,
.slide-left-leave-active {
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.slide-left-enter-from,
.slide-left-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}

/* Drawer slide animation (mobile - up) */
.slide-up-enter-active,
.slide-up-leave-active {
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.slide-up-enter-from,
.slide-up-leave-to {
  transform: translateY(100%);
  opacity: 0;
}
</style>
