<template>
  <div class="page-container">
    <n-card>
      <div class="table-toolbar">
        <n-space align="center">
          <n-button type="primary" :loading="loading" @click="loadBoard">
            <template #icon><n-icon><RefreshOutline /></n-icon></template>
            刷新
          </n-button>
          <n-switch v-model:value="autoRefresh" @update:value="onAutoRefreshChange">
            <template #checked>自动刷新 15s</template>
            <template #unchecked>手动刷新</template>
          </n-switch>
        </n-space>
        <n-button quaternary @click="router.push('/biz/device')">
          返回设备管理
        </n-button>
      </div>

      <div class="stat-row">
        <div class="stat-item">
          <span class="stat-num">{{ list.length }}</span>
          <span class="stat-label">设备总数</span>
        </div>
        <div class="stat-item running">
          <span class="stat-dot running" />
          <span class="stat-num">{{ countByStatus(1) }}</span>
          <span class="stat-label">加工中</span>
        </div>
        <div class="stat-item idle">
          <span class="stat-dot idle" />
          <span class="stat-num">{{ countByStatus(0) }}</span>
          <span class="stat-label">闲置</span>
        </div>
        <div class="stat-item alarm">
          <span class="stat-dot alarm" />
          <span class="stat-num">{{ countByStatus(2) }}</span>
          <span class="stat-label">警报</span>
        </div>
        <div class="stat-item offline">
          <span class="stat-dot offline" />
          <span class="stat-num">{{ offlineCount }}</span>
          <span class="stat-label">离线</span>
        </div>
      </div>

      <n-spin :show="loading">
        <n-empty v-if="!loading && list.length === 0" description="暂无设备状态数据" />
        <div v-else class="card-grid">
          <div
            v-for="item in list"
            :key="item.synEquipId"
            class="device-card"
            :class="cardClass(item)"
          >
            <div class="card-head">
              <div class="head-left">
                <div class="status-lamp" :class="lampClass(item)" />
                <div class="name-block">
                  <div class="name">{{ item.displayName }}</div>
                  <div class="meta">
                    <span v-if="item.deviceCode">{{ item.deviceCode }}</span>
                    <span v-if="item.deviceCode && item.sectionName"> · </span>
                    <span v-if="item.sectionName">{{ item.sectionName }}</span>
                    <span v-if="!item.deviceCode && !item.sectionName">设备监控</span>
                  </div>
                </div>
              </div>
              <n-tag :type="statusTagType(item)" size="small">
                {{ item.cncStatusText || '未知' }}
              </n-tag>
            </div>

            <div class="metric-grid">
              <div class="metric">
                <div class="metric-label">当前程序</div>
                <div class="metric-value program">{{ item.mainProgram || '—' }}</div>
              </div>
              <div class="metric">
                <div class="metric-label">累计产量</div>
                <div class="metric-value">{{ item.partCount ?? '—' }}</div>
              </div>
              <div class="metric">
                <div class="metric-label">通讯状态</div>
                <div class="metric-value">
                  <span class="link-status" :class="item.connected === 1 ? 'on' : 'off'">
                    {{ item.connected === 1 ? '在线' : item.connected === 0 ? '离线' : '—' }}
                  </span>
                </div>
              </div>
              <div class="metric">
                <div class="metric-label">运行状态</div>
                <div class="metric-value">{{ item.cncStatusText || '—' }}</div>
              </div>
            </div>

            <div v-if="item.alarmCount" class="alarm-box">
              <n-icon size="14"><WarningOutline /></n-icon>
              <span>{{ (item.alarmMessages || []).slice(0, 2).join('；') || `当前警报 ${item.alarmCount} 条` }}</span>
            </div>
          </div>
        </div>
      </n-spin>
    </n-card>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
import { RefreshOutline, WarningOutline } from '@vicons/ionicons5'
import { deviceApi, type DeviceRealtimeVO } from '@/api/device'

const router = useRouter()
const message = useMessage()

const list = ref<DeviceRealtimeVO[]>([])
const loading = ref(false)
const autoRefresh = ref(true)
let timer: ReturnType<typeof setInterval> | null = null

const offlineCount = computed(() => list.value.filter((i) => i.connected === 0).length)

function countByStatus(status: number) {
  return list.value.filter((i) => i.connected !== 0 && i.cncStatus === status).length
}

function cardClass(item: DeviceRealtimeVO) {
  if (item.connected === 0) return 'is-offline'
  if (item.cncStatus === 2) return 'is-alarm'
  if (item.cncStatus === 1) return 'is-running'
  if (item.cncStatus === 0) return 'is-idle'
  return ''
}

function lampClass(item: DeviceRealtimeVO) {
  if (item.connected === 0) return 'offline'
  if (item.cncStatus === 2) return 'alarm'
  if (item.cncStatus === 1) return 'running'
  if (item.cncStatus === 0) return 'idle'
  return 'unknown'
}

function statusTagType(item: DeviceRealtimeVO) {
  if (item.connected === 0) return 'default'
  if (item.cncStatus === 2) return 'error'
  if (item.cncStatus === 1) return 'success'
  if (item.cncStatus === 0) return 'info'
  return 'warning'
}

async function loadBoard() {
  loading.value = true
  try {
    list.value = ((await deviceApi.realtimeBoard()) || []).filter((i) => i.bound)
  } catch (e: any) {
    message.error(e?.message || '加载设备状态失败')
  } finally {
    loading.value = false
  }
}

