<template>
  <view class="page">
    <!-- 顶部 -->
    <view class="header">
      <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
      <view class="header-title">
        <text class="title-text">设备</text>
      </view>

      <view class="tab-bar">
        <view
          class="tab-item"
          :class="{ active: activeTab === 'all' }"
          @click="switchTab('all')"
        >
          <text class="tab-text">全部设备</text>
          <view class="tab-line" v-if="activeTab === 'all'"></view>
        </view>
        <view
          class="tab-item"
          :class="{ active: activeTab === 'online' }"
          @click="switchTab('online')"
        >
          <text class="tab-text">在线设备</text>
          <view class="tab-line" v-if="activeTab === 'online'"></view>
        </view>
        <view
          class="tab-item"
          :class="{ active: activeTab === 'offline' }"
          @click="switchTab('offline')"
        >
          <text class="tab-text">离线设备</text>
          <view class="tab-line" v-if="activeTab === 'offline'"></view>
        </view>
      </view>
    </view>

    <!-- 搜索 -->
    <view class="search-bar">
      <view class="search-box">
        <view class="search-icon">
          <view class="si-ring"></view>
          <view class="si-stem"></view>
        </view>
        <input
          class="search-input"
          v-model="keyword"
          placeholder="设备编号、名称、门店"
          placeholder-class="search-ph"
          confirm-type="search"
          @confirm="handleSearch"
        />
      </view>
      <view class="search-btn" @click="handleSearch">
        <text class="search-btn-text">搜索</text>
      </view>
    </view>

    <!-- 统计操作栏 -->
    <view class="toolbar">
      <text class="tb-count">共 {{ totalCount }} 条</text>
      <view class="tb-refresh" @click="refreshNetwork">
        <text class="tb-refresh-text">刷新网络</text>
      </view>
      <view class="tb-filter" @click="showFilter">
        <text class="tb-filter-text">筛选</text>
        <view class="tb-filter-arrow"></view>
      </view>
    </view>

    <!-- 列表 -->
    <scroll-view
      class="list-scroll"
      scroll-y
      @scrolltolower="loadMore"
      refresher-enabled
      :refresher-triggered="refreshing"
      @refresherrefresh="onRefresh"
    >
      <view class="card-set">
        <view
          class="card"
          v-for="device in deviceList"
          :key="device.id"
          @click="goDetail(device.id)"
        >
          <!-- 头部：状态 + 信息 -->
          <view class="card-head">
            <view class="status-chip" :class="statusClass(device.status)">
              <view class="wifi-icon" v-if="device.status === 1">
                <view class="wi wi-1"></view>
                <view class="wi wi-2"></view>
                <view class="wi wi-3"></view>
                <view class="wi-dot"></view>
              </view>
              <view class="wifi-icon off" v-else>
                <view class="wi wi-1"></view>
                <view class="wi wi-2"></view>
                <view class="wi wi-3"></view>
                <view class="wi-dot"></view>
                <view class="wi-cut"></view>
              </view>
              <text class="status-label">{{ statusText(device.status) }}</text>
            </view>

            <view class="card-info">
              <text class="info-name">{{ device.name }}</text>
              <view class="info-meta">
                <text class="meta-id">{{ device.deviceId }}</text>
                <text class="meta-sep" v-if="device.shopName">·</text>
                <text class="meta-shop" v-if="device.shopName">{{ device.shopName }}</text>
              </view>
            </view>
          </view>

          <!-- 操作入口 -->
          <view class="card-foot">
            <view class="foot-item" @click.stop="goProductConfig(device.deviceId)">
              <view class="foot-icon">
                <view class="fi-box">
                  <view class="fi-box-top"></view>
                  <view class="fi-box-body"></view>
                </view>
              </view>
              <text class="foot-label">上架商品</text>
            </view>
            <view class="foot-item" @click.stop="goRestockerConfig(device)">
              <view class="foot-icon">
                <view class="fi-person">
                  <view class="fi-head"></view>
                  <view class="fi-torso"></view>
                </view>
              </view>
              <text class="foot-label">配置补货员</text>
            </view>
            <view class="foot-arrow">
              <view class="fa-inner"></view>
            </view>
          </view>
        </view>
      </view>

      <!-- 加载更多 -->
      <view class="load-tip" v-if="loading">
        <view class="dot-row">
          <view class="pulse-dot"></view>
          <view class="pulse-dot"></view>
          <view class="pulse-dot"></view>
        </view>
      </view>

      <!-- 没有更多 -->
      <view class="end-tip" v-if="!hasMore && deviceList.length > 0">
        <view class="end-line"></view>
        <text class="end-text">没有更多了</text>
        <view class="end-line"></view>
      </view>

      <!-- 空状态 -->
      <view class="empty" v-if="!loading && deviceList.length === 0">
        <view class="empty-icon">
          <view class="empty-wifi">
            <view class="ew-arc"></view>
            <view class="ew-dot"></view>
          </view>
        </view>
        <text class="empty-title">暂无设备数据</text>
        <text class="empty-desc">下拉刷新或检查网络后重试</text>
      </view>
    </scroll-view>

    <CustomTabBar />
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import CustomTabBar from '@/components/CustomTabBar.vue';
import { getDeviceList } from '@/api/device';
import { DeviceStatusText } from '@/utils/constants';

