<template>
  <view class="mixer-page">
    <!-- 顶部蓝牙状态栏 -->
    <view class="custom-navbar">
      <view class="navbar-content">
        <view class="nav-left" @click="goBack">
          <uni-icons type="back" color="#fff" size="20"></uni-icons>
        </view>
        <view class="nav-center">
          <text class="nav-title">{{ deviceName || '六通道搅拌器' }}</text>
        </view>
        <view class="nav-right">
          <view class="bluetooth-status" @click="showDeviceInfo">
            <uni-icons type="bluetooth-filled" color="#fff" size="20"></uni-icons>
            <text class="status-text">{{ connected ? '已连接' : '未连接' }}</text>
          </view>
        </view>
      </view>
    </view>

    <view class="mixer-container">
      <!-- 选择状态栏 -->
      <view class="selection-status">
        <view class="status-row">
          <view class="status-item">
            <text class="status-label">已选择：</text>
            <text :class="['status-value', selectedChannels.length > 0 ? 'status-on' : 'status-off']">
              {{ selectedChannels.length }}/{{ channels.length }} 通道
            </text>
          </view>
          <view class="select-actions">
            <text class="action-link" @click="selectAll">全选</text>
            <text class="action-divider">|</text>
            <text class="action-link" @click="clearSelection">清空</text>
          </view>
        </view>
      </view>

      <!-- 通道卡片网格 -->
      <view class="channel-grid">
        <view 
          v-for="channel in channels" 
          :key="channel.id"
          :class="['channel-card', { 'selected': isChannelSelected(channel.id) }]"
        >
          <!-- 通道标题 -->
          <view class="card-header">
            <!-- 选择复选框（内联在标题左侧） -->
            <view class="channel-checkbox-inline" @click.stop="toggleChannelSelection(channel.id)">
              <view :class="['checkbox-icon', { 'checked': isChannelSelected(channel.id) }]">
                <text v-if="isChannelSelected(channel.id)" class="check-mark">✓</text>
              </view>
            </view>
            
            <text class="channel-title">{{ channel.name }}</text>
            <view :class="['status-indicator', channel.status]">
              <view class="status-dot"></view>
              <text class="status-text">{{ getStatusText(channel.status) }}</text>
            </view>
          </view>

          <!-- 运行模式控制 -->
          <view class="mode-controls">
            <!-- 转速调节滑块 -->
            <view class="slider-group" @click.stop>
              <text class="slider-label">转速</text>
              <text class="slider-min-value">0</text>
              <slider 
                :value="channel.runValue" 
                :min="0" 
                :max="100"
                @change="e => updateRunValue(channel.id, e.detail.value)"
                :disabled="channel.status === 'stopped'"
                activeColor="#22c55e"
                backgroundColor="#e5e7eb"
                block-size="20"
              />
              <text class="slider-max-value">400</text>
            </view>
            
            <!-- 转速数值显示 -->
            <view class="speed-display">
              <text class="speed-value">{{ calculateSpeed(channel.runValue) }}</text>
              <text class="speed-unit">转/分</text>
            </view>
          </view>

          <!-- 定时设置 -->
          <view class="timer-setting" @click.stop="setTimer(channel.id)">
            <text class="timer-emoji">⏱</text>
            <text class="timer-label">{{ channel.timerMode }}：</text>
            <text class="timer-value">{{ channel.timerValue }}</text>
          </view>

          <!-- 启停按钮 -->
          <view class="card-footer">
            <view 
              v-if="channel.status === 'stopped'"
              class="start-btn"
              @click.stop="handleChannelStart(channel.id)"
            >
              <text class="btn-text">启动</text>
            </view>
            <view 
              v-else
              class="stop-btn"
              @click.stop="handleChannelStop(channel.id)"
            >
              <text class="btn-text">停止</text>
            </view>
          </view>
        </view>
      </view>

      <!-- 底部控制区 -->
      <view class="bottom-controls">
        <!-- 批量操作按钮 -->
        <view class="batch-buttons">
          <u-button 
            type="primary" 
            @click="batchStart"
            :disabled="selectedChannels.length === 0"
            :custom-style="{flex: 1, height: '88rpx', fontSize: '28rpx', fontWeight: '600', borderRadius: '16rpx'}"
          >
            <uni-icons type="checkmarkempty" color="#fff" size="24" style="margin-right: 8rpx;"></uni-icons>
            启动选中({{ selectedChannels.length }})
          </u-button>
          <u-button 
            type="error" 
            @click="batchStop"
            :disabled="selectedChannels.length === 0"
            :custom-style="{flex: 1, height: '88rpx', fontSize: '28rpx', fontWeight: '600', borderRadius: '16rpx', marginLeft: '20rpx'}"
          >
            <uni-icons type="closeempty" color="#fff" size="24" style="margin-right: 8rpx;"></uni-icons>
            停止选中({{ selectedChannels.length }})
          </u-button>
        </view>
      </view>
    </view>


  </view>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

