<template>
  <view v-if="isActive" class="guide-overlay" v-show="!isComponentMode">
      <!-- 遮罩层：使用多个矩形拼接来挖洞 -->
      <view v-if="stepConfig && stepConfig.mask !== false" class="guide-mask" @click.stop="handleMaskClick">
        <!-- 高亮区域 -->
        <view class="highlight-area" :style="highlightStyle" @click.stop="handleHighlightClick">
          <!-- 可选：添加脉冲动画效果 -->
          <!-- <view class="highlight-pulse"></view> -->
        </view>
      </view>
      <!-- 无遮罩层时的高亮区域（仅点击区域） -->
      <view v-else class="highlight-area-only" :style="highlightStyle" @click.stop="handleHighlightClick"></view>

      <!-- 角色图片位置 -->
      <view v-if="stepConfig && stepConfig.character" class="guide-character"
        :style="[characterStyle, { zIndex: 10002 }]">
        <image :src="`/static/guide/${stepConfig.character}.png`" mode="aspectFit" :style="{ width: `${stepConfig.characterSize}rpx`, height: `${stepConfig.characterSize}rpx` }" class="character-img" />
      </view>

      <!-- 提示气泡 -->
      <view v-if="stepConfig" class="guide-tooltip"
        :style="[tooltipStyle, stepConfig.dialogType ? { backgroundImage: `url(/static/guide/dialog_${stepConfig.dialogType}.png)` } : {}]"
        @click.stop="handleTooltipClick">
        <view class="tooltip-content">
          <view v-if="stepConfig.image" class="tooltip-image-wrapper" :style="imageStyle">
            <image :src="stepConfig.image" mode="aspectFit" class="tooltip-image" />
          </view>
          <text class="tooltip-text">
            <text v-for="(part, index) in highlightedContent" :key="index"
              :class="{ 'highlight-keyword': part.highlight }">{{ part.text }}</text>
          </text>
        </view>
        <view class="tooltip-buttons">
          <view v-if="stepConfig.buttons && stepConfig.buttons.includes('prev') && !isFirst" class="tooltip-btn prev-btn"
            @click="handlePrev">
            上一步
          </view>
          <view v-if="stepConfig.buttons && stepConfig.buttons.includes('skip') && isLast" class="tooltip-btn skip-btn"
            @click="handleSkip">
            跳过
          </view>
          <view v-if="stepConfig.buttons && stepConfig.buttons.includes('next')" class="tooltip-btn next-btn"
            @click="handleNext">
            {{ isLast ? '完成' : '下一步' }}
          </view>
        </view>
      </view>
    </view>
</template>

<script setup>
import { computed, watch, onMounted, onUnmounted } from 'vue'
import { useStore } from 'vuex'
import { completeGuide, advanceStage, getOnboardingStatus } from '@/utils/task-api.js'
import { onboardingStages } from '@/utils/guideConfig.js'

const store = useStore()

// 状态映射
const isActive = computed(() => {
  const val = store.state.guide.isActive
  console.log('[GuideOverlay] isActive computed:', val)
  return val
})
const isComponentMode = computed(() => store.state.guide.componentMode)
const targetRect = computed(() => store.state.guide.targetRect)
const stepConfig = computed(() => store.getters['guide/currentStepConfig'])
const isFirst = computed(() => store.getters['guide/isFirst'])
const isLast = computed(() => store.getters['guide/isLast'])

