<template>
  <Section variant="plain">
    <Stack gap="6">
        <Heading :level="1">{{ t('ordersDetail.header.title', { id: order?.name || route.params.id }) }}</Heading>

        <Alert v-if="hasOrderError" variant="error">
          <Stack gap="2">
            <Heading :level="4" weight="semibold">{{ t('ordersDetail.errors.title') }}</Heading>
            <Text tone="muted">{{ orderError }}</Text>
            <Button @click="loadOrder">{{ t('ordersDetail.errors.retry') }}</Button>
          </Stack>
        </Alert>

        <Card v-else-if="isLoadingOrder" tone="muted" padding="lg">
          <Stack align="center" justify="center" gap="3">
            <Spinner />
            <Text tone="muted">{{ t('ordersDetail.states.loading') }}</Text>
          </Stack>
        </Card>

        <template v-else>
          <Card padding="lg">
            <Stack gap="4">
              <Stack direction="row" gap="3" align="center" wrap>
                <Text weight="semibold">{{ order?.sourceLocationName }}</Text>
                <Text tone="muted">→</Text>
                <Text weight="semibold">{{ order?.destinationLocationName }}</Text>
              </Stack>
              <Grid :cols="1" :md="3" :gap="4">
                <Stack align="center" gap="1">
                  <Heading :level="3">{{ order?.orderLines?.[0]?.quantity || 0 }} {{ order?.orderLines?.[0]?.unit || t('ordersDetail.labels.unit_tons') }}</Heading>
                  <Text tone="muted">{{ order?.orderLines?.[0]?.productName || t('ordersDetail.labels.product_unknown') }}</Text>
                </Stack>
                <Stack align="center" gap="1">
                  <Heading :level="3">{{ formatPrice(order?.totalAmount) }}</Heading>
                  <Text tone="muted">{{ order?.currency }}</Text>
                </Stack>
                <Stack align="center" gap="1">
                  <Heading :level="3">{{ getOrderDuration() }}</Heading>
                  <Text tone="muted">{{ t('ordersDetail.labels.delivery_days') }}</Text>
                </Stack>
              </Grid>
            </Stack>
          </Card>

          <Stack gap="4">
            <Heading :level="2">{{ t('ordersDetail.sections.stages.title') }}</Heading>
            <Stack v-if="order?.stages?.length" gap="5">
              <Stack
                v-for="stage in order.stages"
                :key="stage.uuid"
                gap="3"
              >
                <Stack direction="row" align="center" justify="between">
                  <Stack gap="1">
                    <Heading :level="3" weight="semibold">{{ stage.name }}</Heading>
                    <Text tone="muted" size="base">{{ getStageDateRange(stage) }}</Text>
                  </Stack>
                  <Pill variant="outline">{{ stage.stageType }}</Pill>
                </Stack>

                <Card padding="lg" class="border border-base-300 bg-base-100">
                  <Grid :cols="1" :md="2" :gap="4">
                    <Stack gap="2">
                      <Heading :level="4" weight="semibold">{{ t('ordersDetail.sections.stages.companies.title') }}</Heading>
                      <Stack v-if="getCompaniesSummary(stage).length" gap="2">
                        <Stack
                          v-for="companySummary in getCompaniesSummary(stage)"
                          :key="companySummary.name"
                          direction="row"
                          align="center"
                          justify="between"
                        >
                          <Text weight="semibold">{{ companySummary.name }}</Text>
                          <Text tone="muted" size="base">
                            {{ companySummary.totalWeight || 0 }}{{ t('ordersDetail.labels.weight_unit') }} · {{ companySummary.tripsCount || 0 }} {{ t('ordersDetail.labels.trips') }}
                          </Text>
                        </Stack>
                      </Stack>
                      <Text v-else tone="muted">{{ t('ordersDetail.sections.stages.companies.empty') }}</Text>
                    </Stack>

                    <Stack gap="2">
                      <Heading :level="4" weight="semibold">{{ t('ordersDetail.sections.stages.route_title') }}</Heading>
                      <div class="rounded-2xl border border-base-200 bg-base-100 overflow-hidden">
                        <ClientOnly>
                          <MapboxGlobe
                            :map-id="`stage-map-${stage.uuid}`"
                            :locations="stageLocations(stage)"
                            :height="220"
                            :initial-zoom="3"
                          />
                        </ClientOnly>
                      </div>
                    </Stack>
                  </Grid>
                </Card>
              </Stack>
            </Stack>
            <Text v-else tone="muted">{{ t('ordersDetail.sections.stages.empty') }}</Text>
          </Stack>

          <Stack gap="3">
            <Heading :level="2">{{ t('ordersDetail.sections.map.title') }}</Heading>
            <div class="rounded-2xl border border-base-300 bg-base-100 overflow-hidden">
              <ClientOnly>
                <MapboxGlobe
                  map-id="order-map"
                  :locations="orderLocations"
                  :height="300"
                  :initial-zoom="3"
                />
              </ClientOnly>
            </div>
          </Stack>

          <Card padding="lg">
            <Stack gap="3">
              <Heading :level="2">{{ t('ordersDetail.sections.timeline.title') }}</Heading>
              <GanttTimeline
                v-if="order?.stages"
                :stages="order.stages"
                :showLoading="showLoading"
                :showUnloading="showUnloading"
              />
              <Stack v-else align="center" justify="center" gap="2">
                <Text tone="muted">{{ t('ordersDetail.sections.timeline.empty') }}</Text>
              </Stack>
            </Stack>
          </Card>
        </template>
      </Stack>
  </Section>