type TabType = 'all' | 'online' | 'offline';

const deviceList = ref<any[]>([]);
const loading = ref(false);
const hasMore = ref(true);
const page = ref(1);
const pageSize = 10;
const keyword = ref('');
const activeTab = ref<TabType>('all');
const refreshing = ref(false);
const totalCount = ref(0);

const statusBarHeight = ref(44);

const statusFilter = computed(() => {
  if (activeTab.value === 'online') return 1;
  if (activeTab.value === 'offline') return 0;
  return undefined;
});

const statusText = (status: number) => DeviceStatusText[status] || '未知';

const statusClass = (status: number) => {
  if (status === 1) return 'on';
  if (status === 0) return 'off';
  if (status === 2) return 'mt';
  return 'off';
};

const loadDevices = async () => {
  if (loading.value) return;
  loading.value = true;
  try {
    const params: any = {
      page: page.value,
      pageSize,
      keyword: keyword.value || undefined
    };
    if (statusFilter.value !== undefined) {
      params.status = statusFilter.value;
    }

    const res = await getDeviceList(params);

    if (page.value === 1) {
      deviceList.value = res.list || [];
    } else {
      deviceList.value = [...deviceList.value, ...(res.list || [])];
    }

    totalCount.value = res.total || 0;
    hasMore.value = deviceList.value.length < (res.total || 0);
  } catch (error) {
    // ignore
  } finally {
    loading.value = false;
    refreshing.value = false;
  }
};

const loadMore = () => {
  if (loading.value || !hasMore.value) return;
  page.value++;
  loadDevices();
};

const onRefresh = () => {
  refreshing.value = true;
  page.value = 1;
  hasMore.value = true;
  loadDevices();
};

const handleSearch = () => {
  page.value = 1;
  hasMore.value = true;
  loadDevices();
};

const switchTab = (tab: TabType) => {
  if (activeTab.value === tab) return;
  activeTab.value = tab;
  page.value = 1;
  hasMore.value = true;
  deviceList.value = [];
  loadDevices();
};

const refreshNetwork = () => {
  uni.showLoading({ title: '刷新中...' });
  page.value = 1;
  hasMore.value = true;
  loadDevices().then(() => {
    uni.hideLoading();
    uni.showToast({ title: '刷新成功', icon: 'success' });
  }).catch(() => {
    uni.hideLoading();
  });
};

