<template>
  <view class="page">
    <NavBar title="配置补货员" :showBack="true" />

    <!-- 设备信息 -->
    <view class="header-card">
      <view class="hc-icon">
        <view class="icon-device"></view>
      </view>
      <view class="hc-info">
        <text class="hc-name">{{ deviceName || deviceId }}</text>
        <text class="hc-id">{{ deviceId }}</text>
      </view>
    </view>

    <!-- 已选统计 -->
    <view class="stats-bar" v-if="!loading">
      <text>已选 <text class="sb-num">{{ selectedIds.length }}</text> 名补货员</text>
    </view>

    <scroll-view class="page-scroll" scroll-y>
      <view class="list" v-if="!loading">
        <view
          class="item"
          v-for="r in replenisherList"
          :key="r.id"
          @click="toggleReplenisher(r.id)"
        >
          <view class="item-avatar" :class="r.status === 0 ? 'off' : ''">
            <text>{{ (r.name || '?')[0] }}</text>
          </view>
          <view class="item-info">
            <text class="item-name">{{ r.name }}</text>
            <text class="item-sub" v-if="r.phone">{{ r.phone }}</text>
          </view>
          <view class="item-check" :class="{ on: selectedIds.includes(r.id) }">
            <text v-if="selectedIds.includes(r.id)">✓</text>
          </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="empty-state" v-if="!loading && replenisherList.length === 0">
        <view class="empty-icon">
          <view class="empty-person">
            <view class="ep-head"></view>
            <view class="ep-body"></view>
          </view>
        </view>
        <text class="empty-title">暂无可用补货员</text>
        <text class="empty-desc">请先在补货员管理中新增补货员</text>
      </view>

      <view class="bottom-safe"></view>
    </scroll-view>

    <!-- 底部操作栏 -->
    <view class="bottom-bar" v-if="!loading">
      <view class="bb-info">
        <text>变更：新增 {{ toBind.length }} 名，移除 {{ toUnbind.length }} 名</text>
      </view>
      <view
        class="bb-btn"
        :class="{ disabled: (toBind.length === 0 && toUnbind.length === 0) || saving }"
        @click="handleSave"
      >
        <view class="bb-spinner" v-if="saving"></view>
        <text class="bb-btn-text" v-else>保存</text>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import NavBar from '@/components/NavBar.vue';
import {
  getReplenisherList,
  getBoundDevices,
  bindDevices,
  unbindDevice
} from '@/api/replenisher';

const deviceId = ref('');
const deviceName = ref('');
const loading = ref(true);
const saving = ref(false);
const replenisherList = ref<any[]>([]);
const selectedIds = ref<string[]>([]);
const origBoundIds = ref<string[]>([]);

const toBind = computed(() => selectedIds.value.filter(id => !origBoundIds.value.includes(id)));
const toUnbind = computed(() => origBoundIds.value.filter(id => !selectedIds.value.includes(id)));

const toggleReplenisher = (id: string) => {
  const idx = selectedIds.value.indexOf(id);
  if (idx >= 0) {
    selectedIds.value.splice(idx, 1);
  } else {
    selectedIds.value.push(id);
  }
};

const handleSave = async () => {
  if (saving.value) return;
  if (toBind.value.length === 0 && toUnbind.value.length === 0) {
    uni.showToast({ title: '未做任何变更', icon: 'none' });
    return;
  }
  saving.value = true;
  uni.showLoading({ title: '保存中...', mask: true });
  try {
    if (toBind.value.length > 0) {
      await Promise.all(toBind.value.map(id => bindDevices(id, [deviceId.value])));
    }
    if (toUnbind.value.length > 0) {
      await Promise.all(toUnbind.value.map(id => unbindDevice(id, deviceId.value)));
    }
    uni.hideLoading();
    uni.showToast({ title: '保存成功', icon: 'success' });
    setTimeout(() => {
      uni.navigateBack();
    }, 1200);
  } catch (e) {
    uni.hideLoading();
    uni.showToast({ title: '保存失败', icon: 'none' });
  } finally {
    saving.value = false;
  }
};

onMounted(async () => {
  const pages = getCurrentPages();
  const page = pages[pages.length - 1];
  const options = (page as Record<string, any>).options || {};
  deviceId.value = options.deviceId || '';
  deviceName.value = decodeURIComponent(options.deviceName || '');

  if (!deviceId.value) {
    uni.showToast({ title: '参数错误', icon: 'none' });
    return;
  }

  try {
    const res = await getReplenisherList({ page: 1, pageSize: 200, status: 1 });
    const list = res.list || [];
    replenisherList.value = list;

    const boundResults = await Promise.all(
      list.map(async (r: any) => {
        try {
          const devices = await getBoundDevices(r.id);
          return { id: r.id, bound: (devices || []).includes(deviceId.value) };
        } catch {
          return { id: r.id, bound: false };
        }
      })
    );

    origBoundIds.value = boundResults.filter(r => r.bound).map(r => r.id);
    selectedIds.value = [...origBoundIds.value];
  } catch (e) {
    uni.showToast({ title: '加载失败', icon: 'none' });
  } finally {
    loading.value = false;
  }
});
</script>