// 监听引导激活状态（当 isActive 变为 false 时触发同步）
watch(() => isActive.value, async (newVal, oldVal) => {
  console.log('[GuideOverlay] isActive watch:', oldVal, '->', newVal)
  if (oldVal === true && newVal === false) {
    const guideKey = store.state.guide.completedGuideKey
    if (guideKey) {
      try {
        await completeGuide(guideKey, onboardingStages)
        console.log('[GuideOverlay] guide synced to backend:', guideKey)

        // 检查当前阶段是否所有任务都已完成，如果完成则推进到下一阶段
        const statusRes = await getOnboardingStatus()
        const stages = statusRes.data?.stages || []
        const currentStageData = stages.find(s => s.is_current)
        if (currentStageData && currentStageData.all_tasks_completed) {
          const nextStage = (currentStageData.stage || 0) + 1
          const maxStage = onboardingStages.length - 1
          if (nextStage <= maxStage) {
            await advanceStage(nextStage)
            console.log('[GuideOverlay] advanced to stage:', nextStage)
          }
        }
      } catch (err) {
        console.error('[GuideOverlay] failed to sync guide to backend:', err)
      } finally {
        // 清除completedGuideKey，避免重复触发
        store.state.guide.completedGuideKey = null
      }
    }
  }
})

// 组件挂载时记录当前状态
onMounted(() => {
  console.log('[GuideOverlay] mounted, isActive:', store.state.guide.isActive)
})

// 高亮区域样式
const highlightStyle = computed(() => {
  const config = stepConfig.value || {}
  const offset = config.offset || { x: 20, y: 16 }

  // 如果配置了 highlightRect，直接使用写死的坐标
  if (config.highlightRect) {
    return {
      top: `${config.highlightRect.top - offset.y}rpx`,
      left: `${config.highlightRect.left - offset.x}rpx`,
      width: `${config.highlightRect.width + offset.x * 2}rpx`,
      height: `${config.highlightRect.height + offset.y * 2}rpx`
    }
  }

  // 否则使用动态计算的坐标
  const rect = targetRect.value
  return {
    top: `${rect.top - offset.y}rpx`,
    left: `${rect.left - offset.x}rpx`,
    width: `${rect.width + offset.x * 2}rpx`,
    height: `${rect.height + offset.y * 2}rpx`
  }
})

// 提示气泡样式
const tooltipStyle = computed(() => {
  const rect = targetRect.value
  const config = stepConfig.value || {}
  const position = config.position || 'bottom'
  const offset = config.offset || { x: 0, y: 0 }
  const center = config.center !== false // 默认 true 居中

  // 获取屏幕尺寸并转换为 rpx
  const systemInfo = uni.getSystemInfoSync()
  const rpxRatio = 750 / systemInfo.windowWidth
  const screenHeight = systemInfo.windowHeight * rpxRatio // 屏幕高度 rpx
  const screenWidth = systemInfo.windowWidth * rpxRatio   // 屏幕宽度 rpx
  const safeAreaTop = (systemInfo.safeAreaInsets?.top || 0) * rpxRatio
  const safeAreaBottom = (systemInfo.safeAreaInsets?.bottom || 0) * rpxRatio

  // 气泡高度估算（用于边界检测），支持自定义高度
  const tooltipHeight = config.tooltipHeight || 300 // 默认 300rpx

  let top, left

  // 如果配置了居中，使用屏幕中心
  if (center) {
    top = screenHeight / 2
    left = screenWidth / 2
  } else if (config.customPosition) {
    // 使用自定义坐标（已经是 rpx）
    top = config.customPosition.y
    left = config.customPosition.x
  } else {
    // 基于目标元素定位，智能选择上下方向
    const targetCenterY = rect.top + rect.height / 2 // 目标元素中心 Y
    const targetTop = rect.top // 目标元素顶部
    const targetBottom = rect.top + rect.height // 目标元素底部

    // 判断目标元素在屏幕的上半部分还是下半部分
    const isTargetInUpperHalf = targetCenterY < screenHeight / 2

    // 根据目标位置决定气泡显示在上方还是下方
    let direction = position
    if (position === 'bottom' || position === 'top') {
      // 动态决定方向：目标在上半部分，气泡显示在下方；目标在下半部分，气泡显示在上方
      direction = isTargetInUpperHalf ? 'bottom' : 'top'
    }

    switch (direction) {
      case 'top':
        // 气泡显示在目标元素上方
        top = targetTop - offset.y - tooltipHeight / 2 - 20
        left = rect.left + rect.width / 2
        break
      case 'bottom':
        // 气泡显示在目标元素下方
        top = targetBottom + offset.y + tooltipHeight / 2 + 20
        left = rect.left + rect.width / 2
        break
      case 'left':
        top = targetCenterY
        left = rect.left - offset.x - 200
        break
      case 'right':
        top = targetCenterY
        left = rect.left + rect.width + offset.x + 200
        break
      default:
        top = targetBottom + offset.y + tooltipHeight / 2 + 20
        left = rect.left + rect.width / 2
    }

    // 边界检测：确保气泡不超出屏幕
    const tooltipWidth = 480 // 气泡最大宽度 rpx
    const minLeft = 20
    const maxLeft = screenWidth - tooltipWidth - 20

    // 左右边界检测
    if (left < minLeft) left = minLeft
    if (left > maxLeft) left = maxLeft

    // 上下边界检测
    if (top < safeAreaTop + 20) {
      // 顶部空间不足，尝试放下面
      top = targetBottom + offset.y + tooltipHeight / 2 + 40
    }
    if (top + tooltipHeight > screenHeight - safeAreaBottom - 20) {
      // 底部空间不足，尝试放上面
      top = targetTop - offset.y - tooltipHeight / 2 - 40
    }
  }

  return {
    top: `${top}rpx`,
    left: `${left}rpx`,
    transform: 'translate(-50%, -50%)',
    ...(config.tooltipHeight ? { height: `${config.tooltipHeight}rpx`, maxHeight: `${config.tooltipHeight}rpx` } : {})
  }
})

