<script setup lang="ts">
import type { PoiImageAsset, PoiResolved } from '@/domain/poi'
import PageState from '@/components/poi/PageState.vue'
import PoiHeroGallery from '@/components/poi/PoiHeroGallery.vue'
import PoiTagList from '@/components/poi/PoiTagList.vue'
import { getPoiRepository } from '@/data/poi'
import { coverPhotoFullUrlFor } from '@/data/poi/photos'
import { formatRecommendationLabel } from '@/domain/poi'
import { getCheckInProfile } from '@/services/check-in'

const state = ref<'loading' | 'ready' | 'invalid' | 'error'>('loading')
const poi = ref<PoiResolved | null>(null)
const hasCheckedIn = ref(false)
const checkInStorageError = ref(false)

/**
 * hero 用分包大图（800×600）替换主包缩略图（400×300）。
 *
 * 本页在 pages-poi 分包内，能引用分包 static 资源；主包页面不行。
 * 占位图仍指向主包，不做替换。
 */
const heroImages = computed<PoiImageAsset[]>(() => {
  const current = poi.value
  if (!current)
    return []

  return current.images.map(image => (
    image.id === current.coverImageId && !image.isPlaceholder
      ? { ...image, url: coverPhotoFullUrlFor(current.id) }
      : image
  ))
})

function loadPoi(poiId: string) {
  state.value = 'loading'
  poi.value = null

  try {
    if (!poiId.trim()) {
      state.value = 'invalid'
      return
    }

    const result = getPoiRepository().getPoiById(poiId)
    if (!result) {
      state.value = 'invalid'
      return
    }

    poi.value = result
    try {
      hasCheckedIn.value = getCheckInProfile().checkIns.some(record => record.poiId === result.id)
      checkInStorageError.value = false
    }
    catch (error) {
      console.error('Failed to load POI check-in state', error)
      hasCheckedIn.value = false
      checkInStorageError.value = true
    }
    state.value = 'ready'
  }
  catch (error) {
    console.error('Failed to load POI detail', error)
    state.value = 'error'
  }
}

function openCheckIn() {
  if (!poi.value)
    return
  uni.navigateTo({ url: `/pages/check-in/index?poiId=${encodeURIComponent(poi.value.id)}` })
}

function openCheckInRecords() {
  uni.navigateTo({ url: '/pages/check-in/records' })
}

function returnToMap() {
  uni.navigateBack({
    fail: () => {
      uni.reLaunch({ url: '/pages/map/index' })
    },
  })
}

function formatCoordinate(value: number): string {
  return value.toFixed(6)
}

function formatUpdatedAt(value: string): string {
  const date = new Date(value)
  if (Number.isNaN(date.getTime()))
    return '待确认'
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}

onLoad((query) => {
  const rawPoiId = typeof query?.poiId === 'string' ? query.poiId : ''
  try {
    loadPoi(decodeURIComponent(rawPoiId))
  }
  catch {
    state.value = 'invalid'
  }
})

onShow(() => {
  if (!poi.value)
    return
  try {
    hasCheckedIn.value = getCheckInProfile().checkIns.some(record => record.poiId === poi.value?.id)
    checkInStorageError.value = false
  }
  catch (error) {
    console.error('Failed to refresh POI check-in state', error)
    hasCheckedIn.value = false
    checkInStorageError.value = true
  }
})
</script>

<template>
  <view class="poi-detail-page">
    <PageState v-if="state === 'loading'" state="loading" title="正在加载点位信息…" />
    <PageState
      v-else-if="state === 'invalid'"
      state="empty"
      title="点位不存在或已下线"
      description="该点位可能已更新，请返回地图重新选择"
      action-label="返回地图"
      @action="returnToMap"
    />
    <PageState
      v-else-if="state === 'error'"
      state="error"
      title="点位信息加载失败"
      description="暂时无法读取该点位，请稍后返回重试"
      action-label="返回地图"
      @action="returnToMap"
    />

    <template v-else-if="poi">
      <PoiHeroGallery :images="heroImages" :name="poi.name" />

      <view class="poi-detail-page__content">
        <view class="poi-detail-page__header">
          <text class="poi-detail-page__category">{{ poi.category.name }}</text>
          <text class="poi-detail-page__name">{{ poi.name }}</text>
          <view class="poi-detail-page__recommendation">
            {{ formatRecommendationLabel(poi.recommendationSource, poi.recommendationIndex) }}
          </view>
          <PoiTagList class="poi-detail-page__tags" :tags="poi.tags" />
        </view>

        <view class="check-in-entry" :class="{ 'check-in-entry--done': hasCheckedIn }">
          <view class="check-in-entry__mark">{{ hasCheckedIn ? '✓' : '◎' }}</view>
          <view class="check-in-entry__copy">
            <text class="check-in-entry__title">{{ checkInStorageError ? '打卡数据需要处理' : hasCheckedIn ? '已留下光明足迹' : '到点打卡' }}</text>
            <text>{{ checkInStorageError ? '本机打卡数据异常，请先处理' : hasCheckedIn ? '该点位已在本机完成打卡' : '到达点位附近后，使用本次真实定位打卡' }}</text>
          </view>
          <button @click="checkInStorageError ? openCheckInRecords() : openCheckIn()">{{ checkInStorageError ? '去处理' : hasCheckedIn ? '查看' : '去打卡' }}</button>
        </view>

        <view class="info-card">
          <view class="info-row">
            <text class="info-row__label">开放时间</text>
            <text class="info-row__value">{{ poi.openingHoursText }}</text>
          </view>
          <view class="info-row">
            <text class="info-row__label">地址</text>
            <text class="info-row__value">{{ poi.address }}</text>
          </view>
          <view class="info-row info-row--coordinates">
            <text class="info-row__label">经纬度</text>
            <view class="info-row__value info-row__coordinates">
              <text>经度 {{ formatCoordinate(poi.longitude) }}</text>
              <text>纬度 {{ formatCoordinate(poi.latitude) }}</text>
              <text class="info-row__coordinate-system">坐标系 {{ poi.coordinateSystem }}</text>
            </view>
          </view>
          <view class="info-row">
            <text class="info-row__label">数据更新</text>
            <text class="info-row__value">{{ formatUpdatedAt(poi.updatedAt) }}</text>
          </view>
        </view>

        <view class="description-section">
          <text class="description-section__title">点位简介</text>
          <text class="description-section__body">{{ poi.description }}</text>
        </view>

        <view class="poc-notice">
          <text class="poc-notice__title">POC 数据说明</text>
          <text class="poc-notice__body">当前内容用于产品和技术可行性验证，正式开放信息请以后续审核版本为准。</text>
        </view>
      </view>
    </template>
  </view>
