<template>
  <GuidePageFrame
    active-tab="explain"
    variant="static"
    :show-top-tabs="false"
    show-back
    back-label="讲解首页"
    @tab-change="handleTopTabChange"
    @back="handleBack"
  >
    <view class="explain-all-page">
      <ExplainHallSelect
        :halls="explainHallItems"
        :business-units="explainBusinessUnitItems"
        :guide-stops="explainGuideStopItems"
        :stage="explainStage"
        :selected-hall-name="selectedExplainHallName"
        :selected-business-unit-name="selectedExplainBusinessUnitName"
        :loading="explainLoading"
        :error="explainError"
        @hall-click="handleExplainHallClick"
        @business-unit-click="handleExplainBusinessUnitClick"
        @guide-stop-click="handleExplainGuideStopClick"
        @back="handlePanelBack"
      />
    </view>
  </GuidePageFrame>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import GuidePageFrame from '@/components/navigation/GuidePageFrame.vue'
import ExplainHallSelect, {
  type ExplainBusinessUnitSelectItem,
  type ExplainGuideStopSelectItem,
  type ExplainHallSelectItem,
  type ExplainSelectStage
} from '@/components/explain/ExplainHallSelect.vue'
import {
  explainUseCase
} from '@/usecases/explainUseCase'
import {
  normalizeExplainDetailTargetFromGuideStop
} from '@/domain/explainDetailTarget'
import type {
  ExplainBusinessUnit,
  MuseumHall
} from '@/domain/museum'
import {
  navigateToGuideTopTab,
  type GuideTopTab
} from '@/utils/guideTopTabs'

const explainHallItems = ref<ExplainHallSelectItem[]>([])
const explainBusinessUnits = ref<ExplainBusinessUnit[]>([])
const explainStage = ref<ExplainSelectStage>('hall')
const selectedExplainHallId = ref('')
const selectedExplainHallName = ref('')
const selectedExplainBusinessUnitId = ref('')
const selectedExplainBusinessUnitName = ref('')
const explainLoading = ref(false)
const explainError = ref('')
let explainLoadPromise: Promise<void> | null = null

const normalizeExplainKeyword = (value?: string) => (value || '').trim().toLowerCase()

const buildExplainHallItems = (
  halls: MuseumHall[],
  summaries: Awaited<ReturnType<typeof explainUseCase.loadExplainHallSummaries>> = {}
): ExplainHallSelectItem[] => (
  halls.map((hall) => ({
    id: hall.id,
    name: hall.name,
    floorLabel: hall.floorLabel,
    image: hall.image,
    explainCount: hall.exhibitCount || 0,
    businessUnitCount: summaries[hall.id]?.businessUnitCount,
    guideStopCount: summaries[hall.id]?.guideStopCount,
    searchText: normalizeExplainKeyword([
      hall.name,
      hall.floorLabel,
      hall.description,
      hall.area
    ].filter(Boolean).join(' '))
  }))
)

const selectedExplainBusinessUnit = computed(() => (
  explainBusinessUnits.value.find((unit) => unit.id === selectedExplainBusinessUnitId.value) || null
))

const explainBusinessUnitItems = computed<ExplainBusinessUnitSelectItem[]>(() => (
  explainBusinessUnits.value.map((unit) => ({
    id: unit.id,
    name: unit.name,
    hallId: unit.hallId,
    previewImageUrl: unit.previewImageUrl,
    guideStopCount: unit.guideStopCount
  }))
))

const explainGuideStopItems = computed<ExplainGuideStopSelectItem[]>(() => (
  selectedExplainBusinessUnit.value?.stops.map((stop) => ({
    id: stop.id,
    name: stop.name,
    hallId: stop.hallId,
    hallName: stop.hallName,
    floorId: stop.floorId,
    poiId: stop.poiId,
    mapX: stop.mapX,
    mapY: stop.mapY,
    coverImageUrl: stop.coverImageUrl,
    description: stop.description,
    hasAudio: stop.hasAudio,
    audioStatus: stop.audioStatus,
    guideLevel: stop.guideLevel,
    playTargetType: stop.playTargetType,
    playTargetId: stop.playTargetId
  })) || []
))

