<template>
  <view class="page">
    <NavBar title="补货操作" showBack />

    <template>
      <!-- 补货单选择器 -->
      <view class="order-selector" v-if="pendingOrders.length > 1">
        <text class="selector-label">补货单</text>
        <picker mode="selector" :range="pendingOrders" range-key="orderNo" :value="selectedOrderIndex" @change="onOrderChange">
          <view class="selector-value"><text>{{ pendingOrders[selectedOrderIndex]?.orderNo || '' }}</text><text class="selector-arrow">▾</text></view>
        </picker>
        <text class="selector-status">{{ pendingOrders[selectedOrderIndex]?.statusLabel || '' }}</text>
      </view>
      <view class="order-banner" v-else-if="orderNo && pendingOrders.length <= 1">
        <text class="order-banner-text">补货单 {{ orderNo }}</text>
      </view>

      <view class="device-bar">
        <text class="device-bar-text">{{ deviceInfo.deviceId }}<text v-if="deviceInfo.name"> · {{ deviceInfo.name }}</text></text>
      </view>

      <view class="inventory-section">
        <view class="section-head">
          <text class="section-title">商品库存清单</text>
          <view class="order-toggle" v-if="orderNo" @click="showOrderOnly = !showOrderOnly">
            <text class="toggle-label">仅看补货单</text>
            <view class="toggle-switch" :class="{ on: showOrderOnly }"><view class="toggle-knob"></view></view>
          </view>
        </view>

        <view class="search-bar">
          <view class="search-icon"></view>
          <input class="search-input" v-model="searchKeyword" placeholder="搜索商品名称或编码" confirm-type="search" />
          <view class="search-clear" v-if="searchKeyword" @click="searchKeyword = ''"><text>✕</text></view>
        </view>

        <view class="empty-state" v-if="!loading && inventoryList.length === 0">
          <view class="empty-icon-box"><view class="empty-doc-icon"></view></view>
          <text class="empty-text">暂无商品库存数据</text>
        </view>

        <view class="empty-state" v-else-if="!loading && inventoryList.length > 0 && filteredInventoryList.length === 0">
          <text class="empty-text">未找到匹配商品</text>
        </view>

        <view class="inventory-card" v-for="({ item, idx }, i) in filteredInventoryList" :key="idx" v-show="!showOrderOnly || isInOrder(item)">
          <view class="item-row">
            <image v-if="item.product_image" :src="item.product_image" class="item-img" mode="aspectFill" />
            <view v-else class="item-img-placeholder"><text>无图</text></view>
            <view class="item-info">
              <view class="item-name-row">
                <text class="item-name">{{ item.product_name || item.productName || '未知商品' }}</text>
                <view class="stock-badge" :class="getStockStatus(item)">{{ getStockStatusText(item) }}</view>
              </view>
              <view class="item-meta">
                <text class="item-code" v-if="item.product_code || item.productCode">{{ item.product_code || item.productCode }}</text>
                <text class="item-std">标准 {{ item.standard_stock || item.standardStock || '-' }}</text>
                <text class="item-cur" :class="{ warn: isLowStock(item), danger: isOutOfStock(item) }">剩余 {{ item.stock || 0 }}</text>
              </view>
            </view>
          </view>
          <view class="replenish-row">
            <view class="qty-control">
              <view class="qty-btn" @click="decrease(item, idx)"><text>-</text></view>
              <input class="qty-input" type="number" v-model="replenishItems[idx].quantity" @blur="validateQuantity(idx)" />
              <view class="qty-btn" @click="increase(item, idx)"><text>+</text></view>
            </view>
            <view class="fill-btn" @click="suggestQuantity(item, idx)"><text>补满</text></view>
          </view>
        </view>
      </view>

      <!-- 补货员底部操作 -->
      <view class="bottom-bar" v-if="!loading && inventoryList.length > 0 && isReplenisherUser">
        <view class="bottom-btn secondary" @click="handleCancel"><text>终止任务</text></view>
        <view class="bottom-btn secondary" @click="handleReopen"><text>重新开门</text></view>
        <view class="bottom-btn primary" :class="{ disabled: submitting || totalReplenishCount === 0 }" @click="handleSubmit">
          <view class="btn-spinner" v-if="submitting"></view>
          <text>{{ submitting ? '提交中' : '一键提交' }}</text>
        </view>
      </view>
      <!-- 运营人员底部操作 -->
      <view class="bottom-bar" v-else-if="inventoryList.length > 0">
        <text class="total-label">共补货 <text class="total-num">{{ totalReplenishCount }}</text> 件</text>
        <view class="submit-btn" :class="{ disabled: submitting || totalReplenishCount === 0 }" @click="handleSubmit">
          <view class="btn-spinner" v-if="submitting"></view>
          <text>{{ submitting ? '提交中' : '确认补货' }}</text>
        </view>
      </view>
    </template>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import NavBar from '@/components/NavBar.vue';
