<template>
  <div class="container mx-auto px-4 py-8 max-w-4xl">
    <PageHeader :title="$t('common.selectLocation')">
      <template #actions>
        <button class="btn btn-ghost" @click="router.back()">
          <Icon name="lucide:x" size="20" />
        </button>
      </template>
    </PageHeader>

    <Stack gap="8" class="mt-6">
      <!-- My addresses -->
      <Stack v-if="isAuthenticated && teamAddresses?.length" gap="4">
        <Heading :level="3">{{ $t('profileAddresses.header.title') }}</Heading>

        <Grid :cols="1" :md="2" :gap="4">
          <Card
            v-for="addr in teamAddresses"
            :key="addr.uuid"
            padding="small"
            interactive
            :class="{ 'ring-2 ring-primary': isSelected('address', addr.uuid) }"
            @click="selectAddress(addr)"
          >
            <Stack gap="2">
              <Stack direction="row" align="center" gap="2">
                <Icon name="lucide:map-pin" size="18" class="text-primary" />
                <Text size="base" weight="semibold">{{ addr.name }}</Text>
                <Pill v-if="addr.isDefault" variant="outline" size="sm">Default</Pill>
              </Stack>
              <Text tone="muted" size="sm">{{ addr.address }}</Text>
            </Stack>
          </Card>
        </Grid>
      </Stack>

      <!-- Hubs -->
      <Stack gap="4">
        <Heading :level="3">{{ $t('catalogMap.hubsTab') }}</Heading>

        <div v-if="pending" class="flex items-center justify-center p-8">
          <span class="loading loading-spinner loading-lg" />
        </div>

        <Alert v-else-if="error" variant="error">
          <Stack gap="2">
            <Heading :level="4" weight="semibold">{{ $t('common.error') }}</Heading>
            <Button @click="refresh()">{{ $t('common.retry') }}</Button>
          </Stack>
        </Alert>

        <EmptyState
          v-else-if="!hubs?.length"
          :title="$t('catalogMap.noHubs')"
        />

        <template v-else>
          <Grid :cols="1" :md="2" :gap="4">
            <HubCard
              v-for="hub in hubs"
              :key="hub.uuid"
              :hub="hub"
              selectable
              :class="{ 'ring-2 ring-primary': isSelected('hub', hub.uuid) }"
              @select="selectHub(hub)"
            />
          </Grid>

          <Stack v-if="totalHubs > 0" gap="2" align="center" justify="center">
            <Text tone="muted">
              {{ $t('common.pagination.showing', { shown: hubs.length, total: totalHubs }) }}
            </Text>
            <Button v-if="canLoadMore" variant="outline" @click="loadMore" :disabled="isLoadingMore">
              {{ $t('common.actions.load_more') }}
            </Button>
          </Stack>
        </template>
      </Stack>
    </Stack>
  </div>
</template>

<script setup lang="ts">
import { useLocationStore } from '~/stores/location'
import { GetNodesDocument } from '~/composables/graphql/public/geo-generated'

const router = useRouter()
const route = useRoute()
const { isAuthenticated } = useAuth()
const locationStore = useLocationStore()
const searchStore = useSearchStore()
const isSearchMode = computed(() => route.query.mode === 'search')
const { execute } = useGraphQL()
const PAGE_SIZE = 24

const hubs = ref<any[]>([])
const totalHubs = ref(0)
const isLoadingMore = ref(false)

// Load hubs
const { data: hubsData, pending, error, refresh } = await useServerQuery(
  'select-location-hubs',
  GetNodesDocument,
  { limit: PAGE_SIZE, offset: 0, transportType: null },
  'public',
  'geo'
)

watchEffect(() => {
  if (hubsData.value?.nodes) {
    hubs.value = hubsData.value.nodes
    totalHubs.value = hubsData.value.nodesCount ?? hubsData.value.nodes.length
  }
})

const canLoadMore = computed(() => hubs.value.length < totalHubs.value)

const loadMore = async () => {
  if (isLoadingMore.value) return
  isLoadingMore.value = true
  try {
    const data = await execute(
      GetNodesDocument,
      { limit: PAGE_SIZE, offset: hubs.value.length, transportType: null },
      'public',
      'geo'
    )
    const next = data?.nodes || []
    hubs.value = hubs.value.concat(next)
    totalHubs.value = data?.nodesCount ?? totalHubs.value
  } finally {
    isLoadingMore.value = false
  }
}

// Load team addresses
const teamAddresses = ref<any[]>([])

if (isAuthenticated.value) {
  try {
    const { GetTeamAddressesDocument } = await import('~/composables/graphql/team/teams-generated')
    const { data: addressesData } = await useServerQuery('select-location-addresses', GetTeamAddressesDocument, {}, 'team', 'teams')
    teamAddresses.value = addressesData.value?.teamAddresses || []
  } catch {
    // Not critical
  }
}

const isSelected = (type: 'address' | 'hub', uuid: string) => {
  return locationStore.selectedLocation?.type === type && locationStore.selectedLocation?.uuid === uuid
}

const goToRequestIfReady = () => {
  if (route.query.after === 'request' && searchStore.searchForm.productUuid && searchStore.searchForm.locationUuid) {
    router.push({
      path: '/request',
      query: {
        productUuid: searchStore.searchForm.productUuid,
        product: searchStore.searchForm.product,
        locationUuid: searchStore.searchForm.locationUuid,
        location: searchStore.searchForm.location,
        quantity: searchStore.searchForm.quantity || undefined
      }
    })
    return true
  }
  return false
}

const selectHub = async (hub: any) => {
  if (isSearchMode.value) {
    searchStore.setLocation(hub.name)
    searchStore.setLocationUuid(hub.uuid)
    if (goToRequestIfReady()) return
    router.back()
    return
  }

  const success = await locationStore.select('hub', hub.uuid, hub.name, hub.latitude, hub.longitude)
  if (success) router.back()
}

const selectAddress = async (addr: any) => {
  if (isSearchMode.value) {
    searchStore.setLocation(addr.address || addr.name)
    searchStore.setLocationUuid(addr.uuid)
    if (goToRequestIfReady()) return
    router.back()
    return
  }

  const success = await locationStore.select('address', addr.uuid, addr.name, addr.latitude, addr.longitude)
  if (success) router.back()
}
</script>
