<template>
  <view class="voice-recorder">
    <!-- 按住说话按钮 -->
    <view 
      class="voice-btn"
      :class="{ recording: isRecording }"
      @touchstart.prevent="handleTouchStart"
      @touchmove.prevent="handleTouchMove"
      @touchend.prevent="handleTouchEnd"
      @touchcancel.prevent="handleTouchCancel"
    >
      <text>{{ btnText }}</text>
    </view>
    
    <!-- 录音提示弹窗 -->
    <view class="voice-modal" v-if="showModal">
      <view class="voice-modal-content" :class="{ cancel: isCancelling }">
        <view class="voice-icon">
          <view class="voice-wave" :class="{ active: isRecording && !isCancelling }"></view>
          <text class="icon">{{ isCancelling ? '↩' : '🎤' }}</text>
        </view>
        <text class="voice-tip">{{ recordingTip }}</text>
        <text class="voice-time" v-if="!isCancelling">{{ recordingTime }}s</text>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, onUnmounted } from 'vue'

const emit = defineEmits(['send'])

const isRecording = ref(false)
const showModal = ref(false)
const isCancelling = ref(false)
const recordingTime = ref(0)
const recorderManager = ref(null)
const recordingTimer = ref(null)
const startY = ref(0)

// 是否是用户主动取消（上滑取消）
let cancelled = false

const btnText = computed(() => {
  if (isRecording.value && isCancelling.value) return '松开取消'
  if (isRecording.value) return '松开发送'
  return '按住说话'
})

const recordingTip = computed(() => {
  if (isCancelling.value) return '松开手指，取消发送'
  return '正在录音...'
})

// 初始化录音管理器
const initRecorder = () => {
  if (recorderManager.value) return
  
  recorderManager.value = uni.getRecorderManager()
  
  recorderManager.value.onStart(() => {
    console.log('[VoiceRecorder] 录音开始')
    isRecording.value = true
    showModal.value = true
    recordingTime.value = 0
    cancelled = false
    
    recordingTimer.value = setInterval(() => {
      recordingTime.value++
      if (recordingTime.value >= 60) {
        stopRecording()
      }
    }, 1000)
  })
  
  recorderManager.value.onStop((res) => {
    console.log('[VoiceRecorder] 录音结束:', res, '已取消:', cancelled)
    clearTimer()
    isRecording.value = false
    showModal.value = false
    isCancelling.value = false
    
    // 如果是取消的，不发送
    if (cancelled) {
      cancelled = false
      return
    }
    
    const duration = Math.ceil((res.duration || 0) / 1000)
    
    if (duration < 1) {
      uni.showToast({ title: '录音时间太短', icon: 'none' })
      return
    }
    
    emit('send', {
      tempFilePath: res.tempFilePath,
      duration: duration
    })
  })
  
  recorderManager.value.onError((err) => {
    console.error('[VoiceRecorder] 录音错误:', err)
    clearTimer()
    isRecording.value = false
    showModal.value = false
    isCancelling.value = false
    cancelled = false
    
    uni.showToast({ title: '录音失败，请检查麦克风权限', icon: 'none' })
  })
}

const clearTimer = () => {
  if (recordingTimer.value) {
    clearInterval(recordingTimer.value)
    recordingTimer.value = null
  }
}

const stopRecording = () => {
  if (recorderManager.value) {
    recorderManager.value.stop()
  }
}

// 开始录音
const handleTouchStart = (e) => {
  startY.value = e.touches[0].clientY
  isCancelling.value = false
  cancelled = false
  
  initRecorder()
  
  recorderManager.value.start({
    duration: 60000,
    sampleRate: 16000,
    numberOfChannels: 1,
    encodeBitRate: 48000,
    format: 'mp3'
  })
}

// 手指移动 - 上滑取消
const handleTouchMove = (e) => {
  if (!isRecording.value) return
  
  const moveY = e.touches[0].clientY
  const diff = startY.value - moveY
  
  // 上滑超过80px进入取消状态
  isCancelling.value = diff > 80
}

// 松开手指 - 发送或取消
const handleTouchEnd = () => {
  if (!isRecording.value) return
  
  if (isCancelling.value) {
    // 取消录音
    cancelled = true
    stopRecording()
  } else {
    // 正常结束，发送
    stopRecording()
  }
}

// 系统取消（如来电等）
const handleTouchCancel = () => {
  if (!isRecording.value) return
  cancelled = true
  stopRecording()
}

onUnmounted(() => {
  clearTimer()
})
</script>

<style lang="scss" scoped>
.voice-recorder {
  flex: 1;
  display: flex;
  align-items: center;
}

.voice-btn {
  flex: 1;
  height: 72rpx;
  line-height: 72rpx;
  text-align: center;
  background: #f5f5f5;
  border-radius: 36rpx;
  font-size: 28rpx;
  color: #333;
  
  &.recording {
    background: #e0e0e0;
    color: #999;
  }
}

.voice-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
}

.voice-modal-content {
  width: 300rpx;
  height: 300rpx;
  background: rgba(0, 0, 0, 0.75);
  border-radius: 24rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  
  &.cancel {
    background: rgba(200, 50, 50, 0.85);
  }
}

.voice-icon {
  position: relative;
  width: 120rpx;
  height: 120rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  
  .icon {
    font-size: 60rpx;
    z-index: 1;
  }
}

.voice-wave {
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 4rpx solid rgba(255, 255, 255, 0.3);
  
  &.active {
    animation: wave 1.2s ease-in-out infinite;
  }
}

@keyframes wave {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

.voice-tip {
  color: #fff;
  font-size: 26rpx;
  margin-top: 20rpx;
}

.voice-time {
  color: rgba(255, 255, 255, 0.8);
  font-size: 24rpx;
  margin-top: 10rpx;
}
</style>
