<template>
  <view class="h-screen overflow-hidden bg-[#06111f] flex flex-col">
    <view class="relative z-0 h-[43vh] shrink-0 overflow-hidden bg-[#173a34]">
      <image class="absolute inset-0 h-full w-full" :src="scenicSpot.heroImage" mode="aspectFill" />
      <view class="absolute inset-0 bg-[linear-gradient(180deg,rgba(6,17,31,0.15)_18%,rgba(6,17,31,0.1)_45%,rgba(6,17,31,0.92)_100%)]" />

      <view class="absolute inset-x-0 top-0 z-20">
        <TopNavBar
          title=""
          background="transparent"
          title-color="#ffffff"
          back-icon-color="#ffffff"
          @back="emit('back')"
        />
        <view class="mt-[8px] flex flex-col items-end gap-[10px] pr-[16px]">
          <view class="flex h-[40px] w-[40px] items-center justify-center rounded-full bg-black/35 shadow-sm" @tap.stop="emit('open-travelers')">
            <uni-icons type="contact" size="21" color="#FFFFFF" />
          </view>
          <view class="flex h-[40px] w-[40px] items-center justify-center rounded-full bg-black/35 shadow-sm" @tap.stop="emit('open-orders')">
            <uni-icons type="list" size="21" color="#FFFFFF" />
          </view>
        </view>
      </view>

      <view class="absolute bottom-[42px] left-[20px] right-[20px]">
        <text class="block text-[28px] font-bold leading-[1.2] text-white">{{ scenicSpot.name }}</text>
        <text class="mt-[7px] block text-[13px] text-white/85">{{ scenicSpot.level }}｜{{ scenicSpot.heritage }}</text>
        <view class="mt-[10px] flex items-center">
          <uni-icons type="location" size="15" color="#FFFFFF" />
          <text class="ml-[4px] flex-1 text-[12px] leading-[17px] text-white/85">{{ scenicSpot.address }}</text>
        </view>
        <view class="mt-[10px] flex items-center gap-[18px]">
          <view class="flex items-center" @click="makePhoneCall">
            <uni-icons type="phone" size="15" color="#FFFFFF" />
            <text class="ml-[4px] text-[12px] text-white">{{ scenicSpot.phone }}</text>
          </view>
          <view class="flex items-center" @click="openLocation">
            <uni-icons type="navigate" size="15" color="#FFFFFF" />
            <text class="ml-[4px] text-[12px] text-white">导航</text>
          </view>
        </view>
      </view>
    </view>

    <view class="relative z-10 -mt-[28px] min-h-0 flex-1 overflow-hidden rounded-t-[28px] bg-[#f4f6f8] shadow-[0_-8px_24px_rgba(6,17,31,0.12)]">
      <view class="flex h-full min-h-0">
        <scroll-view
          class="h-full w-[80px] shrink-0 bg-white"
          scroll-y
          :scroll-into-view="leftScrollIntoViewId"
          scroll-with-animation
        >
          <view
            v-for="group in groups"
            :id="`ticket-nav-${group.id}`"
            :key="group.id"
            class="relative flex min-h-[68px] items-center justify-center px-[10px] py-[12px] text-center"
            :class="group.id === activeGroupId ? 'bg-[#ecf8f2] text-[#11795c]' : 'bg-white text-[#5f6875]'"
            @click="selectGroup(group.id)"
          >
            <view v-if="group.id === activeGroupId" class="absolute left-0 h-[28px] w-[3px] rounded-r-full bg-[#149474]" />
            <text class="text-[13px] leading-[18px]" :class="group.id === activeGroupId ? 'font-semibold' : 'font-normal'">{{ group.name }}</text>
          </view>
        </scroll-view>

        <scroll-view
          id="ticket-product-scroll"
          class="h-full min-w-0 flex-1 bg-[#f4f6f8]"
          scroll-y
          :scroll-into-view="scrollIntoViewId"
          scroll-with-animation
          @scroll="handleProductScroll"
        >
          <view class="px-[12px] pb-[24px]">
            <view v-for="group in groups" :id="`ticket-group-${group.id}`" :key="group.id" class="pt-[14px]">
              <view class="flex items-center">
                <text class="text-[18px] font-bold text-[#202733]">{{ group.name }}</text>
                <text v-if="group.tag" class="ml-[7px] rounded-full bg-[#e5f6ee] px-[7px] py-[2px] text-[10px] text-[#158061]">{{ group.tag }}</text>
              </view>
              <text v-if="group.description" class="mt-[4px] block text-[12px] leading-[17px] text-[#808997]">{{ group.description }}</text>

              <view v-if="productsForGroup(group).length" class="mt-[10px] flex flex-col gap-[10px]">
                <view v-for="product in productsForGroup(group)" :key="product.id" class="flex rounded-[14px] bg-white p-[10px]">
                  <image class="h-[100px] w-[100px] shrink-0 rounded-[10px] bg-[#e8edf0]" :src="product.images && product.images[0]" mode="aspectFill" @click="emit('open-detail', product.id)" />
                  <view class="ml-[10px] flex min-w-0 flex-1 flex-col">
                    <view class="flex min-w-0 items-start" @click="emit('open-detail', product.id)">
                      <text class="line-clamp-2 min-w-0 text-[14px] font-semibold leading-[20px] text-[#242b36]">{{ product.shortTitle || product.name }}</text>
                      <view class="flex h-[20px] shrink-0 items-center">
                        <uni-icons type="right" size="14" color="#242b36" />
                      </view>
                    </view>
                    <view class="mt-[5px] flex flex-wrap gap-[4px]">
                      <text v-if="product.ageRule" class="rounded-[4px] bg-[#f2ebff] px-[5px] py-[2px] text-[10px] text-[#7a52b3]">{{ ageRuleText(product.ageRule) }}</text>
                      <text v-for="highlight in product.highlights || []" :key="highlight" class="rounded-[4px] bg-[#e8f2ff] px-[5px] py-[2px] text-[10px] text-[#3474c7]">{{ highlight }}</text>
                    </view>
                    <view class="mt-auto flex items-end justify-between pt-[6px]">
                      <view>
                        <text v-if="product.sold !== null && product.sold !== undefined" class="block text-[10px] text-[#9aa2ad]">已售 {{ product.sold }}</text>
                        <text class="text-[12px] font-medium text-[#f26b32]">¥<text class="text-[20px] font-bold">{{ product.salePrice }}</text></text>
                      </view>
                      <view class="flex h-[28px] items-center justify-center rounded-full bg-[#f26b32] px-[13px]" @click="emit('buy', product.id)">
                        <text class="text-[12px] font-medium leading-none text-white">选购</text>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
              <view v-else class="mt-[10px] rounded-[14px] bg-white px-[16px] py-[28px] text-center">
                <text class="text-[13px] text-[#9aa2ad]">{{ loading ? '加载中...' : '暂无可售商品' }}</text>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from 'vue'