</template>

<script setup lang="ts">
import { GetOrderDocument } from '~/composables/graphql/team/orders-generated'

definePageMeta({
  middleware: ['auth-oidc']
})

const localePath = useLocalePath()
const route = useRoute()
const { t } = useI18n()
const { isAuthenticated } = useAuth()
const { execute } = useGraphQL()

const order = ref<any>(null)
const isLoadingOrder = ref(true)
const hasOrderError = ref(false)
const orderError = ref('')
const showLoading = ref(true)
const showUnloading = ref(true)

const stageLocations = (stage: any) => {
  const locations: Array<{ uuid?: string; name?: string; latitude?: number; longitude?: number; country?: string }> = []
  if (stage.stageType === 'transport') {
    if (stage.sourceLatitude && stage.sourceLongitude) {
      locations.push({
        uuid: `${stage.uuid}-source`,
        name: stage.sourceLocationName,
        latitude: stage.sourceLatitude,
        longitude: stage.sourceLongitude,
        country: stage.sourceCountry
      })
    }
    if (stage.destinationLatitude && stage.destinationLongitude) {
      locations.push({
        uuid: `${stage.uuid}-destination`,
        name: stage.destinationLocationName,
        latitude: stage.destinationLatitude,
        longitude: stage.destinationLongitude,
        country: stage.destinationCountry
      })
    }
  } else {
    if (stage.locationLatitude && stage.locationLongitude) {
      locations.push({
        uuid: `${stage.uuid}-service`,
        name: stage.locationName,
        latitude: stage.locationLatitude,
        longitude: stage.locationLongitude,
        country: stage.locationCountry
      })
    }
  }
  return locations
}

const orderLocations = computed(() => {
  const locs: Array<{ uuid?: string; name?: string; latitude?: number; longitude?: number; country?: string }> = []
  order.value?.stages?.forEach((stage: any) => {
    stageLocations(stage).forEach(loc => locs.push(loc))
  })
  return locs
})

const loadOrder = async () => {
  try {
    isLoadingOrder.value = true
    hasOrderError.value = false
    const orderUuid = route.params.id as string
    const { data, error: orderErrorResp } = await useServerQuery('order-detail', GetOrderDocument, { orderUuid }, 'team', 'orders')
    if (orderErrorResp.value) throw orderErrorResp.value
    order.value = data.value?.getOrder
  } catch (err: any) {
    hasOrderError.value = true
    orderError.value = err.message || t('ordersDetail.errors.load_failed')
  } finally {
    isLoadingOrder.value = false
  }
}

const formatPrice = (price) => {
  if (!price) return t('ordersDetail.labels.price_zero')
  return new Intl.NumberFormat('ru-RU', {
    style: 'currency',
    currency: 'RUB',
    minimumFractionDigits: 0
  }).format(price)
}

const getCompaniesSummary = (stage) => {
  const companies = []
  if (stage.stageType === 'service' && stage.selectedCompany) {
    companies.push({
      name: stage.selectedCompany.name,
      totalWeight: 0,
      tripsCount: 0,
      company: stage.selectedCompany
    })
    return companies
  }

  if (stage.stageType === 'transport' && stage.trips?.length) {
    const companiesMap = new Map()
    stage.trips.forEach(trip => {
      const companyName = trip.company?.name || t('ordersDetail.labels.company_unknown')
      const weight = trip.plannedWeight || 0
      if (companiesMap.has(companyName)) {
        const existing = companiesMap.get(companyName)
        existing.totalWeight += weight
        existing.tripsCount += 1
      } else {
        companiesMap.set(companyName, {
          name: companyName,
          totalWeight: weight,
          tripsCount: 1,
          company: trip.company
        })
      }
    })
    return Array.from(companiesMap.values())
  }
  return []
}

const getOrderDuration = () => {
  if (!order.value?.stages?.length) return 0
  let minDate = null
  let maxDate = null
  order.value.stages.forEach(stage => {
    stage.trips?.forEach(trip => {
      const startDate = new Date(trip.plannedLoadingDate || trip.actualLoadingDate)
      const endDate = new Date(trip.plannedUnloadingDate || trip.actualUnloadingDate)
      if (!minDate || startDate < minDate) minDate = startDate
      if (!maxDate || endDate > maxDate) maxDate = endDate
    })
  })
  if (!minDate || !maxDate) return 0
  const diffTime = Math.abs(maxDate - minDate)
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24))
}

const getStageDateRange = (stage) => {
  if (!stage.trips?.length) return t('ordersDetail.labels.dates_undefined')
  let minDate = null
  let maxDate = null
  stage.trips.forEach(trip => {
    const startDate = new Date(trip.plannedLoadingDate || trip.actualLoadingDate)
    const endDate = new Date(trip.plannedUnloadingDate || trip.actualUnloadingDate)
    if (!minDate || startDate < minDate) minDate = startDate
    if (!maxDate || endDate > maxDate) maxDate = endDate
  })
  if (!minDate || !maxDate) return t('ordersDetail.labels.dates_undefined')
  const formatDate = (date) => date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' })
  if (minDate.toDateString() === maxDate.toDateString()) return formatDate(minDate)
  return `${formatDate(minDate)} - ${formatDate(maxDate)}`
}

await loadOrder()
</script>
