<template>
  <view class="device-list-container">
    <!-- 站点选择 -->
    <picker
      v-if="stationList.length > 0"
      mode="selector"
      :range="stationList"
      range-key="stationName"
      :value="selectedStationIndex"
      @change="onStationChange"
    >
      <view class="station-picker">
        <view class="station-picker-row">
          <AppIcon name="building" :size="18" color="#C6171E" />
          <text class="station-picker-name">{{ currentStation?.stationName || '选择站点' }}</text>
          <AppIcon name="chevron-down" :size="14" color="#999999" />
        </view>
        <text class="station-picker-count" v-if="deviceList.length > 0">共 {{ totalDevices }} 台设备</text>
      </view>
    </picker>

    <!-- 搜索栏 -->
    <view class="search-bar">
      <view class="search-input-wrap">
        <AppIcon name="search" size="16" color="#999999" />
        <input
          type="text"
          placeholder="搜索设备名称或编号"
          v-model="searchKeyword"
          @confirm="handleSearch"
        />
        <view v-if="searchKeyword" class="search-clear" @click="searchKeyword = ''; handleSearch()">
          <AppIcon name="x" size="14" color="#B0B0B0" />
        </view>
      </view>
    </view>

    <!-- 设备列表 -->
    <view class="device-list">
      <view
        v-for="device in deviceList"
        :key="device.id || device.deviceId"
        class="device-item"
        @click="viewDeviceDetail(getDeviceId(device))"
      >
        <view class="device-header">
          <view class="device-info">
            <text class="device-name">{{ device.name }}</text>
            <view class="device-meta">
              <view class="device-id-row">
                <text class="device-id">ID: {{ device.shortId }}</text>
                <AppIcon v-if="device.shortId" name="copy" :size="24" color="#C6171E" class="copy-icon" @click.stop="copyText(device.shortId)" />
              </view>
              <view class="device-status" :style="getDeviceStatusStyle(getDeviceStatusValue(device))">
                <text class="status-dot"></text>
                <text>{{ getDeviceStatusText(getDeviceStatusValue(device)) }}</text>
              </view>
              <view class="device-busy-tag" :class="getDeviceBusyStatusClass(device)">
                <text>{{ getDeviceBusyStatus(device) }}</text>
              </view>
            </view>
          </view>
          <button
            class="config-btn"
            @click.stop="toggleConfigDropdown(getDeviceId(device))"
          >
            设备配置
          </button>
        </view>

        <view class="device-body">
          <view class="device-row">
            <text class="row-label">所属站点</text>
            <text class="row-value">{{ device.stationName || '未分配站点' }}</text>
          </view>
          <view class="device-row">
            <text class="row-label">价格配置</text>
            <text class="row-value">{{ device.deviceConfigName || '未绑定配置' }}</text>
          </view>
        </view>

        <view class="device-footer" v-if="isDeviceOnline(getDeviceStatusValue(device))">
          <button class="stop-btn" @click.stop="handleStopDevice(device)">停止设备</button>
        </view>

        <view v-if="showConfigDropdown === getDeviceId(device)" class="config-dropdown">
          <view class="dropdown-header">
            <text class="dropdown-title">选择配置</text>
            <view class="dropdown-close" @click.stop="closeConfigDropdown">
              <AppIcon name="x" size="16" color="#999999" />
            </view>
          </view>
          <view class="dropdown-content">
            <view
              v-for="config in configList"
              :key="config.id"
              class="config-option"
              @click.stop="selectConfig(getDeviceId(device), config.id, config.name)"
            >
              <text class="config-option-name">{{ config.name }}</text>
              <text class="config-option-desc">{{ config.remark || '无描述' }}</text>
            </view>
            <view v-if="configList.length === 0" class="no-config">
              <text>暂无配置，请先添加</text>
            </view>
          </view>
        </view>
      </view>
    </view>

    <view class="load-more" v-if="deviceList.length > 0">
      <text v-if="loadMoreStatus === 'loading'">正在加载...</text>
      <text v-else-if="loadMoreStatus === 'noMore'">— 没有更多了 —</text>
      <text v-else>上拉加载更多</text>
    </view>

    <view class="empty-state" v-if="deviceList.length === 0 && !loading">
      <AppIcon name="smartphone" size="48" color="#BFBFBF" />
      <text class="empty-text">暂无设备数据</text>
      <button class="empty-refresh-btn" @click="loadDeviceList">刷新</button>
    </view>

    <view class="loading-state" v-if="loading && deviceList.length === 0">
      <view class="loading-spinner"></view>
      <text class="loading-text">加载中...</text>
    </view>

    <CustomTabBar :selected="2" />
  </view>