// 本地存储 key
const STORAGE_KEY_PREFIX = 'mixer_channel_'
const STORAGE_KEY_START_MODE = 'mixer_start_mode'

// 蓝牙连接状态
const connected = ref(false)
const deviceId = ref('')
const deviceName = ref('')
const serviceId = ref('') // 蓝牙服务 UUID
const characteristicId = ref('') // 蓝牙特征值 UUID
const notifyCharacteristicId = ref('') // 监听特征值 UUID（用于接收数据）

// 通道选择
const selectedChannels = ref([])

// 定时器存储
const timerIntervals = ref({})
// 数据查询定时器
const dataQueryTimer = ref(null)
// 是否正在查询数据
const isQuerying = ref(false)

// 通道数据
const channels = ref([
  {
    id: 'CH1',
    name: 'CH1',
    status: 'stopped', // running, stopped, timing
    mode: 'number', // color, number
    currentValue: '0-400',
    runValue: 60,
    controlType: 'speed', // speed, status
    timerMode: '定时', // 定时, 格式
    timerValue: '未设置',
    remainingTime: 0, // 剩余秒数
    timerHours: 0 // 设置的小时数
  },
  {
    id: 'CH2',
    name: 'CH2',
    status: 'stopped',
    mode: 'number',
    currentValue: '0-400',
    runValue: 65,
    controlType: 'speed',
    timerMode: '定时',
    timerValue: '未设置',
    remainingTime: 0,
    timerHours: 0
  },
  {
    id: 'CH3',
    name: 'CH3',
    status: 'stopped',
    mode: 'number',
    currentValue: '0-400',
    runValue: 70,
    controlType: 'speed',
    timerMode: '定时',
    timerValue: '未设置',
    remainingTime: 0,
    timerHours: 0
  },
  {
    id: 'CH4',
    name: 'CH4',
    status: 'stopped',
    mode: 'number',
    currentValue: '0-400',
    runValue: 75,
    controlType: 'speed',
    timerMode: '定时',
    timerValue: '未设置',
    remainingTime: 0,
    timerHours: 0
  },
  {
    id: 'CH5',
    name: 'CH5',
    status: 'stopped',
    mode: 'number',
    currentValue: '0-400',
    runValue: 80,
    controlType: 'speed',
    timerMode: '定时',
    timerValue: '未设置',
    remainingTime: 0,
    timerHours: 0
  },
  {
    id: 'CH6',
    name: 'CH6',
    status: 'stopped',
    mode: 'number',
    currentValue: '0-400',
    runValue: 50,
    controlType: 'speed',
    timerMode: '定时',
    timerValue: '未设置',
    remainingTime: 0,
    timerHours: 0
  }
])

// 页面加载
onLoad((options) => {
  if (options.deviceId) {
    deviceId.value = options.deviceId
    deviceName.value = decodeURIComponent(options.deviceName || '') || '六通道搅拌器'
    connected.value = true
    
    // 获取蓝牙服务和特征值信息
    if (options.serviceId) {
      serviceId.value = options.serviceId
    }
    if (options.characteristicId) {
      characteristicId.value = options.characteristicId
    }
    if (options.notifyCharacteristicId) {
      notifyCharacteristicId.value = options.notifyCharacteristicId
    }
    
    // 初始化蓝牙通信
    initBluetoothCommunication()
  }
  
  // 加载所有通道的保存数据
  loadAllChannelsData()
})



// 加载所有通道数据
const loadAllChannelsData = () => {
  channels.value.forEach(channel => {
    loadChannelData(channel.id)
  })
}

// 加载单个通道数据
const loadChannelData = (channelId) => {
  try {
    const savedData = uni.getStorageSync(STORAGE_KEY_PREFIX + channelId)
    if (savedData) {
      const data = JSON.parse(savedData)
      const channel = channels.value.find(c => c.id === channelId)
      if (channel) {
        // 恢复保存的数据，但状态默认为停止
        channel.runValue = data.runValue || channel.runValue
        channel.timerHours = data.timerHours || 0
        channel.remainingTime = 0
        channel.status = 'stopped'
        
        if (channel.timerHours > 0) {
          channel.timerValue = `设置 ${channel.timerHours} 小时`
        }
      }
    }
  } catch (e) {
    console.error('加载通道数据失败:', e)
  }
}