function clearTimer() {
  if (timer) {
    clearInterval(timer)
    timer = null
  }
}

function onAutoRefreshChange(val: boolean) {
  clearTimer()
  if (val) {
    timer = setInterval(loadBoard, 15000)
  }
}

onMounted(() => {
  loadBoard()
  onAutoRefreshChange(true)
})

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

<style scoped>
.table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 12px;
}

.stat-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.stat-item {
  min-width: 100px;
  padding: 12px 16px;
  border-radius: 6px;
  background: #f5f7fa;
  border: 1px solid #e5e7eb;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: relative;
}

.stat-item.running { background: #e8f8ef; border-color: #b7ebc6; }
.stat-item.idle { background: #eef5ff; border-color: #b3d4ff; }
.stat-item.alarm { background: #ffecec; border-color: #ffc2c8; }
.stat-item.offline { background: #f5f5f5; border-color: #e5e7eb; }

.stat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  position: absolute;
  top: 12px;
  right: 12px;
}
.stat-dot.running { background: #18a058; box-shadow: 0 0 0 3px rgba(24, 160, 88, 0.2); }
.stat-dot.idle { background: #2080f0; }
.stat-dot.alarm { background: #d03050; }
.stat-dot.offline { background: #9aa0a6; }

.stat-num {
  font-size: 22px;
  font-weight: 600;
  color: #1f2329;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.stat-label {
  font-size: 13px;
  color: #646a73;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

.device-card {
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  padding: 14px 16px;
  background: #ffffff;
  border-left: 3px solid #d0d3d9;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.device-card:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.device-card.is-running { border-left-color: #18a058; }
.device-card.is-idle { border-left-color: #2080f0; }
.device-card.is-alarm { border-left-color: #d03050; }
.device-card.is-offline {
  border-left-color: #c2c2c2;
  opacity: 0.92;
}

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 14px;
}

.head-left {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}

.status-lamp {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-top: 5px;
  flex-shrink: 0;
  background: #c2c2c2;
}
.status-lamp.running {
  background: #18a058;
  box-shadow: 0 0 0 3px rgba(24, 160, 88, 0.22);
  animation: pulse 1.6s ease-in-out infinite;
}
.status-lamp.idle { background: #2080f0; }
.status-lamp.alarm {
  background: #d03050;
  box-shadow: 0 0 0 3px rgba(208, 48, 80, 0.22);
  animation: pulse 1s ease-in-out infinite;
}
.status-lamp.offline { background: #9aa0a6; }

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

.name {
  font-size: 15px;
  font-weight: 600;
  color: #1f2329;
  line-height: 1.35;
}

.meta {
  margin-top: 2px;
  font-size: 12px;
  color: #8a8f98;
}

.metric-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 12px;
}

.metric {
  min-width: 0;
  padding: 8px 10px;
  border-radius: 4px;
  background: #f7f8fa;
}

.metric-label {
  font-size: 12px;
  color: #8a8f98;
  margin-bottom: 4px;
}

.metric-value {
  font-size: 15px;
  font-weight: 600;
  color: #1f2329;
  word-break: break-all;
  line-height: 1.35;
}

.metric-value.program {
  font-weight: 500;
  font-size: 13px;
}

.link-status.on { color: #18a058; }
.link-status.off { color: #8a8f98; }

.alarm-box {
  margin-top: 12px;
  padding: 8px 10px;
  border-radius: 4px;
  background: #fff1f0;
  color: #d03050;
  font-size: 12px;
  line-height: 1.4;
  display: flex;
  align-items: flex-start;
  gap: 6px;
}
</style>

<style>
/* 暗色主题：自定义区域不吃 Naive 组件变量，单独提亮 */
body.dark-theme .stat-item {
  background: #27272a !important;
  border-color: #3f3f46 !important;
}
body.dark-theme .stat-item.running {
  background: rgba(24, 160, 88, 0.18) !important;
  border-color: rgba(52, 211, 153, 0.4) !important;
}
body.dark-theme .stat-item.idle {
  background: rgba(32, 128, 240, 0.18) !important;
  border-color: rgba(96, 165, 250, 0.4) !important;
}
body.dark-theme .stat-item.alarm {
  background: rgba(208, 48, 80, 0.18) !important;
  border-color: rgba(251, 113, 133, 0.4) !important;
}
body.dark-theme .stat-item.offline {
  background: #27272a !important;
  border-color: #3f3f46 !important;
}
body.dark-theme .stat-num {
  color: #f4f4f5 !important;
}
body.dark-theme .stat-label {
  color: #a1a1aa !important;
}
body.dark-theme .device-card {
  background: #18181c !important;
  border-color: #3f3f46 !important;
}
body.dark-theme .device-card.is-offline {
  opacity: 1;
}
body.dark-theme .name {
  color: #f4f4f5 !important;
}
body.dark-theme .meta {
  color: #a1a1aa !important;
}
body.dark-theme .metric {
  background: #27272a !important;
}
body.dark-theme .metric-label {
  color: #a1a1aa !important;
}
body.dark-theme .metric-value {
  color: #f4f4f5 !important;
}
body.dark-theme .link-status.on {
  color: #34d399 !important;
}
body.dark-theme .link-status.off {
  color: #a1a1aa !important;
}
body.dark-theme .alarm-box {
  background: rgba(208, 48, 80, 0.2) !important;
  color: #fb7185 !important;
}
</style>
