<template>
  <view class="modal" v-if="visible">
    <view class="modal-content">
      <view class="modal-title">麦克风检测</view>
      <view class="modal-text">请朗读下面的文字</view>
      
      <!-- 语音波形动画 -->
      <view class="wave-container" v-if="isRecording">
        <view 
          class="wave-bar" 
          v-for="(item, index) in waveData" 
          :key="index" 
          :style="{ height: item + 'rpx' }"
        ></view>
       <!--  <view class="timer">{{ formatTime(recordingTime) }}</view> -->
      </view>
      
      <!-- 待朗读文字 -->
      <view class="read-text">成为奇才，就是现在，我们开始吧。</view>
      
      <!-- 按钮 -->
      <button class="confirm-btn" @tap="handleConfirm">
        {{ isRecording ? '停止录制' : '开始录制' }}
      </button>
      
      <view class="status-message">
        {{ statusMessage }}
      </view>
    </view>
  </view>
</template>

<script>
const recorderManager = uni.getRecorderManager();

export default {
  name: 'VoiceCheckModal',
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isRecording: false,
      waveData: Array(30).fill(20),
      recordingTime: 0,
      statusMessage: '点击"开始录制"按钮朗读文字',
      silenceCounter: 0,
      recordingTimer: null,
      volumeLevel: 0,
      animationTimer: null,
      lastVolume: 0,
      hasPermission: false, // 添加录音权限状态
      noSoundTimeout: null, // 添加无声音超时计时器
      recordingStarted: false, // 添加录音开始标志
      audioPath: null, // 添加录音文件路径
      platform: '', // 添加平台标识
      isRetrying: false // 添加重试标记
    }
  },
  methods: {
    // 检查录音权限 - 跨平台兼容版本
    async checkPermission() {
      // 获取系统信息
      const systemInfo = uni.getSystemInfoSync();
      const platform = systemInfo.platform;
      
      try {
        // iOS平台处理
        if (platform === 'ios') {
          // iOS使用getSystemSetting检查权限状态
          const res = await new Promise((resolve, reject) => {
            uni.getSetting({
              success: (result) => {
                if (result.authSetting['scope.record']) {
                  resolve(true);
                } else {
                  // 请求权限
                  uni.authorize({
                    scope: 'scope.record',
                    success: () => resolve(true),
                    fail: (err) => reject(err)
                  });
                }
              },
              fail: (err) => reject(err)
            });
          });
          this.hasPermission = true;
          return true;
        } 
        // 安卓和鸿蒙平台处理
        else {
          const res = await uni.authorize({
            scope: 'scope.record'
          });
          this.hasPermission = true;
          return true;
        }
      } catch (error) {
        console.error('权限请求失败:', error);
        uni.showModal({
          title: '提示',
          content: '需要录音权限才能进行录音，请在设置中开启录音权限',
          confirmText: '去设置',
          success: (res) => {
            if (res.confirm) {
              uni.openSetting();
            }
          }
        });
        this.hasPermission = false;
        return false;
      }
    },

    async startRecording() {
      // 检查权限
      if (!await this.checkPermission()) {
        return;
      }

      this.isRecording = true;
      this.recordingTime = 0;
      this.silenceCounter = 0;
      this.statusMessage = '正在检测声音...';
      this.waveData = this.waveData.map(() => 20);
      this.lastVolume = 0;
      this.recordingStarted = true;
      
      // 获取系统信息以适配不同平台
      const systemInfo = uni.getSystemInfoSync();
      const platform = systemInfo.platform;
      
      // 根据不同平台配置录音参数
      const recorderOptions = {
        duration: 60000, // 最长录音时间
        format: 'mp3', // 使用mp3格式提高兼容性
        frameSize: 5
      };
      
      // iOS平台特殊处理
      if (platform === 'ios') {
        // iOS推荐参数
        recorderOptions.sampleRate = 44100;
        recorderOptions.numberOfChannels = 1;
        recorderOptions.encodeBitRate = 96000;
      } else {
        // 安卓和鸿蒙平台参数
        recorderOptions.sampleRate = 16000;
        recorderOptions.numberOfChannels = 1;
        recorderOptions.encodeBitRate = 48000;
      }
      
      // 开始录音
      recorderManager.start(recorderOptions);
      
      // 计时器
      this.recordingTimer = setInterval(() => {
        this.recordingTime++;
      }, 1000);

      // 动画定时器
      this.animationTimer = setInterval(() => {
        if (this.isRecording) {
          this.updateWaveform();
        }
      }, 50);

      // 设置无声音检测超时
      this.noSoundTimeout = setTimeout(() => {
        if (this.silenceCounter > 20) {
          this.showNoSoundTip();
        }
      }, 3000);
    },
    
    stopRecording() {
      this.isRecording = false;
      this.recordingStarted = false;
      recorderManager.stop();
      clearInterval(this.recordingTimer);
      clearInterval(this.animationTimer);
      clearTimeout(this.noSoundTimeout);
      this.statusMessage = '录制完成！';
      
      setTimeout(() => {
        this.waveData = Array(30).fill(20);
      }, 500);

      // 延迟触发完成事件，确保audioPath已经设置
      setTimeout(() => {
        // 处理音频文件
        this.processAudioFile();
        
        // 触发完成事件
        this.$emit('complete', {
          success: true,
          audioPath: this.audioPath,
          platform: this.platform
        });
      }, 300);
    },
    
    // 添加音频文件处理方法
    processAudioFile() {
      if (!this.audioPath) return;
      
      // 获取系统信息
      const systemInfo = uni.getSystemInfoSync();
      this.platform = systemInfo.platform;
      
      console.log('处理音频文件:', this.audioPath, '平台:', this.platform);
      
      // 针对不同平台的音频文件处理
      if (this.platform === 'ios') {
        // iOS平台特殊处理
        if (!this.audioPath.startsWith('file://')) {
          this.audioPath = 'file://' + this.audioPath;
        }
      } else if (this.platform === 'android') {
        // 安卓平台特殊处理
        // 通常不需要特殊处理，但如果有特殊需求可以在这里添加
      } else if (this.platform === 'harmony') {
        // 鸿蒙平台特殊处理
        // 根据鸿蒙系统的特性进行处理
      }
      
      // 验证音频文件是否存在
      uni.getFileInfo({
        filePath: this.audioPath,
        success: (res) => {
          console.log('音频文件信息:', res);
          if (res.size === 0) {
            console.warn('警告: 音频文件大小为0');
            // 可以选择重新录制或提示用户
          }
        },
        fail: (err) => {
          console.error('获取音频文件信息失败:', err);
          // 处理文件不存在的情况
        }
      });
    },

    // 显示无声音提示
    showNoSoundTip() {
      if (!this.isRecording) return;
      
      uni.showModal({
        title: '未检测到声音',
        content: '请检查以下问题：\n1. 麦克风是否正常工作\n2. 是否允许使用麦克风\n3. 是否靠近麦克风说话\n4. 说话音量是否足够',
        showCancel: true,
        cancelText: '重新录制',
        confirmText: '继续录制',
        success: (res) => {
          if (res.cancel) {
            // 重新录制：停止当前录音并重新开始
            this.restartRecording();
          } else {
            // 继续录制：重置计数器继续当前录音
            this.continueRecording();
          }
        }
      });
    },

    // 重新录制方法
    restartRecording() {
      // 先停止当前录音
      recorderManager.stop();
      clearInterval(this.recordingTimer);
      clearInterval(this.animationTimer);
      clearTimeout(this.noSoundTimeout);
      
      // 重置所有状态
      this.isRecording = false;
      this.recordingStarted = false;
      this.recordingTime = 0;
      this.silenceCounter = 0;
      this.volumeLevel = 0;
      this.lastVolume = 0;
      this.waveData = Array(30).fill(20);
      
      // 短暂延迟后开始新的录音
      setTimeout(() => {
        this.startRecording();
      }, 500);
    },

    // 继续录制方法
    continueRecording() {
      // 重置计数器和状态，但保持录音继续
      this.silenceCounter = 0;
      this.statusMessage = '正在检测声音...';
      
      // 重新设置无声音检测超时
      clearTimeout(this.noSoundTimeout);
      this.noSoundTimeout = setTimeout(() => {
        if (this.silenceCounter > 20) {
          this.showNoSoundTip();
        }
      }, 3000);
    },

    detectAudio(int16Array) {
      // 获取系统信息
      const systemInfo = uni.getSystemInfoSync();
      const platform = systemInfo.platform;
      
      // 计算平均音量 - 优化算法以提高准确性
      let sum = 0;
      let peak = 0;
      
      // 使用分块处理以提高性能
      const blockSize = 128;
      for (let i = 0; i < int16Array.length; i += blockSize) {
        const end = Math.min(i + blockSize, int16Array.length);
        for (let j = i; j < end; j++) {
          const absValue = Math.abs(int16Array[j]);
          sum += absValue;
          peak = Math.max(peak, absValue);
        }
      }
      
      const avg = sum / int16Array.length;
      
      // 根据不同平台调整阈值
      let SPEAK_THRESHOLD = 500; // 默认阈值
      let volumeScale = 2000;
      
      if (platform === 'ios') {
        SPEAK_THRESHOLD = 300; // iOS通常需要更低的阈值
        volumeScale = 1500;
      } else if (platform === 'android') {
        SPEAK_THRESHOLD = 500; // 安卓标准阈值
        volumeScale = 2000;
      } else {
        // 鸿蒙或其他平台
        SPEAK_THRESHOLD = 400;
        volumeScale = 1800;
      }
      
      // 使用峰值和平均值的组合来计算音量级别
      const combinedLevel = (avg * 0.7 + peak * 0.3) / volumeScale;
      this.volumeLevel = this.smoothVolume(combinedLevel);
      
      // 更新状态
      if (avg > SPEAK_THRESHOLD || peak > SPEAK_THRESHOLD * 3) {
        this.statusMessage = '检测到声音：录音中...';
        this.silenceCounter = 0;
        clearTimeout(this.noSoundTimeout); // 清除无声音超时
        
        // 立即更新波形以反映实际声音
        this.updateWaveform(false);
      } else {
        this.silenceCounter++;
        if (this.silenceCounter > 10) {
          this.statusMessage = '未检测到声音，请靠近麦克风并说话...';
          // 如果持续30次都没有声音，显示提示
          if (this.silenceCounter === 30 && this.isRecording) {
            this.showNoSoundTip();
          }
          
          // 静音时逐渐降低波形
          this.updateWaveform(true);
        }
      }
    },

    // 添加音量平滑处理函数
    smoothVolume(newVolume) {
      const smoothFactor = 0.3; // 平滑系数
      const smoothedVolume = this.lastVolume + (newVolume - this.lastVolume) * smoothFactor;
      this.lastVolume = smoothedVolume;
      return Math.min(1, Math.max(0, smoothedVolume));
    },
    
    updateWaveform(isSilent = false) {
      // 获取系统信息以优化动画性能
      const systemInfo = uni.getSystemInfoSync();
      const platform = systemInfo.platform;
      
      // 根据平台调整动画参数
      let decayFactor = 0.95; // 静音时波形衰减因子
      let animationScale = 1.0; // 动画缩放因子
      
      if (platform === 'ios') {
        // iOS上动画通常需要更平滑
        decayFactor = 0.97;
        animationScale = 0.9;
      } else if (platform === 'android') {
        // 安卓标准参数
        decayFactor = 0.95;
        animationScale = 1.0;
      } else {
        // 鸿蒙或其他平台
        decayFactor = 0.96;
        animationScale = 0.95;
      }
      
      if (isSilent) {
        // 静音时波形逐渐降低
        this.waveData = this.waveData.map(height => Math.max(20, height * decayFactor));
      } else {
        const now = Date.now() * 0.002;
        
        // 使用当前音量级别动态调整波形
        const volumeEffect = this.volumeLevel * animationScale;
        const baseHeight = 20 + volumeEffect * 60;
        const waveAmplitude = volumeEffect * 40;
        
        // 更新波形数据
        this.waveData = this.waveData.map((currentHeight, i) => {
          // 使用余弦和正弦的组合来创建更流畅的波形
          const phase = i * 0.2 + now;
          const wave1 = Math.cos(phase) * 0.5;
          const wave2 = Math.sin(phase * 1.5) * 0.3;
          
          // 添加随机因素使波形更自然
          const randomFactor = Math.random() * 0.1;
          const combinedWave = (wave1 + wave2 + randomFactor) * volumeEffect;
          
          // 计算目标高度
          const targetHeight = baseHeight + combinedWave * waveAmplitude;
          
          // 平滑过渡到新高度 (LERP - 线性插值)
          const smoothFactor = platform === 'ios' ? 0.3 : 0.4; // iOS上更平滑
          const newHeight = currentHeight + (targetHeight - currentHeight) * smoothFactor;
          
          // 确保高度在合理范围内
          return Math.max(20, Math.min(120, newHeight));
        });
      }
    },

    handleConfirm() {
      if (!this.isRecording) {
        this.startRecording();
      } else {
        this.stopRecording();
      }
    },
    
    formatTime(seconds) {
      const mins = Math.floor(seconds / 60);
      const secs = seconds % 60;
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    }
  },
  mounted() {
    // 获取系统信息
    const systemInfo = uni.getSystemInfoSync();
    const platform = systemInfo.platform;
    
    // 监听录音错误 - 增强错误处理
    recorderManager.onError((error) => {
      console.error('录音错误：', error);
      
      // 根据不同平台处理错误
      let errorMessage = '录音出现错误，请检查麦克风权限或重试';
      
      // 针对iOS的特定错误处理
      if (platform === 'ios') {
        if (error.errMsg && error.errMsg.includes('authorize')) {
          errorMessage = 'iOS需要麦克风权限，请在设置中允许访问麦克风';
        } else if (error.errMsg && error.errMsg.includes('busy')) {
          errorMessage = '麦克风正被其他应用使用，请关闭其他使用麦克风的应用';
        }
      } 
      // 针对安卓的特定错误处理
      else if (platform === 'android') {
        if (error.errMsg && error.errMsg.includes('permission')) {
          errorMessage = '安卓系统需要麦克风权限，请在设置中允许访问麦克风';
        }
      }
      // 针对鸿蒙的特定错误处理
      else if (platform === 'harmony') {
        errorMessage = '请确保已授予麦克风权限并重试';
      }
      
      uni.showModal({
        title: '录音错误',
        content: errorMessage,
        showCancel: false,
        success: () => {
          this.stopRecording();
        }
      });
    });

    // 监听录音开始
    recorderManager.onStart(() => {
      console.log('录音开始');
      this.recordingStarted = true;
      
      // 平台特定处理
      if (platform === 'ios') {
        // iOS上可能需要额外延迟来确保录音真正开始
        setTimeout(() => {
          // 如果没有检测到声音，开始模拟波形动画
          if (this.silenceCounter > 5) {
            this.updateWaveform(false);
          }
        }, 500);
      }
    });

    // 监听录音帧数据
    recorderManager.onFrameRecorded(res => {
      if (!res.frameBuffer || !this.recordingStarted) return;
      
      try {
        const int16Array = new Int16Array(res.frameBuffer);
        this.detectAudio(int16Array);
      } catch (error) {
        console.error('处理音频帧数据错误:', error);
        // 出错时使用默认波形动画
        this.updateWaveform(false);
      }
    });
    
    // 录音结束回调
    recorderManager.onStop(res => {
      this.audioPath = res.tempFilePath;
      this.isRecording = false;
      this.recordingStarted = false;
      clearInterval(this.recordingTimer);
      clearInterval(this.animationTimer);
      clearTimeout(this.noSoundTimeout);
      this.statusMessage = '录制完成！';
      
      // 确保在所有平台上都能正确获取录音文件
      if (res.tempFilePath) {
        console.log('录音文件路径:', res.tempFilePath);
        
        // 针对iOS的特殊处理
        if (platform === 'ios' && !res.tempFilePath.startsWith('file://')) {
          this.audioPath = 'file://' + res.tempFilePath;
        } else {
          this.audioPath = res.tempFilePath;
        }
      } else {
        console.error('未获取到录音文件路径');
        uni.showToast({
          title: '录音保存失败',
          icon: 'none'
        });
      }
    });
    
    // 添加中断处理 - 主要针对iOS
    recorderManager.onInterruptionBegin && recorderManager.onInterruptionBegin(() => {
      console.log('录音被中断');
      this.statusMessage = '录音被中断，请重试';
      this.stopRecording();
    });
    
    recorderManager.onInterruptionEnd && recorderManager.onInterruptionEnd(() => {
      console.log('录音中断结束');
      // 可以选择自动重新开始录音
      // this.startRecording();
    });
  },
  beforeDestroy() {
    // 停止所有计时器
    clearInterval(this.recordingTimer);
    clearInterval(this.animationTimer);
    clearTimeout(this.noSoundTimeout);
    
    // 确保录音停止
    if (this.isRecording) {
      recorderManager.stop();
    }
    
    // 移除事件监听器
    try {
      // 注意：uni-app不支持直接移除事件监听器
      // 但我们可以确保组件销毁时停止所有活动
      this.isRecording = false;
      this.recordingStarted = false;
    } catch (error) {
      console.error('清理资源时出错:', error);
    }
  }
}
</script>