import { getDeviceInventory, replenishStock, getDevicePendingOrders, getReplenisherOrderDetail, openDeviceDoor, getDeviceDoorStatus } from '@/api/replenish';
import { isReplenisher } from '@/utils/auth';

interface ReplenishInput {
  productId: number;
  productCode?: string;
  productName?: string;
  quantity: number;
  shelfNum?: number;
  position?: string;
}

const deviceId = ref('');
const deviceInfo = ref<any>({});
const inventoryList = ref<any[]>([]);
const replenishItems = ref<ReplenishInput[]>([]);
const submitting = ref(false);
const isReplenisherUser = ref(false);
const loading = ref(true);
const orderId = ref('');
const orderNo = ref('');
const showOrderOnly = ref(false);
const orderItemCodes = ref<Set<string>>(new Set());
const searchKeyword = ref('');

const filteredInventoryList = computed(() => {
  const kw = searchKeyword.value.trim().toLowerCase();
  return inventoryList.value
    .map((item, idx) => ({ item, idx }))
    .filter(({ item }) => {
      if (!kw) return true;
      const name = (item.product_name || item.productName || '').toLowerCase();
      const code = (item.product_code || item.productCode || '').toLowerCase();
      return name.includes(kw) || code.includes(kw);
    });
});
const pendingOrders = ref<any[]>([]);
const selectedOrderIndex = ref(0);
const doorClosedAlertShown = ref(false);
let doorPollTimer: any = null;

const isInOrder = (item: any) => {
  const code = (item.product_code || item.productCode || '').trim().toUpperCase();
  for (const oc of orderItemCodes.value) { if (oc.toUpperCase() === code) return true; }
  return false;
};

// 补货单预填数据
const orderItemsData = ref<any[]>([]);

const totalReplenishCount = computed(() => {
  return replenishItems.value.reduce((s, i) => s + (i.quantity || 0), 0);
});

const isLowStock = (item: any) => { const s = item.stock || 0; const t = item.warning_threshold || item.warningThreshold || 5; return s > 0 && s <= t; };
const isOutOfStock = (item: any) => (item.stock || 0) === 0;
const getStockStatus = (item: any) => isOutOfStock(item) ? 'danger' : isLowStock(item) ? 'warning' : 'normal';
const getStockStatusText = (item: any) => (item.stock || 0) === 0 ? '缺货' : (item.stock || 0) <= (item.warning_threshold || item.warningThreshold || 5) ? '低库存' : '正常';

const decrease = (_: any, i: number) => { if (replenishItems.value[i].quantity > 0) replenishItems.value[i].quantity--; };
const increase = (_: any, i: number) => { if (replenishItems.value[i].quantity < 9999) replenishItems.value[i].quantity++; };
const suggestQuantity = (item: any, i: number) => {
  const std = item.standard_stock || item.standardStock || 0;
  const cur = item.stock || 0;
  replenishItems.value[i].quantity = cur >= std ? 0 : std - cur;
};
const validateQuantity = (i: number) => { if (replenishItems.value[i].quantity < 0) replenishItems.value[i].quantity = 0; };