</template>

<script setup>
import CustomTabBar from '../../components/CustomTabBar.vue'
import { ref, onMounted, computed } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
import { getDeviceList, stopDevice, getDeviceConfigList, batchModifyDeviceConfig } from '../../api/device.js'
import { getStationList } from '../../api/station.js'
import { showToast, storage, fmtDictName, getDictColor, copyText } from '../../utils/index.js'
import dictUtil, { loadDicts } from '../../utils/dict.js'

const deviceList = ref([])
const loading = ref(true)
const page = ref(1)
const pageSize = ref(10)
const hasMore = ref(true)
const loadMoreStatus = ref('more')
const searchKeyword = ref('')

const stationList = ref([])
const currentStation = ref(null)
const selectedStationIndex = ref(0)
const totalDevices = ref(0)

const configList = ref([])
const showConfigDropdown = ref(null)
const loadingConfig = ref(false)

onMounted(async () => {
  await Promise.all([loadDicts(), loadStationList()])
})

const loadStationList = async () => {
  try {
    const res = await getStationList({ pageNum: 1, pageSize: 1024 })
    if (res && res.code === 200 && res.data && res.data.list) {
      stationList.value = res.data.list
      if (stationList.value.length > 0) {
        currentStation.value = stationList.value[0]
        selectedStationIndex.value = 0
        storage.set('currentStationId', currentStation.value.stationId)
        loadDeviceList()
      }
    }
  } catch (e) {
    console.error('加载站点列表失败:', e)
  }
}

const onStationChange = async (e) => {
  const index = e.detail.value
  selectedStationIndex.value = index
  currentStation.value = stationList.value[index]
  storage.set('currentStationId', currentStation.value.stationId)
  loadDeviceList()
}

const loadDeviceList = async (isLoadMore = false) => {
  if (!isLoadMore) {
    page.value = 1
    deviceList.value = []
    loading.value = true
  }

  try {
    const params = {
      page: page.value,
      pageSize: pageSize.value,
      keyword: searchKeyword.value || '',
      stationId: currentStation.value?.stationId || ''
    }

    const res = await getDeviceList(params)

    if (res && res.code === 200) {
      const data = res.data
      const records = data.records || data.list || data
      const totalPages = data.pages || data.totalPages || 1

      totalDevices.value = data.total || (Array.isArray(records) ? records.length : 0)

      if (isLoadMore) {
        deviceList.value = [...deviceList.value, ...records]
      } else {
        deviceList.value = Array.isArray(records) ? records : []
      }

      hasMore.value = page.value < totalPages
      loadMoreStatus.value = hasMore.value ? 'more' : 'noMore'

      if (!isLoadMore) page.value++
    }
  } catch (error) {
    showToast('获取设备列表失败')
  } finally {
    loading.value = false
  }
}

const loadMore = () => {
  if (hasMore.value && !loading.value && loadMoreStatus.value !== 'loading') {
    loadMoreStatus.value = 'loading'
    page.value++
    loadDeviceList(true)
  }
}

onReachBottom(() => loadMore())

const handleSearch = () => loadDeviceList()

const viewDeviceDetail = (deviceId) => {
  uni.navigateTo({ url: `/pages/device/detail?id=${deviceId}` })
}

const handleStopDevice = (device) => {
  uni.showModal({
    title: '停止设备',
    content: `确定要停止设备「${device.name || device.shortId}」吗？`,
    success: async (res) => {
      if (res.confirm) {
        try {
          await stopDevice(device.shortId)
          showToast('设备已停止', 'success')
          loadDeviceList()
        } catch (error) {
          showToast('停止设备失败')
        }
      }
    }
  })
}

const loadConfigList = async () => {
  if (loadingConfig.value) return
  loadingConfig.value = true
  try {
    const res = await getDeviceConfigList({ page: 1, pageSize: 1000 })
    if (res && res.code === 200) {
      const data = res.data
      configList.value = data.list || data.records || (Array.isArray(data) ? data : [])
    }
  } catch (error) {
    showToast('无法连接服务器')
  } finally {
    loadingConfig.value = false
  }
}

const toggleConfigDropdown = (deviceId) => {
  if (showConfigDropdown.value === deviceId) {
    closeConfigDropdown()
  } else {
    loadConfigList()
    showConfigDropdown.value = deviceId
  }
}

