<template>
  <view class="bluetooth-recorder-page">
    <!-- #ifdef APP -->
    <statusBar></statusBar>
    <!-- #endif -->

    <view class="header">
      <view class="header-title">蓝牙录音设备</view>
      <view class="header-status" :class="{ connected: isConnected }">
        {{ isConnected ? '已连接' : '未连接' }}
      </view>
    </view>

    <!-- 设备搜索区域 -->
    <view class="section">
      <view class="section-title">设备搜索</view>
      <view class="action-buttons">
        <button 
          class="btn btn-primary" 
          :disabled="isScanning || isConnected"
          @click="handleStartScan"
        >
          {{ isScanning ? '搜索中...' : '开始搜索' }}
        </button>
        <button 
          class="btn btn-secondary" 
          :disabled="!isScanning"
          @click="handleStopScan"
        >
          停止搜索
        </button>
      </view>
    </view>

    <!-- 设备列表 -->
    <view class="section" v-if="deviceList.length > 0">
      <view class="section-title">发现的设备 ({{ deviceList.length }})</view>
      <scroll-view class="device-list" scroll-y>
        <view 
          v-for="device in deviceList" 
          :key="device.deviceId"
          class="device-item"
          :class="{ connected: connectedDeviceId === device.deviceId }"
          @click="handleConnectDevice(device)"
        >
          <view class="device-info">
            <text class="device-name">{{ device.name || '未知设备' }}</text>
            <text class="device-id">{{ device.deviceId }}</text>
            <text class="device-rssi">信号强度: {{ device.RSSI }} dBm</text>
          </view>
          <view class="device-action">
            <text v-if="connectedDeviceId === device.deviceId" class="status-text connected">已连接</text>
            <text v-else class="status-text">点击连接</text>
          </view>
        </view>
      </scroll-view>
    </view>

    <!-- 连接状态 -->
    <view class="section" v-if="isConnected">
      <view class="section-title">连接状态</view>
      <view class="connection-info">
        <text class="info-item">设备ID: {{ connectedDeviceId }}</text>
        <text class="info-item">接收状态: {{ isReceiving ? '接收中' : '未接收' }}</text>
        <text class="info-item">数据包数: {{ audioDataCount }}</text>
        <text class="info-item">缓冲区大小: {{ audioBufferSize }} KB</text>
      </view>
      <view class="action-buttons">
        <button 
          class="btn btn-danger" 
          @click="handleDisconnect"
        >
          断开连接
        </button>
        <button 
          class="btn btn-secondary" 
          @click="handleClearBuffer"
        >
          清空缓冲区
        </button>
      </view>
    </view>

    <!-- 音频数据操作 -->
    <view class="section" v-if="isConnected && audioDataCount > 0">
      <view class="section-title">音频数据</view>
      <view class="action-buttons">
        <button 
          class="btn btn-primary" 
          @click="handleSaveAudio"
        >
          保存录音文件
        </button>
        <button 
          class="btn btn-secondary" 
          @click="handleUploadAudio"
        >
          上传到服务器
        </button>
      </view>
    </view>

    <!-- 日志区域 -->
    <view class="section">
      <view class="section-title">操作日志</view>
      <scroll-view class="log-list" scroll-y scroll-top="{{ logScrollTop }}">
        <view 
          v-for="(log, index) in logs" 
          :key="index"
          class="log-item"
          :class="log.type"
        >
          <text class="log-time">{{ log.time }}</text>
          <text class="log-message">{{ log.message }}</text>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script>
import bluetoothRecorder from './utils/bluetooth.js'
// #ifdef APP
import statusBar from '@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar'
// #endif
import { post } from '@/common/request.js'
import { getApiUrl } from '@/common/config.js'