const handleSubmit = async () => {
  if (submitting.value || totalReplenishCount.value === 0) return;
  const items = replenishItems.value.filter(i => i.quantity > 0).map(i => ({
    productId: i.productId, productCode: i.productCode, productName: i.productName,
    quantity: i.quantity, shelfNum: i.shelfNum, position: i.position
  }));
  if (!items.length) { uni.showToast({ title: '请至少补货一件', icon: 'none' }); return; }

  submitting.value = true;
  try {
    const payload: any = { deviceId: deviceId.value, items };
    if (orderId.value) payload.orderId = orderId.value;
    const result = await replenishStock(payload);
    uni.removeStorageSync('pendingReplenishOrder');
    uni.showToast({ title: `补货完成，成功${result.success}项`, icon: 'success' });
    setTimeout(() => uni.navigateBack(), 800);
  } catch (e: any) {
    uni.showToast({ title: e.message || '补货失败', icon: 'none' });
  } finally { submitting.value = false; }
};

const loadOrderItems = async (oid: string) => {
  try {
    const data = await getReplenisherOrderDetail(oid as any);
    if (!data?.items?.length) return;
    orderId.value = oid;
    orderNo.value = data.order?.orderNo || '';
    const items = data.items.map((item: any) => ({
      productCode: (item.productCode || '').trim(),
      productName: item.productName,
      plannedQuantity: item.plannedQuantity || item.quantity || 0,
      shelfNum: item.shelfNum,
      position: item.position
    }));
    orderItemsData.value = items;
    orderItemCodes.value = new Set(items.map((oi: any) => oi.productCode.toUpperCase()));

    // 重新匹配库存并更新数量
    const list = inventoryList.value;
    replenishItems.value = list.map((it: any) => {
      const hasProduct = it.product_id || it.productId;
      if (!hasProduct) return { productId: null, productCode: '', productName: '', quantity: 0, shelfNum: null, position: null };
      const code = (it.product_code || it.productCode || '').trim();
      const m = items.find((oi: any) => oi.productCode.toUpperCase() === code.toUpperCase());
      return {
        productId: it.product_id || it.productId, productCode: code,
        productName: it.product_name || it.productName || '',
        quantity: m ? (m.plannedQuantity || 0) : 0,
        shelfNum: it.shelf_num || it.shelfNum || null, position: it.position || null
      };
    });
  } catch { /* ignore */ }
};

const onOrderChange = (e: any) => {
  const idx = e.detail.value;
  selectedOrderIndex.value = idx;
  const o = pendingOrders.value[idx];
  if (o) loadOrderItems(String(o.id));
};

const handleCancel = () => {
  uni.showModal({
    title: '终止任务',
    content: '确定要终止当前补货任务吗？',
    success: (res) => { if (res.confirm) uni.navigateBack(); }
  });
};

const handleReopen = () => {
  uni.showModal({
    title: '重新开门',
    content: '确定要远程打开柜门吗？',
    success: async (res) => {
      if (!res.confirm) return;
      try {
        await openDeviceDoor(deviceId.value);
        uni.showToast({ title: '开门指令已发送', icon: 'success' });
      } catch (e: any) {
        uni.showToast({ title: e.message || '开门失败', icon: 'none' });
      }
    }
  });
};

const startDoorPolling = () => {
  if (!deviceId.value) return;
  doorPollTimer = setInterval(async () => {
    if (doorClosedAlertShown.value) return;
    try {
      const status = await getDeviceDoorStatus(deviceId.value);
      if (status.status !== 1) {
        doorClosedAlertShown.value = true;
        uni.showModal({
          title: '柜门已关闭',
          content: '检测到柜门已关闭，是否继续补货？\n\n选择「继续补货」留在当前页面\n选择「提交结果」直接提交补货',
          cancelText: '提交结果',
          confirmText: '继续补货',
          success: (res) => {
            if (!res.confirm) {
              handleSubmit();
            }
          }
        });
      }
    } catch { /* ignore poll errors */ }
  }, 3000);
};