const showFilter = () => {
  uni.showActionSheet({
    itemList: ['全部状态', '在线', '离线', '维护中', '故障'],
    success: (res) => {
      const map = ['all', 'online', 'offline', 'maintenance', 'error'];
      const tab = map[res.tapIndex];
      if (tab === 'maintenance' || tab === 'error') {
        activeTab.value = 'all';
        page.value = 1;
        loadDevices();
      } else {
        switchTab(tab as TabType);
      }
    }
  });
};

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

const goProductConfig = (deviceId: string) => {
  uni.navigateTo({ url: `/pages/products/list?deviceId=${deviceId}` });
};

const goRestockerConfig = (device: any) => {
  const name = encodeURIComponent(device.name || '');
  uni.navigateTo({ url: `/pages/device/replenisher-config?deviceId=${device.deviceId}&deviceName=${name}` });
};

onMounted(() => {
  const systemInfo = uni.getSystemInfoSync();
  statusBarHeight.value = systemInfo.statusBarHeight || 44;
  loadDevices();
});
</script>

<style lang="scss" scoped>
// ====== Page ======
.page {
  height: 100vh;
  background: $bg-color-page;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

// ====== Header ======
.header {
  background: $primary-color;
  padding-bottom: 20rpx;
  flex-shrink: 0;
}

.status-bar {
  width: 100%;
}

.header-title {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 88rpx;

  .title-text {
    font-size: 36rpx;
    font-weight: 600;
    color: $text-color-primary;
  }
}

// ====== Tab bar ======
.tab-bar {
  display: flex;
  align-items: center;
  justify-content: space-around;
  margin-top: 8rpx;
  padding: 0 48rpx;
}

.tab-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16rpx 20rpx;
  position: relative;

  .tab-text {
    font-size: 28rpx;
    color: $text-color-secondary;
    font-weight: 500;
    transition: color 0.15s ease;
  }

  &.active .tab-text {
    color: $text-color-primary;
    font-weight: 600;
  }

  .tab-line {
    position: absolute;
    bottom: 0;
    width: 40rpx;
    height: 5rpx;
    background: $text-color-primary;
    border-radius: 3rpx;
  }
}

// ====== Search bar ======
.search-bar {
  display: flex;
  align-items: center;
  gap: 16rpx;
  padding: 20rpx 24rpx;
  background: $bg-color-card;
  flex-shrink: 0;
}

.search-box {
  flex: 1;
  display: flex;
  align-items: center;
  background: $bg-color-page;
  border-radius: 40rpx;
  padding: 14rpx 24rpx;
  height: 68rpx;
}

.search-icon {
  position: relative;
  width: 30rpx;
  height: 30rpx;
  margin-right: 14rpx;
  flex-shrink: 0;

  .si-ring {
    width: 22rpx;
    height: 22rpx;
    border: 3rpx solid $text-color-muted;
    border-radius: 50%;
    position: absolute;
    top: 0;
    left: 0;
  }
  .si-stem {
    width: 9rpx;
    height: 3rpx;
    background: $text-color-muted;
    border-radius: 2rpx;
    position: absolute;
    bottom: 3rpx;
    right: 2rpx;
    transform: rotate(45deg);
  }
}

.search-input {
  flex: 1;
  font-size: 28rpx;
  color: $text-color-primary;
}

.search-ph {
  color: $text-color-muted;
  font-size: 26rpx;
}

.search-btn {
  background: $primary-color;
  border-radius: 36rpx;
  padding: 14rpx 32rpx;
  flex-shrink: 0;
  transition: opacity 0.15s ease;

  &:active { opacity: 0.8; }

  .search-btn-text {
    font-size: 28rpx;
    color: $text-color-primary;
    font-weight: 500;
  }
}

// ====== Toolbar ======
.toolbar {
  display: flex;
  align-items: center;
  padding: 18rpx 24rpx;
  background: $bg-color-card;
  border-bottom: 1rpx solid $border-color-light;
  flex-shrink: 0;
  gap: 20rpx;
}

.tb-count {
  font-size: 24rpx;
  color: $text-color-muted;
  flex-shrink: 0;
}