const loadExplainHalls = async () => {
  if (explainHallItems.value.length) return
  if (explainLoadPromise) return explainLoadPromise

  explainLoading.value = true
  explainError.value = ''

  explainLoadPromise = (async () => {
    try {
      const halls = await explainUseCase.loadExplainHalls()
      const summaries = await explainUseCase.loadExplainHallSummaries(halls.map((hall) => hall.id))
      explainHallItems.value = buildExplainHallItems(halls, summaries)
    } catch (error) {
      console.error('加载讲解展厅失败:', error)
      explainError.value = '讲解展厅加载失败，请稍后重试'
      explainHallItems.value = []
    } finally {
      explainLoading.value = false
      explainLoadPromise = null
    }
  })()

  return explainLoadPromise
}

onLoad(() => {
  void loadExplainHalls()
})

const handleBack = () => {
  uni.navigateBack({
    delta: 1,
    fail: () => {
      uni.reLaunch({
        url: '/pages/index/index?tab=explain'
      })
    }
  })
}

const handleTopTabChange = (tab: GuideTopTab) => {
  navigateToGuideTopTab(tab)
}

const handleExplainHallClick = async (hallId: string) => {
  const hall = explainHallItems.value.find((item) => item.id === hallId)
  selectedExplainHallId.value = hallId
  selectedExplainHallName.value = hall?.name || '业务单元'
  selectedExplainBusinessUnitId.value = ''
  selectedExplainBusinessUnitName.value = ''
  explainBusinessUnits.value = []
  explainLoading.value = true
  explainError.value = ''

  try {
    explainBusinessUnits.value = await explainUseCase.loadTemporaryBusinessUnitsByHall(hallId)
    explainStage.value = 'unit'
  } catch (error) {
    console.error('加载展厅讲解点失败:', error)
    explainError.value = '展厅讲解点加载失败，请稍后重试'
    explainStage.value = 'unit'
  } finally {
    explainLoading.value = false
  }
}

const handleExplainBusinessUnitClick = (unitId: string) => {
  const unit = explainBusinessUnits.value.find((item) => item.id === unitId)
  selectedExplainBusinessUnitId.value = unitId
  selectedExplainBusinessUnitName.value = unit?.name || '讲解点'
  explainStage.value = 'stop'
}

const handleExplainGuideStopClick = (stop: ExplainGuideStopSelectItem) => {
  const target = stop.playTargetType && stop.playTargetId
    ? {
      targetType: stop.playTargetType,
      targetId: stop.playTargetId
    }
    : normalizeExplainDetailTargetFromGuideStop({ id: stop.id })
  const params = new URLSearchParams({
    id: stop.id,
    tab: 'explain',
    targetType: target.targetType,
    targetId: target.targetId
  })
  uni.navigateTo({
    url: `/pages/exhibit/detail?${params.toString()}`
  })
}

const handlePanelBack = () => {
  if (explainStage.value === 'stop') {
    explainStage.value = 'unit'
    selectedExplainBusinessUnitId.value = ''
    selectedExplainBusinessUnitName.value = ''
    explainError.value = ''
    return
  }

  if (explainStage.value === 'unit') {
    explainStage.value = 'hall'
    selectedExplainHallId.value = ''
    selectedExplainHallName.value = ''
    selectedExplainBusinessUnitId.value = ''
    selectedExplainBusinessUnitName.value = ''
    explainBusinessUnits.value = []
    explainError.value = ''
    return
  }

  handleBack()
}
</script>

<style scoped lang="scss">
.explain-all-page {
  position: absolute;
  inset: 0;
  background: #edf0ea;
}
</style>