onMounted(async () => {
  const pages = getCurrentPages();
  const opts = (pages[pages.length - 1] as any)?.$page?.options || (pages[pages.length - 1] as any)?.options || {};
  isReplenisherUser.value = isReplenisher();
  deviceId.value = opts.deviceId || '';
  orderId.value = opts.orderId || '';
  if (!deviceId.value) { uni.showToast({ title: '缺少设备ID', icon: 'none' }); setTimeout(() => uni.navigateBack(), 500); return; }

  try {
    const data = await getDeviceInventory(deviceId.value);
    deviceInfo.value = data;
    const list = data.inventoryList || [];
    inventoryList.value = list;

    // 加载待处理补货单列表
    pendingOrders.value = await getDevicePendingOrders(deviceId.value);

    let orderItems: any[] = [];
    let targetIndex = 0;

    if (pendingOrders.value.length > 0) {
      // 如果有传入orderId，定位到对应补货单
      if (orderId.value) {
        targetIndex = pendingOrders.value.findIndex((o: any) => String(o.id) === String(orderId.value));
        if (targetIndex < 0) targetIndex = 0;
      }
      selectedOrderIndex.value = targetIndex;
      const targetOrder = pendingOrders.value[targetIndex];
      if (targetOrder) {
        // 拉取补货单详情
        try {
          const detail = await getReplenisherOrderDetail(targetOrder.id);
          if (detail?.items) {
            orderId.value = String(targetOrder.id);
            orderNo.value = targetOrder.orderNo || '';
            orderItems = detail.items.map((item: any) => ({
              productCode: (item.productCode || '').trim(),
              productName: item.productName,
              plannedQuantity: item.plannedQuantity || item.quantity || 0,
              shelfNum: item.shelfNum,
              position: item.position
            }));
            orderItemsData.value = orderItems;
            orderItemCodes.value = new Set(orderItems.map((oi: any) => oi.productCode.toUpperCase()));
            showOrderOnly.value = true;
          }
        } catch { /* fallback */ }
      }
    } else {
      // 没有待处理补货单时尝试从localStorage加载
      const orderStr = uni.getStorageSync('pendingReplenishOrder');
      if (orderStr) {
        try { const od = JSON.parse(orderStr); if (String(od.orderId) === String(orderId.value)) { orderNo.value = od.orderNo || ''; orderItems = od.items || []; orderItemsData.value = orderItems; orderItemCodes.value = new Set(orderItems.map((oi: any) => (oi.productCode || '').trim().toUpperCase())); showOrderOnly.value = true; } } catch { }
      }
    }

    replenishItems.value = list.map((it: any) => {
      const hasProduct = it.product_id || it.productId;
      if (!hasProduct) return { productId: null, productCode: '', productName: '', quantity: 0, shelfNum: null, position: null };
      const code = (it.product_code || it.productCode || '').trim();
      const m = orderItems.find((oi: any) => oi.productCode.toUpperCase() === code.toUpperCase());
      return {
        productId: it.product_id || it.productId, productCode: code,
        productName: it.product_name || it.productName || '',
        quantity: m ? (m.plannedQuantity || 0) : 0,
        shelfNum: it.shelf_num || it.shelfNum || null, position: it.position || null
      };
    });
  } catch (e: any) {
    uni.showToast({ title: e.message || '加载失败', icon: 'none' });
  } finally {
    loading.value = false;
    startDoorPolling();
  }
});

onUnmounted(() => {
  if (doorPollTimer) { clearInterval(doorPollTimer); doorPollTimer = null; }
});
</script>

<style lang="scss" scoped>
.page { height: 100vh; background: $bg-color-page; display: flex; flex-direction: column; }