.tb-refresh {
  flex: 1;
  display: flex;
  justify-content: center;
  transition: opacity 0.15s ease;

  &:active { opacity: 0.6; }

  .tb-refresh-text {
    font-size: 24rpx;
    color: $info-color;
    font-weight: 500;
  }
}

.tb-filter {
  display: flex;
  align-items: center;
  gap: 6rpx;
  flex-shrink: 0;
  transition: opacity 0.15s ease;

  &:active { opacity: 0.6; }

  .tb-filter-text {
    font-size: 24rpx;
    color: $text-color-secondary;
    font-weight: 500;
  }

  .tb-filter-arrow {
    width: 0;
    height: 0;
    border-left: 7rpx solid transparent;
    border-right: 7rpx solid transparent;
    border-top: 9rpx solid $text-color-secondary;
  }
}

// ====== List ======
.list-scroll {
  flex: 1;
  height: 0;
}

.card-set {
  padding: 20rpx 24rpx;
  display: flex;
  flex-direction: column;
  gap: 18rpx;
}

// ====== Card ======
.card {
  background: $bg-color-card;
  border-radius: 20rpx;
  padding: 28rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
  transition: opacity 0.15s ease;

  &:active { opacity: 0.7; }
}

.card-head {
  display: flex;
  align-items: flex-start;
  gap: 18rpx;
}

// Status chip
.status-chip {
  display: flex;
  align-items: center;
  gap: 8rpx;
  padding: 8rpx 16rpx;
  border-radius: 10rpx;
  flex-shrink: 0;
  margin-top: 2rpx;

  &.on { background: $success-color-bg; }
  &.off { background: $bg-color-page; }
  &.mt { background: $accent-color-bg; }

  .status-label {
    font-size: 22rpx;
    font-weight: 500;
  }

  &.on .status-label { color: $success-color; }
  &.off .status-label { color: $text-color-muted; }
  &.mt .status-label { color: $warning-color; }
}

// WiFi icon
.wifi-icon {
  position: relative;
  width: 26rpx;
  height: 20rpx;
  display: flex;
  align-items: flex-end;
  justify-content: center;

  .wi {
    position: absolute;
    border-radius: 50%;
    border-style: solid;
    border-bottom-color: transparent;
    border-left-color: transparent;
    border-right-color: transparent;
  }
  .wi-1 { width: 22rpx; height: 11rpx; border-width: 3rpx; bottom: 3rpx; }
  .wi-2 { width: 16rpx; height: 8rpx; border-width: 3rpx; bottom: 3rpx; }
  .wi-3 { width: 10rpx; height: 5rpx; border-width: 3rpx; bottom: 3rpx; }
  .wi-dot {
    width: 5rpx; height: 5rpx; border-radius: 50%; position: absolute; bottom: 0;
  }

  &:not(.off) {
    .wi { border-color: $success-color; }
    .wi-dot { background: $success-color; }
  }
  &.off {
    .wi { border-color: $text-color-placeholder; }
    .wi-dot { background: $text-color-placeholder; }
    .wi-cut {
      position: absolute;
      width: 2rpx;
      height: 24rpx;
      background: $error-color;
      transform: rotate(45deg);
      top: -2rpx;
      left: 50%;
      margin-left: -1rpx;
      border-radius: 1rpx;
    }
  }
}

// Card info
.card-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.info-name {
  font-size: 30rpx;
  color: $text-color-primary;
  font-weight: 600;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.info-meta {
  display: flex;
  align-items: center;
  gap: 8rpx;
  flex-wrap: wrap;
}

.meta-id {
  font-size: 24rpx;
  color: $text-color-secondary;
  font-weight: 500;
  font-family: monospace;
}

.meta-sep {
  font-size: 22rpx;
  color: $border-color;
}

.meta-shop {
  font-size: 24rpx;
  color: $text-color-muted;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 240rpx;
}

// Card footer (actions)
.card-foot {
  display: flex;
  align-items: center;
  padding-top: 20rpx;
  margin-top: 20rpx;
  border-top: 1rpx solid $border-color-light;
  gap: 36rpx;
}

.foot-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: opacity 0.15s ease;

  &:active { opacity: 0.6; }
}