// 保存通道数据
const saveChannelData = (channelId) => {
  try {
    const channel = channels.value.find(c => c.id === channelId)
    if (channel) {
      const data = {
        runValue: channel.runValue,
        timerHours: channel.timerHours
      }
      uni.setStorageSync(STORAGE_KEY_PREFIX + channelId, JSON.stringify(data))
    }
  } catch (e) {
    console.error('保存通道数据失败:', e)
  }
}

// 选择/取消选择通道
const toggleChannelSelection = (channelId) => {
  const index = selectedChannels.value.indexOf(channelId)
  if (index > -1) {
    selectedChannels.value.splice(index, 1)
  } else {
    selectedChannels.value.push(channelId)
  }
}

// 判断通道是否被选中
const isChannelSelected = (channelId) => {
  return selectedChannels.value.includes(channelId)
}

// 全选
const selectAll = () => {
  selectedChannels.value = channels.value.map(c => c.id)
  uni.showToast({
    title: '已全选',
    icon: 'success',
    duration: 1000
  })
}

// 清空选择
const clearSelection = () => {
  selectedChannels.value = []
  uni.showToast({
    title: '已清空选择',
    icon: 'success',
    duration: 1000
  })
}

// 获取状态文本
const getStatusText = (status) => {
  const statusMap = {
    running: '运行中',
    stopped: '已停止',
    timing: '定时中'
  }
  return statusMap[status] || '未知'
}

// 返回
const goBack = () => {
  uni.navigateBack()
}

// 显示设备信息
const showDeviceInfo = () => {
  uni.showModal({
    title: '设备信息',
    content: `设备名称：${deviceName.value}\n设备ID：${deviceId.value}\n连接状态：${connected.value ? '已连接' : '未连接'}`,
    showCancel: false
  })
}

// 更新运行值（转速）
const updateRunValue = (channelId, value) => {
  const channel = channels.value.find(c => c.id === channelId)
  if (channel) {
    channel.runValue = value
    saveChannelData(channelId)
    sendBluetoothCommand('setRunValue', channelId, value)
  }
}

// 计算实际转速（0-100 映射到 0-400）
const calculateSpeed = (value) => {
  return Math.round(value * 4)
}

// 设置定时
const setTimer = (channelId) => {
  const channel = channels.value.find(c => c.id === channelId)
  if (!channel) return
  
  uni.showModal({
    title: '定时设置',
    editable: true,
    placeholderText: '请输入小时数(0-99)',
    content: channel.timerHours > 0 ? String(channel.timerHours) : '',
    success: (res) => {
      if (res.confirm && res.content) {
        const hours = parseInt(res.content)
        if (isNaN(hours) || hours < 0 || hours > 99) {
          uni.showToast({
            title: '请输入0-99的数字',
            icon: 'none'
          })
          return
        }
        
        channel.timerHours = hours
        channel.remainingTime = hours * 3600 // 转为秒（小时*3600）
        
        if (hours > 0) {
          channel.timerValue = `设置 ${hours} 小时`
        } else {
          channel.timerValue = '未设置'
        }
        
        saveChannelData(channelId)
        sendBluetoothCommand('setTimer', channelId, hours)
        
        uni.showToast({
          title: `定时设置成功`,
          icon: 'success'
        })
      }
    }
  })
}

// 处理通道启动
const handleChannelStart = (channelId) => {
  startChannel(channelId)
}

// 处理通道停止
const handleChannelStop = (channelId) => {
  stopChannel(channelId)
}

// 启动通道
const startChannel = (channelId) => {
  const channel = channels.value.find(c => c.id === channelId)
  if (channel) {
    // 如果设置了定时，进入定时模式
    if (channel.timerHours > 0) {
      channel.status = 'timing'
      // 重置剩余时间
      channel.remainingTime = channel.timerHours * 3600
      startTimer(channelId)
    } else {
      channel.status = 'running'
    }
    
    sendBluetoothCommand('start', channelId)
    uni.showToast({
      title: `${channel.name} 已启动`,
      icon: 'success'
    })
  }
}

// 停止通道
const stopChannel = (channelId) => {
  const channel = channels.value.find(c => c.id === channelId)
  if (channel) {
    channel.status = 'stopped'
    stopTimer(channelId)
    sendBluetoothCommand('stop', channelId)
    uni.showToast({
      title: `${channel.name} 已停止`,
      icon: 'success'
    })
  }
}