<style scoped>
.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.modal-content {
  width: 80%;
  background: #fff;
  border-radius: 20rpx;
  padding: 40rpx;
  text-align: center;
  box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.2);
}

.modal-title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 20rpx;
  color: #0039b3;
}

.modal-text {
  font-size: 30rpx;
  color: #666;
  margin-bottom: 30rpx;
}

.wave-container {
  height: 200rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4rpx; /* 减小波形条之间的间距 */
  margin: 30rpx 0;
  background: #f8f9fa;
  border-radius: 15rpx;
  position: relative;
  overflow: hidden;
  border: 1rpx solid #eee;
}

.wave-bar {
  width: 6rpx; /* 减小波形条的宽度 */
  background: linear-gradient(to top, #1a73e8, #0039b3);
  border-radius: 3rpx;
  transition: height 0.1s ease-out; /* 加快过渡动画速度 */
}

.timer {
  position: absolute;
  top: 15rpx;
  right: 15rpx;
  background: rgba(0, 57, 179, 0.1);
  color: #0039b3;
  padding: 5rpx 15rpx;
  border-radius: 20rpx;
  font-size: 26rpx;
  font-weight: 500;
}

.read-text {
  background: #f8f9fa;
  padding: 30rpx;
  border-radius: 15rpx;
  font-size: 32rpx;
  margin: 30rpx 0;
  color: #333;
  line-height: 1.6;
  border: 1rpx solid #eee;
}

.confirm-btn {
  width: 80%;
  height: 80rpx;
  line-height: 80rpx;
  background: linear-gradient(90deg, #0039b3, #1a73e8);
  color: #fff;
  border-radius: 40rpx;
  margin-top: 30rpx;
  font-size: 32rpx;
  font-weight: 500;
  box-shadow: 0 5rpx 15rpx rgba(0, 57, 179, 0.3);
}

.status-message {
  font-size: 28rpx;
  color: #666;
  margin-top: 30rpx;
  height: 40rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 添加状态消息的动画效果 */
@keyframes blink {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

.status-message.warning {
  color: #ff9800;
  animation: blink 1.5s infinite;
}
</style>