export default {
  // #ifdef APP
  components: {
    statusBar
  },
  // #endif
  data() {
    return {
      isScanning: false,
      isConnected: false,
      isReceiving: false,
      deviceList: [],
      connectedDeviceId: null,
      audioDataCount: 0,
      audioBufferSize: 0,
      logs: [],
      logScrollTop: 0
    }
  },
  onLoad() {
    this.initBluetooth()
  },
  onUnload() {
    this.cleanup()
  },
  methods: {
    /**
     * 初始化蓝牙
     */
    async initBluetooth() {
      try {
        // 设置回调函数
        bluetoothRecorder.onDeviceFound = (device) => {
          this.addLog('info', `发现设备: ${device.name || device.deviceId}`)
          this.deviceList = bluetoothRecorder.getDeviceList()
        }

        bluetoothRecorder.onDeviceConnected = (deviceId) => {
          this.addLog('success', `设备连接成功: ${deviceId}`)
          this.isConnected = true
          this.connectedDeviceId = deviceId
        }

        bluetoothRecorder.onDeviceDisconnected = (deviceId) => {
          this.addLog('warning', `设备断开连接: ${deviceId}`)
          this.isConnected = false
          this.isReceiving = false
          this.connectedDeviceId = null
        }

        bluetoothRecorder.onAudioDataReceived = (data) => {
          this.audioDataCount++
          // 估算缓冲区大小（Base64编码后约为原数据的4/3）
          const estimatedSize = (data.data.length * 3) / 4 / 1024
          this.audioBufferSize = Math.round(estimatedSize * 100) / 100
          this.isReceiving = true
        }

        bluetoothRecorder.onError = (error) => {
          this.addLog('error', error.message || '发生错误')
          uni.showToast({
            title: error.message || '操作失败',
            icon: 'none'
          })
        }

        // 初始化蓝牙适配器
        await bluetoothRecorder.initBluetoothAdapter()
        this.addLog('success', '蓝牙适配器初始化成功')
      } catch (error) {
        this.addLog('error', `初始化失败: ${error.message || error.errMsg}`)
        uni.showModal({
          title: '提示',
          content: '蓝牙初始化失败，请检查手机蓝牙是否开启',
          showCancel: false
        })
      }
    },

    /**
     * 开始搜索设备
     */
    async handleStartScan() {
      try {
        this.deviceList = []
        bluetoothRecorder.clearDeviceList()
        await bluetoothRecorder.startScan({
          allowDuplicatesKey: false,
          interval: 0
        })
        this.isScanning = true
        this.addLog('info', '开始搜索蓝牙设备...')
        
        // 10秒后自动停止搜索
        setTimeout(() => {
          if (this.isScanning) {
            this.handleStopScan()
          }
        }, 10000)
      } catch (error) {
        this.addLog('error', `搜索失败: ${error.message || error.errMsg}`)
      }
    },

    /**
     * 停止搜索
     */
    async handleStopScan() {
      try {
        await bluetoothRecorder.stopScan()
        this.isScanning = false
        this.addLog('info', '停止搜索')
      } catch (error) {
        this.addLog('error', `停止搜索失败: ${error.message || error.errMsg}`)
      }
    },

    /**
     * 连接设备
     */
    async handleConnectDevice(device) {
      if (this.connectedDeviceId === device.deviceId) {
        return
      }

      try {
        uni.showLoading({ title: '连接中...' })
        await bluetoothRecorder.connectDevice(device.deviceId)
        this.addLog('success', `正在连接设备: ${device.name || device.deviceId}`)
      } catch (error) {
        this.addLog('error', `连接失败: ${error.message || error.errMsg}`)
      } finally {
        uni.hideLoading()
      }
    },

    /**
     * 断开连接
     */
    async handleDisconnect() {
      try {
        uni.showLoading({ title: '断开中...' })
        await bluetoothRecorder.disconnectDevice()
        this.isConnected = false
        this.isReceiving = false
        this.connectedDeviceId = null
        this.audioDataCount = 0
        this.audioBufferSize = 0
        this.addLog('info', '已断开连接')
      } catch (error) {
        this.addLog('error', `断开失败: ${error.message || error.errMsg}`)
      } finally {
        uni.hideLoading()
      }
    },

    /**
     * 清空缓冲区
     */
    handleClearBuffer() {
      bluetoothRecorder.clearAudioBuffer()
      this.audioDataCount = 0
      this.audioBufferSize = 0
      this.addLog('info', '已清空音频缓冲区')
    },

    /**
     * 保存录音文件
     */
    async handleSaveAudio() {
      try {
        const audioData = bluetoothRecorder.mergeAudioData()
        if (!audioData) {
          uni.showToast({
            title: '没有可保存的音频数据',
            icon: 'none'
          })
          return
        }

        // 将Base64转换为ArrayBuffer
        const arrayBuffer = uni.base64ToArrayBuffer(audioData)
        
        // 生成文件名
        const timestamp = new Date().getTime()
        const fileName = `bluetooth_recording_${timestamp}.pcm`
        
        // #ifdef APP-PLUS
        // 保存到本地文件系统
        const fs = uni.getFileSystemManager()
        const filePath = `${uni.env.USER_DATA_PATH}/${fileName}`
        
        fs.writeFile({
          filePath: filePath,
          data: arrayBuffer,
          success: () => {
            this.addLog('success', `文件已保存: ${filePath}`)
            uni.showToast({
              title: '保存成功',
              icon: 'success'
            })
          },
          fail: (err) => {
            this.addLog('error', `保存失败: ${err.errMsg}`)
            uni.showToast({
              title: '保存失败',
              icon: 'none'
            })
          }
        })
        // #endif

        // #ifndef APP-PLUS
        uni.showToast({
          title: '当前平台不支持文件保存',
          icon: 'none'
        })
        // #endif
      } catch (error) {
        this.addLog('error', `保存失败: ${error.message || error.errMsg}`)
        uni.showToast({
          title: '保存失败',
          icon: 'none'
        })
      }
    },

    /**
     * 上传音频到服务器
     */
    async handleUploadAudio() {
      try {
        const audioData = bluetoothRecorder.mergeAudioData()
        if (!audioData) {
          uni.showToast({
            title: '没有可上传的音频数据',
            icon: 'none'
          })
          return
        }

        uni.showLoading({ title: '上传中...' })

        // 将Base64转换为ArrayBuffer
        const arrayBuffer = uni.base64ToArrayBuffer(audioData)
        
        // 创建FormData
        const formData = {
          audio: arrayBuffer,
          fileName: `bluetooth_recording_${new Date().getTime()}.pcm`,
          deviceId: this.connectedDeviceId
        }

        // 上传到服务器（需要根据实际API调整）
        const url = getApiUrl('/api/audioManagement/upload')
        const res = await post(url, formData, {
          header: {
            'Content-Type': 'multipart/form-data'
          }
        })

        if (res.statusCode === 200 && res.data && res.data.success) {
          this.addLog('success', '音频上传成功')
          uni.showToast({
            title: '上传成功',
            icon: 'success'
          })
        } else {
          throw new Error(res.data?.message || '上传失败')
        }
      } catch (error) {
        this.addLog('error', `上传失败: ${error.message || error.errMsg}`)
        uni.showToast({
          title: '上传失败',
          icon: 'none'
        })
      } finally {
        uni.hideLoading()
      }
    },

    /**
     * 添加日志
     */
    addLog(type, message) {
      const time = new Date().toLocaleTimeString()
      this.logs.unshift({
        type,
        message,
        time
      })
      
      // 限制日志数量
      if (this.logs.length > 50) {
        this.logs = this.logs.slice(0, 50)
      }

      // 滚动到底部
      this.$nextTick(() => {
        this.logScrollTop = 9999
      })
    },

    /**
     * 清理资源
     */
    async cleanup() {
      try {
        if (this.isConnected) {
          await bluetoothRecorder.disconnectDevice()
        }
        if (this.isScanning) {
          await bluetoothRecorder.stopScan()
        }
        await bluetoothRecorder.closeBluetoothAdapter()
      } catch (error) {
        console.error('清理资源失败', error)
      }
    }
  }
}
</script>

