<template>
  <div class="space-y-10">
    <Card padding="lg" class="border border-base-300">
      <RouteSummaryHeader :title="summaryTitle" :meta="summaryMeta" />
    </Card>

    <div v-if="pending" class="text-sm text-base-content/60">
      Загрузка маршрутов...
    </div>

    <div v-else-if="error" class="text-sm text-error">
      Ошибка загрузки маршрутов: {{ error.message }}
    </div>

    <div v-else-if="productRouteOptions.length > 0 || legacyRoutes.length > 0" class="space-y-10">
      <div v-if="productRouteOptions.length" class="space-y-10">
        <div
          v-for="(option, optionIndex) in productRouteOptions"
          :key="option.sourceUuid || optionIndex"
          class="space-y-6"
        >
          <div class="space-y-1">
            <Heading :level="3" weight="semibold">Источник {{ optionIndex + 1 }}</Heading>
            <Text tone="muted" size="sm">{{ option.sourceName || 'Склад' }}</Text>
          </div>

          <div v-if="option.routes?.length" class="space-y-6">
            <Card
              v-for="(route, routeIndex) in option.routes"
              :key="routeIndex"
              padding="lg"
              class="border border-base-300"
            >
              <Stack gap="4">
                <div class="flex flex-wrap items-center justify-between gap-2">
                  <Text weight="semibold">Маршрут {{ routeIndex + 1 }}</Text>
                  <Text tone="muted" size="sm">
                    {{ formatDistance(route.totalDistanceKm) }} км · {{ formatDuration(route.totalTimeSeconds) }}
                  </Text>
                </div>

                <RouteStagesList :stages="mapRouteStages(route)" />

                <div class="divider my-0"></div>

                <RequestRoutesMap :routes="[route]" :height="240" />
              </Stack>
            </Card>
          </div>

          <Text v-else tone="muted" size="sm">
            Маршруты от источника не найдены.
          </Text>
        </div>
      </div>

      <template v-if="!productRouteOptions.length && legacyRoutes.length">
        <div class="space-y-6">
          <Card
            v-for="(route, routeIndex) in legacyRoutes"
            :key="routeIndex"
            padding="lg"
            class="border border-base-300"
          >
            <Stack gap="4">
              <div class="flex flex-wrap items-center justify-between gap-2">
                <Text weight="semibold">Маршрут {{ routeIndex + 1 }}</Text>
                <Text tone="muted" size="sm">
                  {{ formatDistance(route.totalDistanceKm) }} км · {{ formatDuration(route.totalTimeSeconds) }}
                </Text>
              </div>

              <RouteStagesList :stages="mapRouteStages(route)" />

              <div class="divider my-0"></div>

              <RequestRoutesMap :routes="[route]" :height="240" />
            </Stack>
          </Card>
        </div>
      </template>
    </div>

    <div v-else class="text-sm text-base-content/60">
      Маршруты не найдены. Возможно, нет связи между точками в графе.
    </div>
  </div>
</template>

<script setup lang="ts">
import { FindRoutesDocument } from '~/composables/graphql/public/geo-generated'
import type { RoutePathType } from '~/composables/graphql/public/geo-generated'
import type { RouteStageItem } from '~/components/RouteStagesList.vue'

const route = useRoute()
const searchStore = useSearchStore()

const productName = computed(() => searchStore.searchForm.product || (route.query.product as string) || 'Товар')
const locationName = computed(() => searchStore.searchForm.location || (route.query.location as string) || 'Назначение')
const quantity = computed(() => (route.query.quantity as string) || (searchStore.searchForm as any)?.quantity)

const summaryTitle = computed(() => `${productName.value} → ${locationName.value}`)
const summaryMeta = computed(() => {
  const meta: string[] = []
  if (quantity.value) {
    meta.push(`${quantity.value}`)
  }
  return meta
})