.order-selector { display: flex; align-items: center; gap: 12rpx; margin: 12rpx 24rpx; padding: 12rpx 20rpx; background: $primary-color-bg; border-radius: $radius-sm; }
.selector-label { font-size: $font-size-sm; color: $text-color-muted; flex-shrink: 0; }
.selector-value { display: flex; align-items: center; gap: 6rpx; padding: 4rpx 14rpx; background: $bg-color-card; border-radius: $radius-sm; border: 1rpx solid $border-color;
  text { font-size: $font-size-sm; color: $text-color-primary; font-weight: 500; }
}
.selector-arrow { font-size: 18rpx; color: $text-color-muted; }
.selector-status { font-size: 22rpx; color: $primary-color-dark; margin-left: auto; }
.order-banner { margin: 12rpx 24rpx; padding: 14rpx 20rpx; background: $primary-color-bg; border-radius: $radius-sm; }
.order-banner-text { font-size: $font-size-sm; color: $primary-color-dark; }

.device-bar { margin: 12rpx 24rpx; padding: 16rpx 20rpx; background: $bg-color-card; border-radius: $radius-md; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); }
.device-bar-text { font-size: $font-size-sm; font-weight: 600; color: $text-color-primary; }

.inventory-section { padding: 0 24rpx; flex: 1; height: 0; overflow-y: auto; }
.section-head { display: flex; align-items: center; justify-content: space-between; padding: 16rpx 0 12rpx; }
.section-title { font-size: $font-size-md; font-weight: 700; color: $text-color-primary; }
.search-bar { display: flex; align-items: center; background: $bg-color-card; border: 1rpx solid $border-color; border-radius: $radius-base; padding: 0 16rpx; height: 60rpx; margin-bottom: 12rpx; }
.search-icon { width: 28rpx; height: 28rpx; border: 2.5rpx solid $text-color-muted; border-radius: 50%; position: relative; flex-shrink: 0; margin-right: 10rpx;
  &::after { content: ''; position: absolute; bottom: -2rpx; right: -4rpx; width: 2.5rpx; height: 10rpx; background: $text-color-muted; border-radius: 1rpx; transform: rotate(-45deg); }
}
.search-input { flex: 1; font-size: $font-size-sm; color: $text-color-primary; height: 100%; }
.search-clear { width: 36rpx; height: 36rpx; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: $bg-color-secondary; flex-shrink: 0; margin-left: 8rpx;
  text { font-size: 20rpx; color: $text-color-muted; line-height: 1; }
}
.order-toggle { display: flex; align-items: center; gap: 8rpx; }
.toggle-label { font-size: 20rpx; color: $text-color-muted; }
.toggle-switch { width: 56rpx; height: 32rpx; border-radius: 16rpx; background: $border-color; position: relative; transition: background 0.2s;
  .toggle-knob { width: 26rpx; height: 26rpx; border-radius: 50%; background: $bg-color-card; position: absolute; top: 3rpx; left: 3rpx; transition: left 0.2s; box-shadow: 0 1rpx 4rpx rgba(0,0,0,0.1); }
  &.on { background: $primary-color; .toggle-knob { left: 27rpx; } }
}

.empty-state { display: flex; flex-direction: column; align-items: center; padding: 80rpx 0; }
.empty-icon-box { width: 96rpx; height: 96rpx; background: $bg-color-secondary; border-radius: $radius-lg; display: flex; align-items: center; justify-content: center; margin-bottom: $spacing-2; }
.empty-doc-icon { width: 40rpx; height: 48rpx; border: 2.5rpx solid $text-color-placeholder; border-radius: 4rpx; position: relative;
  &::after { content: ''; position: absolute; top: 14rpx; left: 8rpx; right: 8rpx; height: 2.5rpx; background: $text-color-placeholder; border-radius: 1rpx; box-shadow: 0 8rpx 0 $text-color-placeholder, 0 16rpx 0 $text-color-placeholder; }
}
.empty-text { font-size: $font-size-base; color: $text-color-muted; }