// 批量启动选中的通道
const batchStart = () => {
  if (selectedChannels.value.length === 0) {
    uni.showToast({
      title: '请先选择通道',
      icon: 'none'
    })
    return
  }
  
  uni.showModal({
    title: '确认启动',
    content: `是否启动选中的 ${selectedChannels.value.length} 个通道？`,
    success: (res) => {
      if (res.confirm) {
        selectedChannels.value.forEach(channelId => {
          startChannel(channelId)
        })
        uni.showToast({
          title: `已启动 ${selectedChannels.value.length} 个通道`,
          icon: 'success'
        })
      }
    }
  })
}

// 批量停止选中的通道
const batchStop = () => {
  if (selectedChannels.value.length === 0) {
    uni.showToast({
      title: '请先选择通道',
      icon: 'none'
    })
    return
  }
  
  uni.showModal({
    title: '确认停止',
    content: `是否停止选中的 ${selectedChannels.value.length} 个通道？`,
    success: (res) => {
      if (res.confirm) {
        selectedChannels.value.forEach(channelId => {
          stopChannel(channelId)
        })
        uni.showToast({
          title: `已停止 ${selectedChannels.value.length} 个通道`,
          icon: 'success'
        })
      }
    }
  })
}

// 启动定时器
const startTimer = (channelId) => {
  const channel = channels.value.find(c => c.id === channelId)
  if (!channel || channel.remainingTime <= 0) return
  
  // 清除旧定时器
  stopTimer(channelId)
  
  // 创建新定时器（后台倒计时，不显示给用户）
  timerIntervals.value[channelId] = setInterval(() => {
    if (channel.remainingTime > 0) {
      channel.remainingTime--
      
      // 定时到期
      if (channel.remainingTime === 0) {
        stopTimer(channelId)
        channel.status = 'stopped'
        
        // 发送停止命令
        sendBluetoothCommand('stop', channelId)
        
        uni.showToast({
          title: `${channel.name} 定时已到，自动停止`,
          icon: 'none',
          duration: 2000
        })
      }
    }
  }, 1000)
}

// 停止定时器
const stopTimer = (channelId) => {
  if (timerIntervals.value[channelId]) {
    clearInterval(timerIntervals.value[channelId])
    delete timerIntervals.value[channelId]
  }
}

// 发送蓝牙命令
const sendBluetoothCommand = (command, channelId, value) => {
  if (!connected.value) {
    uni.showToast({
      title: '蓝牙未连接',
      icon: 'none'
    })
    return
  }
  
  if (!characteristicId.value) {
    console.error('未找到可写入的特征值')
    return
  }
  
  try {
    // 构造简短的 JSON 命令（减少字节数）
    const commandData = {
      c: command,           // cmd 缩写为 c
      n: channelId,         // channel 缩写为 n
      v: value || 0         // value 缩写为 v
    }
    
    const jsonStr = JSON.stringify(commandData)
    console.log('发送蓝牙命令:', jsonStr, `(${jsonStr.length} 字节)`)
    
    // 检查是否需要分包
    if (jsonStr.length <= 20) {
      // 单包发送
      sendSinglePacket(jsonStr)
    } else {
      // 分包发送
      sendMultiplePackets(jsonStr)
    }
  } catch (error) {
    console.error('构造蓝牙命令失败:', error)
  }
}

// 发送单个数据包
const sendSinglePacket = (data) => {
  const buffer = stringToArrayBuffer(data)
  
  uni.writeBLECharacteristicValue({
    deviceId: deviceId.value,
    serviceId: serviceId.value,
    characteristicId: characteristicId.value,
    value: buffer,
    success: (res) => {
      console.log('✅ 蓝牙数据发送成功')
    },
    fail: (err) => {
      console.error('❌ 蓝牙数据发送失败:', err)
      uni.showToast({
        title: '发送失败',
        icon: 'none'
      })
    }
  })
}

// 分包发送（超过 20 字节）
const sendMultiplePackets = (data) => {
  const maxPacketSize = 20
  const packets = []
  
  // 将数据分割成多个包
  for (let i = 0; i < data.length; i += maxPacketSize) {
    packets.push(data.slice(i, i + maxPacketSize))
  }
  
  console.log(`📦 数据需要分 ${packets.length} 包发送`)
  
  // 依次发送每个包（间隔 100ms）
  packets.forEach((packet, index) => {
    setTimeout(() => {
      const buffer = stringToArrayBuffer(packet)
      
      uni.writeBLECharacteristicValue({
        deviceId: deviceId.value,
        serviceId: serviceId.value,
        characteristicId: characteristicId.value,
        value: buffer,
        success: () => {
          console.log(`✅ 第 ${index + 1}/${packets.length} 包发送成功`)
        },
        fail: (err) => {
          console.error(`❌ 第 ${index + 1}/${packets.length} 包发送失败:`, err)
        }
      })
    }, index * 100)
  })
}

