<template>
  <Stack gap="0">
    <!-- Loading -->
    <Section v-if="isLoading" variant="plain" paddingY="lg">
      <Stack align="center" justify="center" gap="4">
        <Spinner />
        <Text tone="muted">{{ t('catalogHub.states.loading') }}</Text>
      </Stack>
    </Section>

    <!-- Error / Not Found -->
    <Section v-else-if="!hub" variant="plain" paddingY="lg">
      <Card padding="lg">
        <Stack align="center" gap="4">
          <IconCircle tone="primary">
            <Icon name="lucide:map-pin" size="24" />
          </IconCircle>
          <Heading :level="2">{{ t('catalogHub.not_found.title') }}</Heading>
          <Text tone="muted">{{ t('catalogHub.not_found.subtitle') }}</Text>
          <Button @click="navigateTo(localePath('/catalog'))">
            {{ t('catalogHub.actions.back_to_catalog') }}
          </Button>
        </Stack>
      </Card>
    </Section>

    <template v-else>
      <!-- Map Hero -->
      <MapHero
        :title="hub.name"
        :location="mapLocation"
        :badges="hubBadges"
      />

      <!-- Offers Section -->
      <Section v-if="offers.length > 0" variant="plain" paddingY="md">
        <Stack gap="4">
          <Heading :level="2">{{ t('catalogHub.sections.offers.title') }}</Heading>
          <Grid :cols="1" :md="2" :lg="3" :gap="4">
            <OfferCard
              v-for="offer in offers"
              :key="offer.uuid"
              :offer="offer"
            />
          </Grid>
        </Stack>
      </Section>

      <!-- Empty offers state -->
      <Section v-else variant="plain" paddingY="md">
        <Card padding="lg">
          <Stack align="center" gap="4">
            <IconCircle tone="primary">
              <Icon name="lucide:package-x" size="24" />
            </IconCircle>
            <Heading :level="3">{{ t('catalogHub.empty.offers.title') }}</Heading>
            <Text tone="muted" align="center">
              {{ t('catalogHub.empty.offers.subtitle') }}
            </Text>
          </Stack>
        </Card>
      </Section>

      <!-- Suppliers Section -->
      <Section v-if="uniqueSuppliers.length > 0" variant="plain" paddingY="md">
        <Stack gap="4">
            <Heading :level="2">{{ t('catalogHub.sections.suppliers.title') }}</Heading>
            <Grid :cols="1" :md="2" :lg="3" :gap="4">
            <SupplierCard
              v-for="supplier in uniqueSuppliers"
              :key="supplier.teamUuid"
              :supplier="supplier"
            />
          </Grid>
        </Stack>
      </Section>

      <!-- Products Section -->
      <Section v-if="uniqueProducts.length > 0" variant="plain" paddingY="md">
        <Stack gap="4">
          <Heading :level="2">{{ t('catalogHub.sections.products.title') }}</Heading>
          <Stack direction="row" gap="2" wrap>
            <NuxtLink
              v-for="product in uniqueProducts"
              :key="product.uuid"
              :to="localePath(`/catalog/products/${product.uuid}`)"
            >
              <Pill variant="primary" class="hover:bg-primary hover:text-white transition-colors cursor-pointer">
                {{ product.name }}
              </Pill>
            </NuxtLink>
          </Stack>
        </Stack>
      </Section>

      <!-- Nearby Connections -->
      <NearbyConnectionsSection
        :auto-edges="autoEdges"
        :rail-edges="railEdges"
        :hub="currentHubForMap"
        :rail-hub="railHubForMap"
        :auto-route-geometries="autoRouteGeometries"
        :rail-route-geometries="railRouteGeometries"
      />

    </template>
  </Stack>
</template>

<script setup lang="ts">
import { GetLocationOffersDocument, GetSuppliersDocument } from '~/composables/graphql/public/exchange-generated'
import { GetNodeConnectionsDocument, GetAutoRouteDocument, GetRailRouteDocument } from '~/composables/graphql/public/geo-generated'
import type { EdgeType } from '~/composables/graphql/public/geo-generated'

interface RouteGeometry {
  toUuid: string
  coordinates: [number, number][]
}

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

const isLoading = ref(true)
const hub = ref<any>(null)
const railHub = ref<any>(null)
const offers = ref<any[]>([])
const allSuppliers = ref<any[]>([])
const autoEdges = ref<EdgeType[]>([])
const railEdges = ref<EdgeType[]>([])
const autoRouteGeometries = ref<RouteGeometry[]>([])
const railRouteGeometries = ref<RouteGeometry[]>([])

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

// Map location
const mapLocation = computed(() => ({
  uuid: hub.value?.uuid,
  name: hub.value?.name,
  latitude: hub.value?.latitude,
  longitude: hub.value?.longitude,
  country: hub.value?.country,
  countryCode: hub.value?.countryCode
}))

// Badges for MapHero
const hubBadges = computed(() => {
  const badges: Array<{ icon?: string; text: string }> = []
  if (hub.value?.country) {
    badges.push({ icon: 'lucide:globe', text: hub.value.country })
  }
  if (offers.value.length > 0) {
    badges.push({ icon: 'lucide:package', text: t('catalogHub.badges.offers', { count: offers.value.length }) })
  }
  if (hub.value?.latitude && hub.value?.longitude) {
    badges.push({ icon: 'lucide:map-pin', text: `${hub.value.latitude.toFixed(2)}°, ${hub.value.longitude.toFixed(2)}°` })
  }
  return badges
})