.foot-icon {
  width: 56rpx;
  height: 56rpx;
  border-radius: 50%;
  background: $accent-color-bg;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 8rpx;
}

.foot-label {
  font-size: 22rpx;
  color: $text-color-secondary;
  font-weight: 500;
}

// Product icon (box)
.fi-box {
  position: relative;
  width: 28rpx;
  height: 28rpx;

  .fi-box-top {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 20rpx;
    height: 6rpx;
    background: $accent-color;
    border-radius: 3rpx 3rpx 0 0;
  }
  .fi-box-body {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 28rpx;
    height: 18rpx;
    background: $accent-color;
    border-radius: 4rpx;
    &::after {
      content: '';
      position: absolute;
      top: 6rpx;
      left: 50%;
      transform: translateX(-50%);
      width: 14rpx;
      height: 2rpx;
      background: $accent-color-bg;
      border-radius: 1rpx;
    }
  }
}

// Person icon
.fi-person {
  position: relative;
  width: 24rpx;
  height: 28rpx;

  .fi-head {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 12rpx;
    height: 12rpx;
    background: $accent-color;
    border-radius: 50%;
  }
  .fi-torso {
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 22rpx;
    height: 12rpx;
    background: $accent-color;
    border-radius: 11rpx 11rpx 2rpx 2rpx;
  }
}

// Arrow
.foot-arrow {
  margin-left: auto;
  width: 36rpx;
  height: 36rpx;
  display: flex;
  align-items: center;
  justify-content: center;

  .fa-inner {
    width: 14rpx;
    height: 14rpx;
    border-top: 2rpx solid $text-color-placeholder;
    border-right: 2rpx solid $text-color-placeholder;
    transform: rotate(45deg);
  }
}

// ====== Load more ======
.load-tip {
  display: flex;
  justify-content: center;
  padding: 36rpx 0 20rpx;
}

.dot-row {
  display: flex;
  gap: 8rpx;
}

.pulse-dot {
  width: 9rpx;
  height: 9rpx;
  background: $text-color-placeholder;
  border-radius: 50%;
  animation: pulse 1.2s ease-in-out infinite;

  &:nth-child(2) { animation-delay: 0.2s; }
  &:nth-child(3) { animation-delay: 0.4s; }
}

@keyframes pulse {
  0%, 80%, 100% { transform: scale(0.5); opacity: 0.4; }
  40% { transform: scale(1); opacity: 1; }
}

// ====== End ======
.end-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16rpx;
  padding: 36rpx 0 20rpx;
}

.end-line {
  width: 44rpx;
  height: 1rpx;
  background: $border-color;
}

.end-text {
  font-size: 24rpx;
  color: $text-color-muted;
}

// ====== Empty ======
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 100rpx 0 60rpx;
  gap: 20rpx;
}

.empty-icon {
  width: 120rpx;
  height: 120rpx;
  border-radius: 50%;
  background: $bg-color-secondary;
  display: flex;
  align-items: center;
  justify-content: center;
}

.empty-wifi {
  position: relative;
  width: 54rpx;
  height: 44rpx;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.ew-arc {
  position: absolute;
  width: 50rpx;
  height: 25rpx;
  border-radius: 50%;
  border: 4rpx solid $text-color-placeholder;
  border-bottom-color: transparent;
  border-left-color: transparent;
  border-right-color: transparent;
  bottom: 8rpx;
}

.ew-dot {
  width: 10rpx;
  height: 10rpx;
  border-radius: 50%;
  background: $text-color-placeholder;
}

.empty-title {
  font-size: 28rpx;
  color: $text-color-secondary;
  font-weight: 500;
}

.empty-desc {
  font-size: 24rpx;
  color: $text-color-muted;
}
</style>