// 字符串转 ArrayBuffer（辅助函数）
const stringToArrayBuffer = (str) => {
  const buffer = new ArrayBuffer(str.length)
  const dataView = new Uint8Array(buffer)
  for (let i = 0; i < str.length; i++) {
    dataView[i] = str.charCodeAt(i)
  }
  return buffer
}

// ArrayBuffer 转字符串（辅助函数）
const arrayBufferToString = (buffer) => {
  const dataView = new Uint8Array(buffer)
  let str = ''
  for (let i = 0; i < dataView.length; i++) {
    str += String.fromCharCode(dataView[i])
  }
  return str
}

// 初始化蓝牙通信
const initBluetoothCommunication = () => {
  if (!deviceId.value) return
  
  // 监听蓝牙设备连接状态
  uni.onBLEConnectionStateChange((res) => {
    console.log('蓝牙连接状态变化:', res)
    connected.value = res.connected
    
    if (!res.connected) {
      uni.showToast({
        title: '蓝牙已断开',
        icon: 'none'
      })
      // 停止数据查询
      stopDataQuery()
    }
  })
  
  // 监听特征值变化（接收数据）
  if (notifyCharacteristicId.value) {
    uni.onBLECharacteristicValueChange((res) => {
      console.log('收到蓝牙数据:', res)
      handleBluetoothData(res.value)
    })
    
    // 启用通知
    uni.notifyBLECharacteristicValueChange({
      deviceId: deviceId.value,
      serviceId: serviceId.value,
      characteristicId: notifyCharacteristicId.value,
      state: true,
      success: () => {
        console.log('启用蓝牙数据监听成功')
        // 启动定时查询
        startDataQuery()
      },
      fail: (err) => {
        console.error('启用蓝牙数据监听失败:', err)
      }
    })
  }
}

// 处理接收到的蓝牙数据
const handleBluetoothData = (buffer) => {
  try {
    // 将 ArrayBuffer 转换为字符串或根据协议解析
    const dataStr = arrayBufferToString(buffer)
    console.log('解析蓝牙数据:', dataStr)
    
    // 尝试解析为 JSON（根据实际协议调整）
    try {
      const data = JSON.parse(dataStr)
      updateChannelFromDevice(data)
    } catch (e) {
      // 如果不是 JSON 格式，按照其他协议解析
      console.log('非 JSON 格式数据:', dataStr)
    }
  } catch (error) {
    console.error('解析蓝牙数据失败:', error)
  }
}

// 根据设备返回的数据更新通道状态
const updateChannelFromDevice = (data) => {
  if (!data.channel) return
  
  const channel = channels.value.find(c => c.id === data.channel)
  if (channel) {
    // 更新通道状态（根据实际数据格式调整）
    if (data.status !== undefined) {
      channel.status = data.status // running/stopped/timing
    }
    if (data.speed !== undefined) {
      channel.runValue = Math.round(data.speed / 4) // 实际转速转回 0-100
    }
    if (data.remainingTime !== undefined) {
      channel.remainingTime = data.remainingTime
    }
    
    console.log(`通道 ${data.channel} 状态已更新:`, channel)
  }
}

// 启动定时查询所有通道数据
const startDataQuery = () => {
  // 如果已经在查询，先停止
  if (dataQueryTimer.value) {
    stopDataQuery()
  }
  
  console.log('启动定时查询通道数据')
  
  // 立即查询一次
  queryAllChannelsData()
  
  // 每 2 秒查询一次
  dataQueryTimer.value = setInterval(() => {
    queryAllChannelsData()
  }, 2000)
}

// 停止定时查询
const stopDataQuery = () => {
  if (dataQueryTimer.value) {
    clearInterval(dataQueryTimer.value)
    dataQueryTimer.value = null
    console.log('已停止定时查询')
  }
}