const closeConfigDropdown = () => {
  showConfigDropdown.value = null
}

const selectConfig = async (deviceId, configId, configName) => {
  try {
    const res = await batchModifyDeviceConfig({
      deviceIds: [deviceId],
      deviceConfigId: configId
    })
    if (res && res.code === 200) {
      showToast(`成功绑定: ${configName}`, 'success')
      closeConfigDropdown()
      setTimeout(() => loadDeviceList(), 500)
    } else {
      showToast(res.message || '绑定失败')
    }
  } catch (error) {
    showToast('网络连接失败')
  }
}

const getDeviceId = (device) => device?.id || device?.deviceId || device?.device_id || device?.shortId || null

const getDeviceStatusValue = (device) => device?.status ?? device?.state ?? device?.stateCode ?? device?.deviceStatus ?? null

const getDeviceStatusText = (status) => fmtDictName('WashDevice.status', status)

const getDeviceBusyStatus = (device) => {
  const status = getDeviceStatusValue(device)
  const onlineValue = dictUtil.getDictValue('WashDevice.status', '在线')
  if (status != onlineValue) return ''
  const hasCurrentOrder = device.isBusy || device.currentOrder || device.workingStatus === 'BUSY'
  return hasCurrentOrder || (device.todayOrders > 0)
    ? dictUtil.getDictLabel('deviceBusyStatus', '1')
    : dictUtil.getDictLabel('deviceBusyStatus', '0')
}

const getDeviceBusyStatusClass = (device) => {
  const label = getDeviceBusyStatus(device)
  if (!label) return ''
  return label !== dictUtil.getDictLabel('deviceBusyStatus', '0') ? 'busy' : 'idle'
}

const getDeviceStatusStyle = (status) => {
  const color = getDictColor('WashDevice.status', status)
  if (color) return { color, backgroundColor: `${color}1A` }
  return {}
}

const isDeviceOnline = (status) => {
  const onlineValue = dictUtil.getDictValue('WashDevice.status', '在线')
  return status == onlineValue
}
</script>

<style scoped>
.device-list-container {
  padding: 20rpx 28rpx;
  background-color: #F5F7FA;
  min-height: 100vh;
  box-sizing: border-box;
  padding-bottom: 120rpx;
}

/* ===== Station Picker ===== */
.station-picker {
  background: #FFFFFF;
  border-radius: 20rpx;
  padding: 24rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8rpx;
  margin-bottom: 20rpx;
}

.station-picker:active {
  background: #F5F7FA;
}

.station-picker-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10rpx;
}

.station-picker-name {
  font-size: 28rpx;
  font-weight: 600;
  color: #1A1A1A;
}

.station-picker-count {
  font-size: 22rpx;
  color: #999999;
}

/* ===== Search Bar ===== */
.search-bar {
  margin-bottom: 20rpx;
}