<style scoped>
.bluetooth-recorder-page {
  min-height: 100vh;
  background: #f5f5f5;
  padding-bottom: 20rpx;
}

.header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
  padding: 40rpx 30rpx 30rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  font-size: 36rpx;
  font-weight: bold;
}

.header-status {
  font-size: 28rpx;
  padding: 8rpx 20rpx;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 20rpx;
}

.header-status.connected {
  background: rgba(76, 175, 80, 0.8);
}

.section {
  background: #fff;
  margin: 20rpx 30rpx;
  padding: 30rpx;
  border-radius: 16rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}

.section-title {
  font-size: 32rpx;
  font-weight: bold;
  margin-bottom: 20rpx;
  color: #333;
}

.action-buttons {
  display: flex;
  gap: 20rpx;
}

.btn {
  flex: 1;
  padding: 20rpx;
  border-radius: 8rpx;
  font-size: 28rpx;
  border: none;
}

.btn-primary {
  background: #667eea;
  color: #fff;
}

.btn-secondary {
  background: #e0e0e0;
  color: #666;
}

.btn-danger {
  background: #f44336;
  color: #fff;
}

.btn:disabled {
  opacity: 0.5;
}

.device-list {
  max-height: 600rpx;
}

.device-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx;
  margin-bottom: 20rpx;
  background: #f9f9f9;
  border-radius: 12rpx;
  border: 2rpx solid transparent;
}

.device-item.connected {
  border-color: #667eea;
  background: #f0f4ff;
}

.device-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.device-name {
  font-size: 30rpx;
  font-weight: bold;
  color: #333;
}

.device-id {
  font-size: 24rpx;
  color: #999;
}

.device-rssi {
  font-size: 24rpx;
  color: #666;
}

.device-action {
  padding: 10rpx 20rpx;
}

.status-text {
  font-size: 26rpx;
  color: #999;
}

.status-text.connected {
  color: #667eea;
  font-weight: bold;
}

.connection-info {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
  margin-bottom: 20rpx;
}

.info-item {
  font-size: 28rpx;
  color: #666;
}

.log-list {
  max-height: 400rpx;
  background: #f9f9f9;
  border-radius: 8rpx;
  padding: 20rpx;
}

.log-item {
  display: flex;
  gap: 20rpx;
  padding: 12rpx 0;
  border-bottom: 1rpx solid #eee;
  font-size: 24rpx;
}

.log-item:last-child {
  border-bottom: none;
}

.log-time {
  color: #999;
  min-width: 120rpx;
}

.log-message {
  flex: 1;
  color: #333;
}

.log-item.success .log-message {
  color: #4caf50;
}

.log-item.error .log-message {
  color: #f44336;
}

.log-item.warning .log-message {
  color: #ff9800;
}

.log-item.info .log-message {
  color: #2196f3;
}
</style>