// 查询所有通道数据
const queryAllChannelsData = () => {
  if (!connected.value || isQuerying.value) {
    return
  }
  
  isQuerying.value = true
  
  // 依次查询每个通道（根据实际协议调整）
  channels.value.forEach((channel, index) => {
    setTimeout(() => {
      sendBluetoothCommand('query', channel.id)
    }, index * 100) // 每个通道间隔 100ms，避免数据冲突
  })
  
  // 查询完成后重置标志
  setTimeout(() => {
    isQuerying.value = false
  }, channels.value.length * 100 + 500)
}

// 页面卸载
onUnmounted(() => {
  // 清除所有定时器
  Object.keys(timerIntervals.value).forEach(channelId => {
    stopTimer(channelId)
  })
  
  // 停止数据查询
  stopDataQuery()
  
  // 关闭蓝牙连接（可选，如果需要保持连接则不关闭）
  if (connected.value && deviceId.value) {
    uni.closeBLEConnection({
      deviceId: deviceId.value,
      success: () => {
        console.log('蓝牙连接已关闭')
      }
    })
  }
})
</script>

<style lang="scss" scoped>
page {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #667eea;
}

.mixer-page {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

// 自定义导航栏
.custom-navbar {
  width: 100%;
  background: rgba(102, 126, 234, 0.9);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 999;
  // 给状态栏留空间（真机上自动适配，浏览器上固定20px）
  padding-top: max(env(safe-area-inset-top), 20px);
  
  .navbar-content {
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 16rpx;
    padding-right: 16rpx;
    position: relative;
  }
  
  .nav-center {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    
    .nav-title {
      font-size: 32rpx;
      font-weight: 600;
      color: #fff;
    }
  }
}

.nav-left {
  display: flex;
  align-items: center;
  padding: 0 10rpx;
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 16rpx;
}

.mode-switch {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8rpx 16rpx;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 20rpx;
  border: 2rpx solid rgba(255, 255, 255, 0.4);
  
  .mode-text {
    font-size: 24rpx;
    color: #fff;
    font-weight: 600;
  }
}

.bluetooth-status {
  display: flex;
  align-items: center;
  gap: 8rpx;
  padding: 0 10rpx;
  
  .status-text {
    font-size: 24rpx;
    color: #fff;
  }
}

.mixer-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  // 避免被导航栏遮挡(真机上自动适配,浏览器上固定64px)
  padding-top: max(calc(44px + env(safe-area-inset-top)), 64px);
  padding-bottom: 140rpx;
  
  // 平板竖屏减小底部内边距
  @media (min-width: 768px) and (orientation: portrait) {
    padding-bottom: 130rpx;
  }
}

// 选择状态栏
.selection-status {
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.95);
  padding: 16rpx 24rpx;
  margin: 16rpx 20rpx 8rpx 20rpx;
  border-radius: 20rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
  
  .status-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .status-item {
    display: flex;
    align-items: center;
    
    .status-label {
      font-size: 28rpx;
      color: #666;
    }
    
    .status-value {
      font-size: 28rpx;
      font-weight: 600;
      
      &.status-on {
        color: #667eea;
      }
      
      &.status-off {
        color: #999;
      }
    }
  }
  
  .select-actions {
    display: flex;
    align-items: center;
    gap: 16rpx;
    
    .action-link {
      font-size: 26rpx;
      color: #667eea;
      font-weight: 600;
      
      &:active {
        opacity: 0.7;
      }
    }
    
    .action-divider {
      font-size: 26rpx;
      color: #d1d5db;
    }
  }
}

.channel-grid {
  flex: 1;
  display: grid;
  gap: 10rpx;
  padding: 0 20rpx 10rpx 20rpx;
  overflow: hidden;
  align-content: stretch;
  
  // 手机端竖屏：2列3行，固定高度
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(3, 1fr);
  
  // 手机端横屏：3列2行，固定高度
  @media (orientation: landscape) and (max-width: 767px) {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 1fr);
  }
  
  // 平板竖屏(768px-1023px)：2列3行，进一步减小间距
  @media (min-width: 768px) and (max-width: 1023px) and (orientation: portrait) {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(3, 1fr);
    gap: 8rpx;
    padding: 0 14rpx 12rpx 14rpx;
  }
  
  // 平板横屏(768px-1280px)：3列2行，减小间距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 1fr);
    gap: 12rpx;
    padding: 0 16rpx 16rpx 16rpx;
  }
  
  // 大屏幕设备(>1280px)：3列2行
  @media (min-width: 1281px) {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 1fr);
    gap: 24rpx;
    padding: 0 32rpx 32rpx 32rpx;
  }
}