import TopNavBar from "@/components/TopNavBar/index.vue"

const props = defineProps({
  scenicSpot: { type: Object, required: true },
  groups: { type: Array, default: () => [] },
  products: { type: Array, default: () => [] },
  loading: { type: Boolean, default: false },
})

const emit = defineEmits(['back', 'open-travelers', 'open-orders', 'open-detail', 'buy'])
const activeGroupId = ref(props.groups[0]?.id || '')
const scrollIntoViewId = ref('')
const leftScrollIntoViewId = computed(() => `ticket-nav-${activeGroupId.value}`)
const groupOffsets = ref([])
const rightScrollTop = ref(0)
const instance = getCurrentInstance()
const productsById = computed(() => new Map(props.products.map((product) => [product.id, product])))

const productsForGroup = (group) => (group.productIds || [])
  .map((productId) => productsById.value.get(productId))
  .filter((product) => product?.status === 'on_sale' && product.clientVisible !== false)

const ageRuleText = (rule) => {
  if (rule.min > 0 && rule.max >= 999) return `${rule.min}周岁及以上`
  if (rule.min <= 0 && rule.max < 999) return `${rule.max}周岁及以下`
  return `${rule.min}—${rule.max}周岁`
}

const selectGroup = (groupId) => {
  activeGroupId.value = groupId
  scrollIntoViewId.value = ''
  nextTick(() => {
    scrollIntoViewId.value = `ticket-group-${groupId}`
  })
}

const measureGroupOffsets = () => {
  if (!props.groups.length) return

  nextTick(() => {
    const query = uni.createSelectorQuery().in(instance?.proxy)
    query.select('#ticket-product-scroll').boundingClientRect()
    props.groups.forEach((group) => {
      query.select(`#ticket-group-${group.id}`).boundingClientRect()
    })
    query.exec((rects = []) => {
      const containerRect = rects[0]
      if (!containerRect) return
      groupOffsets.value = props.groups
        .map((group, index) => ({
          id: group.id,
          top: Math.max(
            0,
            Number(rects[index + 1]?.top || 0) -
              Number(containerRect.top || 0) +
              rightScrollTop.value
          ),
        }))
        .sort((left, right) => left.top - right.top)
    })
  })
}

const handleProductScroll = (event) => {
  rightScrollTop.value = Number(event.detail?.scrollTop || 0)
  if (!groupOffsets.value.length) {
    measureGroupOffsets()
    return
  }

  const activationLine = rightScrollTop.value + 24
  const activeGroup = groupOffsets.value.reduce(
    (current, group) => (group.top <= activationLine ? group : current),
    groupOffsets.value[0]
  )
  if (activeGroup?.id) activeGroupId.value = activeGroup.id
}

onMounted(measureGroupOffsets)
watch(() => props.groups.map((group) => group.id).join(','), measureGroupOffsets)

const makePhoneCall = () => {
  if (!props.scenicSpot.phone) return
  uni.makePhoneCall({ phoneNumber: props.scenicSpot.phone })
}

const openLocation = () => {
  const latitude = Number(props.scenicSpot.latitude)
  const longitude = Number(props.scenicSpot.longitude)
  if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
    uni.showToast({ title: '暂无导航坐标', icon: 'none' })
    return
  }

  uni.openLocation({
    latitude,
    longitude,
    name: props.scenicSpot.name || '',
    address: props.scenicSpot.address || '',
    fail: () => uni.showToast({ title: '打开导航失败', icon: 'none' }),
  })
}
</script>