// 角色图片样式（可自定义位置和尺寸）
const characterStyle = computed(() => {
  const config = stepConfig.value || {}
  const style = {}

  if (config.characterPosition) {
    style.top = `${config.characterPosition.y}rpx`
    style.left = `${config.characterPosition.x}rpx`
    style.transform = 'translate(-50%, -50%)'
  } else {
    // 默认：相对于气泡位置偏移
    const tooltipTop = parseFloat(tooltipStyle.value.top)
    const tooltipLeft = parseFloat(tooltipStyle.value.left)
    const offsetX = config.characterOffsetX || 300
    const offsetY = config.characterOffsetY || -100
    style.top = `${tooltipTop + offsetY}rpx`
    style.left = `${tooltipLeft + offsetX}rpx`
    style.transform = 'translate(-50%, -50%)'
  }

  // 自定义尺寸
  if (config.characterSize) {
    style.width = `${config.characterSize}rpx`
    style.height = `${config.characterSize}rpx`
  }

  return style
})

// 图片样式
const imageStyle = computed(() => {
  const config = stepConfig.value || {}
  const style = {}
  if (config.imagePosition) {
    style.marginLeft = `${config.imagePosition.x}rpx`
    style.marginTop = `${config.imagePosition.y}rpx`
  }
  if (config.imageCenter) {
    style.margin = '0 auto'
  }
  return style
})

// 高亮文字内容处理
const highlightedContent = computed(() => {
  const config = stepConfig.value || {}
  const content = config.content || ''
  const keywords = config.highlightKeywords || []

  if (!keywords.length) {
    return [{ text: content, highlight: false }]
  }

  // 构建正则表达式，匹配所有关键词
  const pattern = keywords.map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')
  const regex = new RegExp(`(${pattern})`, 'g')
  const parts = content.split(regex)

  return parts.map(part => ({
    text: part,
    highlight: keywords.includes(part)
  }))
})


// 监听引导激活，刷新位置
watch(() => store.state.guide.isActive, async (newVal) => {
  if (newVal) {
    // 延迟执行，确保 stepConfig 已更新
    setTimeout(() => {
      calculatePosition()
    }, 300)
  }
})

// 监听步骤变化，重新计算位置
watch(() => store.state.guide.currentStep, async () => {
  if (isActive.value) {
    // 延迟执行，确保 stepConfig 已更新
    setTimeout(() => {
      calculatePosition()
    }, 300)
  }
})