.channel-card {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 16rpx;
  padding: 12rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
  border: 3rpx solid transparent;
  position: relative;
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 0;
  overflow: hidden;
  
  // 平板竖屏进一步减小内边距
  @media (min-width: 768px) and (orientation: portrait) {
    padding: 6rpx;
  }
  
  // 平板横屏减小内边距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    padding: 12rpx;
  }
  
  // 大屏增加内边距
  @media (min-width: 1281px) {
    padding: 20rpx;
  }
  
  &.selected {
    border-color: #667eea;
    background: linear-gradient(135deg, #f8f9ff 0%, #ffffff 100%);
    box-shadow: 0 8rpx 32rpx rgba(102, 126, 234, 0.3);
  }
  
  &:active {
    transform: scale(0.98);
  }
}

// 选择复选框（内联样式）
.channel-checkbox-inline {
  display: flex;
  align-items: center;
  margin-right: 10rpx;
  cursor: pointer;
  
  .checkbox-icon {
    width: 40rpx;
    height: 40rpx;
    border-radius: 50%;
    border: 3rpx solid #d1d5db;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    transition: all 0.3s ease;
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
    
    &:active {
      transform: scale(0.9);
    }
    
    &.checked {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      border-color: #667eea;
      box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.4);
      
      .check-mark {
        color: #fff;
        font-size: 28rpx;
        font-weight: 700;
      }
    }
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8rpx;
  padding-bottom: 6rpx;
  border-bottom: 2rpx solid #e2e8f0;
  flex-shrink: 0;
  
  // 平板竖屏减小间距
  @media (min-width: 768px) and (orientation: portrait) {
    margin-bottom: 2rpx;
    padding-bottom: 2rpx;
  }
  
  // 平板横屏减小间距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    margin-bottom: 6rpx;
    padding-bottom: 4rpx;
  }
  
  .channel-title {
    font-size: 28rpx;
    font-weight: 700;
    color: #1e293b;
    letter-spacing: 1rpx;
    
    // 平板竖屏减小字体
    @media (min-width: 768px) and (orientation: portrait) {
      font-size: 26rpx;
    }
  }
  
  .status-indicator {
    display: flex;
    align-items: center;
    gap: 6rpx;
    padding: 6rpx 12rpx;
    background: #f1f5f9;
    border-radius: 24rpx;
    
    // 平板及以上设备增加内边距
    @media (min-width: 768px) {
      gap: 8rpx;
      padding: 8rpx 16rpx;
    }
    
    .status-dot {
      width: 12rpx;
      height: 12rpx;
      border-radius: 50%;
      background: #cbd5e1;
    }
    
    .status-text {
      font-size: 20rpx;
      color: #475569;
      font-weight: 600;
      
      // 平板竖屏减小字体
      @media (min-width: 768px) and (orientation: portrait) {
        font-size: 18rpx;
      }
    }
    
    &.running {
      background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
      
      .status-dot {
        background: #22c55e;
        animation: pulse 2s infinite;
        box-shadow: 0 0 8rpx rgba(34, 197, 94, 0.6);
      }
      
      .status-text {
        color: #166534;
      }
    }
    
    &.stopped {
      background: #f1f5f9;
      
      .status-dot {
        background: #94a3b8;
      }
      
      .status-text {
        color: #64748b;
      }
    }
    
    &.timing {
      background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
      
      .status-dot {
        background: #f59e0b;
        animation: pulse 1s infinite;
        box-shadow: 0 0 8rpx rgba(245, 158, 11, 0.6);
      }
      
      .status-text {
        color: #92400e;
      }
    }
  }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.current-value {
  text-align: center;
  margin-bottom: 24rpx;
  padding: 20rpx;
  background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
  border-radius: 16rpx;
  border: 2rpx solid #bae6fd;
  
  .value-color,
  .value-number {
    font-size: 52rpx;
    font-weight: 700;
    color: #0c4a6e;
    text-shadow: 0 2rpx 4rpx rgba(12, 74, 110, 0.1);
    letter-spacing: 2rpx;
  }
}

.mode-controls {
  margin-bottom: 8rpx;
  flex-shrink: 0;
  
  // 平板竖屏减小间距
  @media (min-width: 768px) and (orientation: portrait) {
    margin-bottom: 2rpx;
  }
  
  // 平板横屏减小间距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    margin-bottom: 6rpx;
  }
}