</template>

<route lang="yaml">
layout: map
style:
  navigationBarTitleText: 点位详情
  navigationBarBackgroundColor: '#ffffff'
  navigationBarTextStyle: black
  backgroundColor: '#f5f7f6'
</route>

<style scoped lang="scss">
.poi-detail-page {
  min-height: 100vh;
  background: #f5f7f6;
}

.poi-detail-page__content {
  padding: 32rpx 32rpx calc(32rpx + env(safe-area-inset-bottom));
}

.poi-detail-page__header {
  display: flex;
  flex-direction: column;
}

.poi-detail-page__category {
  align-self: flex-start;
  padding: 8rpx 18rpx;
  font-size: 24rpx;
  font-weight: 600;
  line-height: 34rpx;
  color: #0e6247;
  background: #e8f4ee;
  border-radius: 24rpx;
}

.poi-detail-page__name {
  margin-top: 16rpx;
  font-size: 40rpx;
  font-weight: 700;
  line-height: 56rpx;
  color: #18201d;
}

.poi-detail-page__recommendation {
  align-self: flex-start;
  padding: 8rpx 16rpx;
  margin-top: 16rpx;
  font-size: 26rpx;
  font-weight: 600;
  line-height: 38rpx;
  color: #934b00;
  background: #fff3e0;
  border-radius: 10rpx;
}

.poi-detail-page__tags {
  margin-top: 18rpx;
}

.info-card,
.check-in-entry,
.description-section,
.poc-notice {
  padding: 28rpx;
  margin-top: 24rpx;
  background: #fff;
  border: 1rpx solid #dde5e1;
  border-radius: 20rpx;
}

.check-in-entry {
  display: flex;
  gap: 18rpx;
  align-items: center;
  padding: 24rpx;
}

.check-in-entry--done {
  background: #e8f4ee;
  border-color: #cfe4d9;
}

.check-in-entry__mark {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 62rpx;
  height: 62rpx;
  font-size: 28rpx;
  font-weight: 800;
  color: #fff;
  background: #167a5b;
  border-radius: 50%;
}

.check-in-entry__copy {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  font-size: 21rpx;
  line-height: 32rpx;
  color: #5e6b65;
}

.check-in-entry__title {
  margin-bottom: 3rpx;
  font-size: 27rpx;
  font-weight: 750;
  color: #18201d;
}

.check-in-entry button {
  flex: none;
  width: auto;
  height: 60rpx;
  padding: 0 22rpx;
  margin: 0;
  font-size: 23rpx;
  font-weight: 700;
  line-height: 60rpx;
  color: #fff;
  background: #167a5b;
  border: 0;
  border-radius: 30rpx;
}

.check-in-entry button::after {
  border: 0;
}

.info-row {
  display: flex;
  gap: 24rpx;
  align-items: flex-start;
  padding: 20rpx 0;
  border-bottom: 1rpx solid #edf1ef;
}

.info-row:first-child {
  padding-top: 0;
}

.info-row:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.info-row__label {
  flex: none;
  width: 128rpx;
  font-size: 26rpx;
  line-height: 40rpx;
  color: #5e6b65;
}

.info-row__value {
  flex: 1;
  font-size: 28rpx;
  line-height: 40rpx;
  color: #18201d;
}

.info-row__coordinates {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.info-row__coordinate-system {
  margin-top: 6rpx;
  font-size: 24rpx;
  color: #8a9690;
}

.description-section__title,
.poc-notice__title {
  display: block;
  font-size: 30rpx;
  font-weight: 700;
  line-height: 42rpx;
  color: #18201d;
}

.description-section__body,
.poc-notice__body {
  display: block;
  margin-top: 16rpx;
  font-size: 28rpx;
  line-height: 44rpx;
  color: #425049;
  white-space: pre-wrap;
}

.poc-notice {
  background: #e8f4ee;
  border-color: #cfe4d9;
}

.poc-notice__title {
  font-size: 26rpx;
  color: #0e6247;
}

.poc-notice__body {
  font-size: 24rpx;
  line-height: 38rpx;
  color: #3d5a4d;
}
</style>