<style lang="scss" scoped>
$font-stack: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', system-ui, sans-serif;

.page {
  height: 100vh;
  width: 100vw;
  overflow-x: hidden;
  background: $bg-color-page;
  display: flex;
  flex-direction: column;
  font-family: $font-stack;
}

// ====== Header ======
.header-card {
  display: flex;
  align-items: center;
  background: $bg-color-card;
  padding: $spacing-3 $spacing-4;
  gap: $spacing-2;
  flex-shrink: 0;
  border-bottom: 1rpx solid $border-color-light;
}

.hc-icon {
  width: 72rpx;
  height: 72rpx;
  border-radius: 18rpx;
  background: $success-color-bg;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.icon-device {
  width: 36rpx;
  height: 28rpx;
  border: 3rpx solid $primary-color;
  border-radius: 6rpx;
  position: relative;
  &::after {
    content: '';
    position: absolute;
    bottom: -8rpx;
    left: 50%;
    transform: translateX(-50%);
    width: 16rpx;
    height: 8rpx;
    background: $primary-color;
    border-radius: 0 0 4rpx 4rpx;
  }
}

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

.hc-name {
  display: block;
  font-size: 30rpx;
  font-weight: 600;
  color: $text-color-primary;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hc-id {
  font-size: 24rpx;
  color: $text-color-muted;
  margin-top: 4rpx;
  display: block;
  font-family: monospace;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

// ====== Stats ======
.stats-bar {
  padding: $spacing-2 $spacing-4;
  font-size: 24rpx;
  color: $text-color-muted;
  flex-shrink: 0;

  .sb-num {
    font-weight: 600;
    color: $primary-color-dark;
  }
}

// ====== Scroll ======
.page-scroll {
  flex: 1;
  height: 0;
  padding: 0 $spacing-3;
  overflow-x: hidden;
}

.list {
  display: flex;
  flex-direction: column;
  gap: $spacing-2;
  padding-top: $spacing-2;
  width: 100%;
  box-sizing: border-box;
}

// ====== Item ======
.item {
  display: flex;
  align-items: center;
  background: $bg-color-card;
  border-radius: $radius-md;
  padding: $spacing-3 $spacing-3;
  gap: $spacing-2;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
  transition: opacity 0.15s ease;
  width: 100%;
  box-sizing: border-box;

  &:active { opacity: 0.7; }
}

.item-avatar {
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
  background: $primary-color-bg;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;

  text {
    font-size: 28rpx;
    font-weight: 700;
    color: $primary-color-dark;
  }

  &.off {
    background: $bg-color-page;
    text { color: $text-color-placeholder; }
  }
}

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

.item-name {
  display: block;
  font-size: 28rpx;
  font-weight: 500;
  color: $text-color-primary;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-sub {
  font-size: 24rpx;
  color: $text-color-muted;
  margin-top: 4rpx;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-check {
  width: 40rpx;
  height: 40rpx;
  border-radius: $radius-sm;
  border: 2rpx solid $border-color;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 24rpx;
  color: transparent;
  transition: all 0.15s ease;

  &.on {
    background: $primary-color;
    border-color: $primary-color;
    color: $text-color-primary;
  }
}

// ====== Bottom bar ======
.bottom-bar {
  display: flex;
  align-items: center;
  padding: $spacing-2 $spacing-3;
  padding-bottom: calc($spacing-2 + constant(safe-area-inset-bottom));
  padding-bottom: calc($spacing-2 + env(safe-area-inset-bottom));
  background: $bg-color-card;
  border-top: 1rpx solid $border-color-light;
  box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.05);
  gap: $spacing-2;
  flex-shrink: 0;
}

.bb-info {
  flex: 1;
  font-size: 22rpx;
  color: $text-color-muted;
}

.bb-btn {
  background: $primary-color;
  border-radius: $radius-full;
  padding: 18rpx 48rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 120rpx;
  transition: opacity 0.15s ease;

  &:active { opacity: 0.8; }

  &.disabled {
    opacity: 0.4;
    pointer-events: none;
  }
}

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

.bb-spinner {
  width: 28rpx;
  height: 28rpx;
  border: 3rpx solid rgba(30, 41, 59, 0.2);
  border-top-color: $text-color-primary;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

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

// ====== Load / Empty ======
.load-tip {
  display: flex;
  justify-content: center;
  padding: 60rpx 0;
}

.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; }
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 100rpx 0 60rpx;
  gap: $spacing-2;
}

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

.empty-person {
  position: relative;
  width: 40rpx;
  height: 48rpx;

  .ep-head {
    position: absolute; top: 0; left: 50%;
    transform: translateX(-50%);
    width: 18rpx; height: 18rpx;
    background: $text-color-placeholder;
    border-radius: 50%;
  }
  .ep-body {
    position: absolute; bottom: 0; left: 50%;
    transform: translateX(-50%);
    width: 34rpx; height: 20rpx;
    background: $text-color-placeholder;
    border-radius: 17rpx 17rpx 4rpx 4rpx;
  }
}

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

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

.bottom-safe {
  height: $spacing-5;
}
</style>