.inventory-card { margin-bottom: 10rpx; padding: 16rpx; background: $bg-color-card; border-radius: $radius-md; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); }

.item-row { display: flex; align-items: center; margin-bottom: 10rpx; }
.item-img { width: 56rpx; height: 56rpx; border-radius: $radius-sm; background: $bg-color-page; flex-shrink: 0; margin-right: 12rpx; }
.item-img-placeholder { width: 56rpx; height: 56rpx; border-radius: $radius-sm; background: $bg-color-page; flex-shrink: 0; margin-right: 12rpx; display: flex; align-items: center; justify-content: center;
  text { font-size: 18rpx; color: $text-color-muted; }
}
.item-info { flex: 1; min-width: 0; overflow: hidden; }
.item-name-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4rpx; }
.item-name { font-size: $font-size-base; font-weight: 600; color: $text-color-primary; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.item-meta { display: flex; gap: 16rpx; }
.item-code { font-size: 20rpx; color: $text-color-muted; }
.item-std { font-size: 20rpx; color: $text-color-muted; }
.item-cur { font-size: 20rpx; font-weight: 500; color: $text-color-primary;
  &.warn { color: $warning-color; }
  &.danger { color: $error-color; }
}

.stock-badge { padding: 2rpx 10rpx; border-radius: $radius-sm; font-size: 20rpx; font-weight: 500; flex-shrink: 0; margin-left: 8rpx;
  &.normal { background: $success-color-bg; color: $success-color; }
  &.warning { background: $warning-color-bg; color: $warning-color; }
  &.danger { background: $error-color-bg; color: $error-color; }
}

.replenish-row { display: flex; align-items: center; background: $bg-color-page; border-radius: $radius-base; padding: 8rpx 12rpx; }
.qty-control { display: flex; align-items: center; border: 1rpx solid $border-color; border-radius: $radius-sm; overflow: hidden; }
.qty-btn { width: 44rpx; height: 44rpx; display: flex; align-items: center; justify-content: center; background: $bg-color-card;
  text { font-size: 26rpx; color: $text-color-secondary; line-height: 1; }
  &:active { background: $bg-color-secondary; }
}
.qty-input { width: 64rpx; height: 44rpx; text-align: center; font-size: $font-size-base; font-weight: 600; color: $text-color-primary; border-left: 1rpx solid $border-color; border-right: 1rpx solid $border-color; }
.fill-btn { margin-left: auto; padding: 8rpx 20rpx; background: $success-color-bg; border-radius: $radius-sm;
  text { font-size: 22rpx; color: $success-color; font-weight: 500; }
  &:active { opacity: 0.7; }
}

.bottom-bar { display: flex; align-items: center; gap: 12rpx; padding: 16rpx 24rpx; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); background: $bg-color-card; border-top: 1rpx solid $border-color-light; }
.total-label { font-size: $font-size-sm; color: $text-color-muted; flex-shrink: 0; }
.total-num { font-size: $font-size-xl; font-weight: 700; color: $primary-color-dark; margin: 0 4rpx; }
.bottom-btn { flex: 1; height: 72rpx; display: flex; align-items: center; justify-content: center; border-radius: $radius-base;
  text { font-size: $font-size-base; font-weight: 600; line-height: 1; }
  &:active { opacity: 0.8; }
  &.secondary { background: $bg-color-page; text { color: $text-color-secondary; } }
  &.primary { background: $primary-color; text { color: $text-color-primary; } }
  &.disabled { opacity: 0.5; pointer-events: none; }
}
.submit-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 12rpx; height: 72rpx; background: $primary-color; border-radius: $radius-base;
  text { font-size: $font-size-md; font-weight: 600; color: $text-color-primary; }
  &:active { opacity: 0.8; }
  &.disabled { opacity: 0.5; pointer-events: none; }
}
.btn-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.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
</style>