.slider-group {
  display: flex;
  align-items: center;
  padding: 6rpx 0rpx;
  background: #f8fafc;
  border-radius: 12rpx;
  
  // 平板竖屏减小内边距
  @media (min-width: 768px) and (orientation: portrait) {
    padding: 2rpx 0rpx;
  }
  
  // 平板横屏减小内边距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    padding: 4rpx 0rpx;
  }

  .slider-label {
    font-size: 22rpx;
    color: #475569;
    font-weight: 600;
    margin-right: 10rpx;
    flex-shrink: 0;
  }
  
  .slider-min-value {
    font-size: 22rpx;
    color: #64748b;
    font-weight: 600;
    margin-right: 10rpx;
    flex-shrink: 0;
  }
  
  slider {
    flex: 1;
    margin: 0 8rpx;
  }
  
  .slider-max-value {
    font-size: 22rpx;
    color: #64748b;
    font-weight: 600;
    margin-left: 10rpx;
    flex-shrink: 0;
  }
}

.speed-display {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 6rpx;
  margin-top: 6rpx;
  padding: 6rpx;
  background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
  border-radius: 12rpx;
  border: 2rpx solid #86efac;
  
  // 平板竖屏减小间距
  @media (min-width: 768px) and (orientation: portrait) {
    margin-top: 2rpx;
    padding: 2rpx;
  }
  
  // 平板横屏减小间距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    margin-top: 4rpx;
    padding: 4rpx;
  }

  .speed-value {
    font-size: 32rpx;
    font-weight: 700;
    color: #166534;
    
    // 平板竖屏减小字体
    @media (min-width: 768px) and (orientation: portrait) {
      font-size: 28rpx;
    }
  }
  
  .speed-unit {
    font-size: 22rpx;
    color: #16a34a;
    font-weight: 600;
  }
}

.timer-setting {
  display: flex;
  align-items: center;
  gap: 6rpx;
  padding: 8rpx;
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  border-radius: 12rpx;
  margin-bottom: 8rpx;
  border: 2rpx solid #fbbf24;
  flex-shrink: 0;
  
  // 平板竖屏减小间距和内边距
  @media (min-width: 768px) and (orientation: portrait) {
    margin-bottom: 2rpx;
    padding: 3rpx;
  }
  
  // 平板横屏减小间距和内边距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    margin-bottom: 6rpx;
    padding: 6rpx;
  }

  .timer-emoji {
    font-size: 24rpx;
    line-height: 1;
  }
  
  .timer-label {
    font-size: 22rpx;
    color: #92400e;
    font-weight: 600;
    
    // 平板竖屏减小字体
    @media (min-width: 768px) and (orientation: portrait) {
      font-size: 20rpx;
    }
  }
  
  .timer-value {
    flex: 1;
    font-size: 22rpx;
    color: #92400e;
    font-weight: 700;
    
    // 平板竖屏减小字体
    @media (min-width: 768px) and (orientation: portrait) {
      font-size: 20rpx;
    }
  }
}

.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12rpx;
  flex-shrink: 0;
  
  // 平板竖屏减小间距
  @media (min-width: 768px) and (orientation: portrait) {
    gap: 6rpx;
  }
  
  // 平板横屏减小间距
  @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
    gap: 10rpx;
  }

  .start-btn,
  .stop-btn {
    flex: 1;
    height: 56rpx;
    border-radius: 16rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15);
    transition: all 0.3s ease;
    
    // 平板竖屏进一步减小高度
    @media (min-width: 768px) and (orientation: portrait) {
      height: 42rpx;
    }
    
    // 平板横屏减小高度
    @media (min-width: 768px) and (max-width: 1280px) and (orientation: landscape) {
      height: 54rpx;
    }
    
    .btn-text {
      font-size: 24rpx;
      color: #fff;
      font-weight: 700;
      letter-spacing: 2rpx;
      
      // 平板竖屏减小字体
      @media (min-width: 768px) and (orientation: portrait) {
        font-size: 22rpx;
      }
      
      // 平板横屏及大屏增大字体
      @media (min-width: 768px) and (orientation: landscape) {
        font-size: 28rpx;
      }
    }
    
    &:active {
      transform: scale(0.95);
      box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
    }
  }
  
  .start-btn {
    background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
    
    &:active {
      background: linear-gradient(135deg, #16a34a 0%, #15803d 100%);
    }
  }
  
  .stop-btn {
    background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
    
    &:active {
      background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
    }
  }
}

.bottom-controls {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(255, 255, 255, 0.98);
  padding: 20rpx;
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  border-top: 2rpx solid rgba(102, 126, 234, 0.1);
  box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(10rpx);
}

.batch-buttons {
  display: flex;
  gap: 0;
  
  :deep(.u-button) {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

</style>