// Unique suppliers
const uniqueSuppliers = computed(() => {
  const suppliers = new Map<string, { teamUuid: string; name: string; offersCount: number }>()
  offers.value.forEach(offer => {
    if (offer.teamUuid) {
      const existing = suppliers.get(offer.teamUuid)
      const supplierInfo = allSuppliers.value.find(s => s.teamUuid === offer.teamUuid)
      if (existing) {
        existing.offersCount++
      } else {
        suppliers.set(offer.teamUuid, {
          teamUuid: offer.teamUuid,
          name: supplierInfo?.name || t('catalogHub.labels.default_supplier'),
          offersCount: 1
        })
      }
    }
  })
  return Array.from(suppliers.values())
})

// Unique products
const uniqueProducts = computed(() => {
  const products = new Map<string, { uuid: string; name: string }>()
  offers.value.forEach(offer => {
    offer.lines?.forEach((line: any) => {
      if (line?.productUuid && line?.productName) {
        products.set(line.productUuid, { uuid: line.productUuid, name: line.productName })
      }
    })
  })
  return Array.from(products.values())
})

// Current hub for NearbyConnectionsSection
const currentHubForMap = computed(() => ({
  uuid: hub.value?.uuid || '',
  name: hub.value?.name || '',
  latitude: hub.value?.latitude || 0,
  longitude: hub.value?.longitude || 0
}))

const railHubForMap = computed(() => ({
  uuid: railHub.value?.uuid || hub.value?.uuid || '',
  name: railHub.value?.name || hub.value?.name || '',
  latitude: railHub.value?.latitude || hub.value?.latitude || 0,
  longitude: railHub.value?.longitude || hub.value?.longitude || 0
}))

// Load route geometries for edges
const loadRouteGeometries = async (
  edges: EdgeType[],
  hubLat: number,
  hubLon: number,
  transportType: 'auto' | 'rail'
): Promise<RouteGeometry[]> => {
  const RouteDocument = transportType === 'auto' ? GetAutoRouteDocument : GetRailRouteDocument
  const routeField = transportType === 'auto' ? 'autoRoute' : 'railRoute'

  const filteredEdges = edges
    .filter(e => e?.transportType === transportType && e?.toLatitude && e?.toLongitude)
    .sort((a, b) => (a.distanceKm || 0) - (b.distanceKm || 0))
    .slice(0, 12)

  const routePromises = filteredEdges.map(async (edge) => {
    try {
      const { data: routeDataResponse } = await useServerQuery(
        `hub-route-${transportType}-${edge.toUuid}`,
        RouteDocument,
        {
          fromLat: hubLat,
          fromLon: hubLon,
          toLat: edge.toLatitude!,
          toLon: edge.toLongitude!
        },
        'public',
        'geo'
      )

      const routeData = routeDataResponse.value?.[routeField]
      if (routeData?.geometry) {
        const geometryArray = typeof routeData.geometry === 'string'
          ? JSON.parse(routeData.geometry)
          : routeData.geometry

        if (Array.isArray(geometryArray) && geometryArray.length > 0) {
          return {
            toUuid: edge.toUuid!,
            coordinates: geometryArray as [number, number][]
          }
        }
      }
    } catch (error) {
      console.error(`Failed to load ${transportType} route to ${edge.toName}:`, error)
    }
    return null
  })

  const results = await Promise.all(routePromises)
  return results.filter(Boolean) as RouteGeometry[]
}

try {
  const [{ data: connectionsData }, { data: offersData }, { data: suppliersData }] = await Promise.all([
    useServerQuery('hub-connections', GetNodeConnectionsDocument, { uuid: hubId.value }, 'public', 'geo'),
    useServerQuery('hub-offers', GetLocationOffersDocument, { locationUuid: hubId.value }, 'public', 'exchange'),
    useServerQuery('hub-suppliers', GetSuppliersDocument, {}, 'public', 'exchange')
  ])

  const connectionsResult = connectionsData.value
  hub.value = connectionsResult?.nodeConnections?.hub || null
  railHub.value = connectionsResult?.nodeConnections?.railNode || null
  offers.value = offersData.value?.getOffers || []
  allSuppliers.value = suppliersData.value?.getSuppliers || []
  autoEdges.value = (connectionsResult?.nodeConnections?.autoEdges || []).filter((e): e is EdgeType => e !== null)
  railEdges.value = (connectionsResult?.nodeConnections?.railEdges || []).filter((e): e is EdgeType => e !== null)

  if (hub.value?.latitude && hub.value?.longitude) {
    const railOrigin = railHub.value || hub.value
    const [autoGeometries, railGeometries] = await Promise.all([
      loadRouteGeometries(autoEdges.value, hub.value.latitude, hub.value.longitude, 'auto'),
      loadRouteGeometries(railEdges.value, railOrigin.latitude, railOrigin.longitude, 'rail')
    ])
    autoRouteGeometries.value = autoGeometries
    railRouteGeometries.value = railGeometries
  }
} 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 || '',
        offers: offers.value.length,
        suppliers: uniqueSuppliers.value.length
      })
    }
  ]
}))
</script>