.search-input-wrap {
  display: flex;
  align-items: center;
  gap: 12rpx;
  background: #FFFFFF;
  border-radius: 16rpx;
  padding: 0 24rpx;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.search-input-wrap input {
  flex: 1;
  height: 72rpx;
  border: none;
  outline: none;
  font-size: 28rpx;
  color: #1A1A1A;
  background: transparent;
}

.search-clear {
  padding: 6rpx;
  display: flex;
  align-items: center;
}

/* ===== Device List ===== */
.device-list {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
}

.device-item {
  background: #FFFFFF;
  border-radius: 20rpx;
  padding: 24rpx;
  position: relative;
  transition: box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.device-item:active {
  transform: translateY(-2rpx);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.device-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16rpx;
  margin-bottom: 18rpx;
}

.device-info {
  flex: 1;
  min-width: 0;
}

.device-name {
  font-size: 30rpx;
  font-weight: 600;
  color: #1A1A1A;
  display: block;
  margin-bottom: 10rpx;
}

.device-meta {
  display: flex;
  align-items: center;
  gap: 12rpx;
  flex-wrap: wrap;
}

.device-id-row {
  display: flex;
  align-items: center;
  gap: 6rpx;
}
.device-id {
  font-size: 24rpx;
  color: #999999;
}
.copy-icon {
  flex-shrink: 0;
}

.device-status {
  display: flex;
  align-items: center;
  font-size: 22rpx;
  font-weight: 600;
  padding: 4rpx 16rpx;
  border-radius: 100px;
  white-space: nowrap;
}

.status-dot {
  display: inline-block;
  width: 10rpx;
  height: 10rpx;
  border-radius: 50%;
  margin-right: 6rpx;
  background-color: currentColor;
}

.device-busy-tag {
  display: flex;
  align-items: center;
  font-size: 20rpx;
  font-weight: 600;
  padding: 4rpx 14rpx;
  border-radius: 100px;
  flex-shrink: 0;
}

.device-busy-tag.busy {
  color: #F44336;
  background-color: rgba(244, 67, 54, 0.08);
}

.device-busy-tag.idle {
  color: #52C41A;
  background-color: rgba(82, 196, 26, 0.08);
}

/* ===== Device Body ===== */
.device-body {
  padding: 14rpx 0;
  border-top: 1px solid #F0F0F0;
  border-bottom: 1px solid #F0F0F0;
  margin-bottom: 16rpx;
}

.device-row {
  display: flex;
  align-items: center;
  padding: 6rpx 0;
}

.row-label {
  font-size: 24rpx;
  color: #999999;
  width: 120rpx;
  flex-shrink: 0;
}

.row-value {
  font-size: 24rpx;
  color: #1A1A1A;
  font-weight: 500;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ===== Device Footer ===== */
.device-footer {
  padding-top: 16rpx;
  border-top: 1px solid #F0F0F0;
}

.stop-btn {
  width: 100%;
  padding: 14rpx 0;
  background: #FFFFFF;
  color: #1A1A1A;
  border: 1px solid #E0E0E0;
  border-radius: 12rpx;
  font-size: 24rpx;
  font-weight: 500;
  transition: border-color 0.25s, color 0.25s;
}

.stop-btn:active {
  border-color: #C6171E;
  color: #C6171E;
}

/* ===== Config Button ===== */
.config-btn {
  padding: 8rpx 20rpx;
  background: #C6171E;
  color: #FFFFFF;
  border: none;
  border-radius: 12rpx;
  font-size: 22rpx;
  font-weight: 500;
  flex-shrink: 0;
  transition: background 0.25s, transform 0.15s;
}

.config-btn:active {
  background: #A81212;
  transform: scale(0.97);
}

/* ===== Config Dropdown ===== */
.config-dropdown {
  position: absolute;
  top: 60rpx;
  right: 0;
  width: 340rpx;
  background: #FFFFFF;
  border-radius: 16rpx;
  box-shadow: 0 10px 15px rgba(0, 0, 0, 0.08), 0 4px 6px rgba(0, 0, 0, 0.05);
  z-index: 100;
  overflow: hidden;
}

.dropdown-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18rpx 22rpx;
  background: #F5F7FA;
  border-bottom: 1px solid #F0F0F0;
}

.dropdown-title {
  font-size: 26rpx;
  font-weight: 600;
  color: #1A1A1A;
}

.dropdown-close {
  padding: 4rpx;
}

.dropdown-content {
  max-height: 360rpx;
  overflow-y: auto;
}

.config-option {
  padding: 18rpx 22rpx;
  border-bottom: 1px solid #F0F0F0;
  transition: background 0.2s;
}

.config-option:last-child {
  border-bottom: none;
}

.config-option:active {
  background: #F5F7FA;
}

.config-option-name {
  font-size: 26rpx;
  font-weight: 500;
  color: #1A1A1A;
  display: block;
  margin-bottom: 4rpx;
}

.config-option-desc {
  font-size: 22rpx;
  color: #999999;
  display: block;
}

.no-config {
  padding: 40rpx 20rpx;
  text-align: center;
  color: #999999;
  font-size: 24rpx;
}

/* ===== Load More ===== */
.load-more {
  text-align: center;
  padding: 32rpx;
  color: #666666;
  font-size: 26rpx;
  margin-top: 24rpx;
}

/* ===== Empty State ===== */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 120rpx 0;
}

.empty-text {
  font-size: 28rpx;
  color: #999999;
  margin: 24rpx 0 32rpx;
}

.empty-refresh-btn {
  padding: 16rpx 48rpx;
  background: #C6171E;
  color: #FFFFFF;
  border: none;
  border-radius: 44rpx;
  font-size: 28rpx;
  font-weight: 500;
}

/* ===== Loading ===== */
.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 120rpx 0;
}

.loading-spinner {
  width: 56rpx;
  height: 56rpx;
  border: 4rpx solid #F0F0F0;
  border-top-color: #C6171E;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loading-text {
  font-size: 26rpx;
  color: #999999;
  margin-top: 20rpx;
}
</style>