// Determine context (new flow: product + destination; legacy: from param)
const productUuid = computed(() => (route.query.productUuid as string) || searchStore.searchForm.productUuid)
const destinationUuid = computed(() => (route.query.locationUuid as string) || searchStore.searchForm.locationUuid)
const legacyFromUuid = computed(() => route.params.id as string | undefined)

type ProductRouteOption = {
  sourceUuid?: string | null
  sourceName?: string | null
  sourceLat?: number | null
  sourceLon?: number | null
  distanceKm?: number | null
  routes?: RoutePathType[] | null
}

const fetchProductRoutes = async () => {
  if (!productUuid.value || !destinationUuid.value) return null
  const { client } = useApolloClient('publicGeo')
  const { default: gql } = await import('graphql-tag')

  const query = gql`
    query FindProductRoutes($productUuid: String!, $toUuid: String!, $limitSources: Int, $limitRoutes: Int) {
      findProductRoutes(
        productUuid: $productUuid
        toUuid: $toUuid
        limitSources: $limitSources
        limitRoutes: $limitRoutes
      ) {
        sourceUuid
        sourceName
        sourceLat
        sourceLon
        distanceKm
        routes {
          totalDistanceKm
          totalTimeSeconds
          stages {
            fromUuid
            fromName
            fromLat
            fromLon
            toUuid
            toName
            toLat
            toLon
            distanceKm
            travelTimeSeconds
            transportType
          }
        }
      }
    }
  `

  const { data } = await client.query({
    query,
    variables: {
      productUuid: productUuid.value,
      toUuid: destinationUuid.value,
      limitSources: 5,
      limitRoutes: 1
    }
  })
  return data
}

const fetchLegacyRoutes = async () => {
  if (!legacyFromUuid.value || !destinationUuid.value) return null
  const { client } = useApolloClient('publicGeo')
  const { data } = await client.query({
    query: FindRoutesDocument,
    variables: {
      fromUuid: legacyFromUuid.value,
      toUuid: destinationUuid.value,
      limit: 3
    }
  })
  return data
}

const { data: productRoutesData, pending, error } = await useAsyncData(
  () => `product-routes-${productUuid.value}-${destinationUuid.value}-${legacyFromUuid.value || 'none'}`,
  async () => {
    // Prefer product-based routes; fallback to legacy if no product
    if (productUuid.value && destinationUuid.value) {
      return await fetchProductRoutes()
    }
    if (legacyFromUuid.value && destinationUuid.value) {
      return await fetchLegacyRoutes()
    }
    return null
  },
  { watch: [productUuid, destinationUuid, legacyFromUuid] }
)

const productRouteOptions = computed(() => {
  const options = productRoutesData.value?.findProductRoutes as ProductRouteOption[] | undefined
  return options?.filter(Boolean) || []
})

const legacyRoutes = computed(() => {
  const data = productRoutesData.value?.findRoutes
  if (!data) return []
  return (data as (RoutePathType | null)[]).filter((r): r is RoutePathType => r !== null)
})

const mapRouteStages = (route: RoutePathType): RouteStageItem[] => {
  return (route.stages || [])
    .filter(Boolean)
    .map((stage, index) => ({
      key: stage?.fromUuid || `stage-${index}`,
      from: stage?.fromName || 'Начало',
      to: stage?.toName || 'Конец',
      distanceKm: stage?.distanceKm,
      durationSeconds: stage?.travelTimeSeconds,
      transportType: stage?.transportType
    }))
}

// Formatting helpers
const formatDistance = (km: number | null | undefined) => {
  if (!km) return '0'
  return Math.round(km).toLocaleString()
}

const formatDuration = (seconds: number | null | undefined) => {
  if (!seconds) return '-'
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  if (hours > 24) {
    const days = Math.floor(hours / 24)
    const remainingHours = hours % 24
    return `${days}д ${remainingHours}ч`
  }
  if (hours > 0) {
    return `${hours}ч ${minutes}м`
  }
  return `${minutes}м`
}
</script>