// 组件挂载时初始化
onMounted(() => {
  console.log('[GuideOverlay] mounted, isActive:', store.state.guide.isActive, 'currentGuide:', store.state.guide.currentGuide?.key, 'currentStep:', store.state.guide.currentStep)
  if (isActive.value) {
    // 延迟执行，确保 DOM 已渲染完成
    setTimeout(() => {
      calculatePosition()
    }, 500)
  }
  // 监听 cabin 数据加载完成事件，触发重新计算位置
  uni.$on('guide:recalculatePosition', () => {
    if (isActive.value) {
      setTimeout(() => {
        calculatePosition()
      }, 100)
    }
  })
  // 监听组件关闭事件，关闭后执行下一步
  let closeComponentHandled = false  // 防止重复处理的标志
  uni.$on('guide:closeComponent', () => {
    console.log('[GuideOverlay] 收到 guide:closeComponent 事件, componentMode:', store.state.guide.componentMode)
    // 如果已经处理过或者 componentMode 已经是 false，忽略
    if (closeComponentHandled || !store.state.guide.componentMode) {
      console.log('[GuideOverlay] guide:closeComponent 忽略, closeComponentHandled:', closeComponentHandled, 'componentMode:', store.state.guide.componentMode)
      return
    }
    closeComponentHandled = true
    store.commit('guide/RESET_COMPONENT_MODE')
    // component action 后需要手动前进到下一步
    if (store.getters['guide/hasNext']) {
      console.log('[GuideOverlay] 有下一步，前进')
      store.commit('guide/NEXT_STEP')
    } else {
      console.log('[GuideOverlay] 没有下一步，结束引导')
      store.commit('guide/END_GUIDE')
    }
    // 重置标志，允许未来再次处理
    setTimeout(() => {
      closeComponentHandled = false
    }, 500)
  })
})

// 计算目标元素位置（带重试）
async function calculatePosition(retryCount = 0) {
  const config = stepConfig.value
  const selector = config?.target

  // 如果配置了 highlightRect，直接使用写死的坐标，不需要查询元素
  if (config?.highlightRect) {
    store.commit('guide/SET_TARGET_RECT', config.highlightRect)
    return config.highlightRect
  }

  if (!selector) return

  const maxRetries = 5  // 增加重试次数
  const result = await store.dispatch('guide/calculateTargetPosition', selector)

  // 如果没找到元素且还有重试次数，延迟后重试
  if (!result && retryCount < maxRetries) {
    await new Promise(resolve => setTimeout(resolve, 500))  // 增加重试间隔
    return calculatePosition(retryCount + 1)
  }

  return result
}

// 点击遮罩（高亮区域外）
function handleMaskClick() {
  // 可选：播放提示音效或震动
  uni.vibrateShort({ fail: () => { } })
}

// 点击气泡继续下一步（当 mask: false 且无按钮时）
function handleTooltipClick() {
  const config = stepConfig.value
  if (!config) return

  // 如果有按钮，不处理气泡点击
  if (config.buttons && config.buttons.length > 0) return

  // 如果有高亮区域，不处理气泡点击
  if (config.mask !== false) return

  // 无高亮无按钮时，点击气泡继续下一步
  handleNext()
}

// 点击高亮区域
function handleHighlightClick() {
  const stepConfigVal = stepConfig.value
  console.log('[GuideOverlay] handleHighlightClick, stepConfig:', stepConfigVal)
  if (stepConfigVal && stepConfigVal.action) {
    const { action } = stepConfigVal
    console.log('[GuideOverlay] action:', action)

    if (action.type === 'navigate' && action.url) {
      // 路由跳转
      // 先设置 isNavigating 标志，防止 nextStep 重复发起导航
      store.commit('guide/SET_NAVIGATING', true)
      uni.navigateTo({
        url: action.url,
        success: () => {
          // 跳转成功后执行下一步
          // isNavigating 已在 handleNext -> nextStep 中处理
          handleNext()
        },
        fail: (err) => {
          console.error('[Guide] 页面跳转失败:', err)
          store.commit('guide/SET_NAVIGATING', false)
        }
      })
    } else if (action.type === 'component' && action.name) {
      // 打开组件（通过事件通知父组件）
      // 先标记当前步骤完成，关闭遮罩
      store.commit('guide/COMPLETE_SUBSTEP')
      store.commit('guide/SET_COMPONENT_MODE')
      // 通知父组件打开组件
      store.dispatch('guide/openComponent', action.name)
      // 组件打开后会通过 guide:closeComponent 事件通知关闭
    } else if (action.type === 'function' && action.handler) {
      // 执行函数
      store.dispatch('guide/executeFunction', action.handler)
    }
  }
}

// 上一步
function handlePrev() {
  store.dispatch('guide/prevStep')
}

// 下一步
function handleNext() {
  store.dispatch('guide/nextStep')
}

// 跳过
function handleSkip() {
  store.dispatch('guide/skipGuide')
}

// 页面卸载时清理
onUnmounted(() => {
  uni.$off('guide:recalculatePosition')
})

// 暴露方法供外部调用
defineExpose({
  calculatePosition
})
</script>

<style scoped>
.guide-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10000;
  pointer-events: auto;
  overflow: hidden;
}

/* 遮罩层：使用伪元素创建半透明背景 */
.guide-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0);
  pointer-events: none;
}

/* 高亮区域：透明显示 */
.highlight-area {
  position: absolute;
  background: transparent;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.8);
  pointer-events: auto;
  transition: all 0.3s ease;
}

/* 无遮罩层时的高亮区域 */
.highlight-area-only {
  position: absolute;
  background: transparent;
  pointer-events: auto;
  transition: all 0.3s ease;
}

/* 脉冲动画效果 */
.highlight-pulse {
  position: absolute;
  top: -8rpx;
  left: -8rpx;
  right: -8rpx;
  bottom: -8rpx;
}

/* 提示气泡 */
.guide-tooltip {
  position: absolute;
  transform: translate(-50%, -50%);
  min-width: 464rpx;
  max-width: 560rpx;
  /* max-height: 192rpx; */
  /* background: #fff; */
  background-size: cover;
  background-repeat: no-repeat;
  border-radius: 24rpx;
  padding: 32rpx;
  /* box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.3); */
  pointer-events: auto;
  z-index: 10001;
  display: flex;
  align-items: center;
  flex-direction: column;
}

.tooltip-content {
  margin-bottom: 24rpx;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.tooltip-image-wrapper {
  margin-top: 16rpx;
  margin-bottom: 16rpx;
  display: flex;
  justify-content: center;
}

.tooltip-image {
  max-width: 300rpx;
  max-height: 200rpx;
}

.highlight-keyword {
  color: #FFA500;
}

/* 背景图片层 */
.guide-bg-image {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  overflow: hidden;
}

.bg-image-img {
  width: 100%;
  height: 100%;
}

/* 角色图片层 */
.guide-character {
  position: absolute;
  pointer-events: auto;
}

.tooltip-text {
  font-size: 32rpx;
  color: #fff;
  line-height: 1.5;
  white-space: pre-line;
  text-align: center;
}

.tooltip-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 24rpx;
}

.tooltip-btn {
  padding: 16rpx 40rpx;
  border-radius: 40rpx;
  font-size: 28rpx;
  cursor: pointer;
  transition: all 0.2s ease;
}

.prev-btn {
  background: #f0f0f0;
  color: #666;
}

.prev-btn:active {
  background: #e0e0e0;
}

.skip-btn {
  background: #f0f0f0;
  color: #666;
}

.skip-btn:active {
  background: #e0e0e0;
}

.next-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
}

.next-btn:active {
  opacity: 0.9;
  transform: scale(0.98);
}
</style>
