<template>
  <view class="products-page">
    <!-- 加载状态 -->
    <view v-if="loading" class="loading-container">
      <view class="loading-spinner"></view>
      <text class="loading-text">加载中...</text>
    </view>

    <!-- 错误状态 -->
    <view v-else-if="errorMsg" class="error-container">
      <text class="error-icon">!</text>
      <text class="error-text">{{ errorMsg }}</text>
      <view class="error-btn" @click="goBack">返回</view>
    </view>

    <!-- 商品内容 -->
    <view v-else class="content">
      <!-- 双门柜Tab切换 -->
      <view v-if="hasRightDoor" class="door-tabs">
        <view
          class="door-tab"
          :class="{ active: activeDoor === 'left' }"
          @click="activeDoor = 'left'"
        >左门</view>
        <view
          class="door-tab"
          :class="{ active: activeDoor === 'right' }"
          @click="activeDoor = 'right'"
        >右门</view>
      </view>

      <!-- 商品列表 -->
      <view class="floors-list">
        <view
          v-for="floor in currentFloors"
          :key="floor.floor"
          class="floor-card"
        >
          <view class="floor-header">
            <view class="floor-badge">{{ floor.floor }}</view>
            <text class="floor-title">第{{ floor.floor }}层</text>
            <text class="floor-count">{{ floor.goods?.length || 0 }}件商品</text>
          </view>

          <!-- 该层无商品 -->
          <view v-if="!floor.goods || floor.goods.length === 0" class="empty-floor">
            <text class="empty-text">该层暂无商品</text>
          </view>

          <!-- 商品列表 -->
          <view v-else class="goods-list">
            <view
              v-for="(item, index) in floor.goods"
              :key="index"
              class="goods-item"
            >
              <!-- 商品图片 -->
              <view class="goods-image-wrap">
                <image
                  v-if="item.pic"
                  :src="item.pic"
                  class="goods-image"
                  mode="aspectFill"
                />
                <view v-else class="goods-image-placeholder">
                  <text class="placeholder-text">暂无图片</text>
                </view>
              </view>

              <!-- 商品信息 -->
              <view class="goods-info">
                <text class="goods-name">{{ item.label || '未知商品' }}</text>
                <text v-if="item.type" class="goods-type">{{ item.type }}</text>
                <view class="goods-price-row">
                  <text class="goods-price">¥{{ item.c_price || '0.00' }}</text>
                  <text
                    v-if="item.dis_price && item.dis_price !== item.c_price"
                    class="goods-discount-price"
                  >¥{{ item.dis_price }}</text>
                </view>
              </view>
            </view>
          </view>
        </view>

        <!-- 无任何层数据 -->
        <view v-if="currentFloors.length === 0" class="empty-container">
          <text class="empty-icon">📦</text>
          <text class="empty-main-text">暂无商品信息</text>
          <text class="empty-sub-text">该设备尚未配置商品</text>
        </view>
      </view>

      <!-- 底部占位，避免被固定栏遮挡 -->
      <view class="bottom-placeholder"></view>
    </view>

    <!-- 底部操作栏 -->
    <view v-if="!loading && !errorMsg" class="bottom-bar">
      <!-- 扫码开门按钮（暂时隐藏，可能以后还会用到） -->
      <!-- <view class="bottom-actions">
        <view class="btn-open" @click="handleOpenDoor">
          <image
            class="btn-open__logo"
            src="/static/icons/payscore-button.png"
            mode="aspectFit"
          />
          <text>{{ opening ? '处理中...' : '扫码开门' }}</text>
        </view>
      </view> -->
      <view class="bottom-actions">
        <view class="btn-open-door" @click="handleOpenDoor">
          <text>{{ opening ? '处理中...' : '立即开门' }}</text>
        </view>
      </view>
      <view class="bottom-trust">
        <BrandSlogan type="standard" :compact="true" />
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { API_CONFIG } from '@/utils/config';
import { getDeviceProducts, scanDoor } from '@/api/device';
import { queryPayscoreByOutNo } from '@/api/payscore';
import { isLoggedIn, getToken } from '@/utils/auth';
import { logger } from '@/utils/logger';
import BrandSlogan from '@/components/BrandSlogan.vue';
import type { FloorConfig } from '@/api/device';

const deviceId = ref('');

const loading = ref(true);
const errorMsg = ref('');
const templateName = ref('');
const shelfNum = ref(0);
const deviceType = ref(0);
const leftFloors = ref<FloorConfig[]>([]);
const rightFloors = ref<FloorConfig[]>([]);
const opening = ref(false);
let pollingOutOrderNo = '';
let pollTimer: ReturnType<typeof setInterval> | null = null;

const activeDoor = ref<'left' | 'right'>('left');

const hasRightDoor = computed(() => rightFloors.value.length > 0);

const currentFloors = computed(() => {
  if (activeDoor.value === 'right' && hasRightDoor.value) {
    return rightFloors.value;
  }
  return leftFloors.value;
});

onLoad((options: any) => {
  let id = '';

  if (options?.deviceId) {
    id = options.deviceId;
  } else if (options?.q) {
    try {
      const url = decodeURIComponent(options.q);
      logger.log('扫码链接:', url);
      const match = url.match(/\/([A-Za-z0-9]+)(?:\?|$)/);
      if (match && match[1]) {
        id = match[1];
      }
    } catch (e) {
      logger.error('解析扫码链接失败:', e);
    }
  }

  if (id) {
    logger.log('设备ID:', id);
    deviceId.value = id;
    loadProducts();
  } else {
    errorMsg.value = '缺少设备ID参数';
    loading.value = false;
  }
});

const loadProducts = async () => {
  loading.value = true;
  errorMsg.value = '';

  try {
    const data = await getDeviceProducts(deviceId.value);
    templateName.value = data.templateName || '';
    shelfNum.value = data.shelfNum || 0;
    deviceType.value = data.deviceType || 0;
    leftFloors.value = data.leftFloors || [];
    rightFloors.value = data.rightFloors || [];
  } catch (error: any) {
    logger.error('加载商品数据失败:', error);
    errorMsg.value = error.message || '加载失败，请稍后重试';
  } finally {
    loading.value = false;
  }
};

const handleOpenDoor = () => {
  if (opening.value) return;

  if (!isLoggedIn()) {
    uni.showModal({
      title: '提示',
      content: '请先登录后再开门购物',
      showCancel: false,
      success: () => {
        uni.reLaunch({
          url: '/pages/login/login?redirect=' + encodeURIComponent('/pages/products/products?deviceId=' + deviceId.value)
        });
      }
    });
    return;
  }

  opening.value = true;
  uni.showLoading({ title: '准备中...', mask: true });

  // 使用 uni.request 回调方式，避免 async/await 打破手势链
  uni.request({
    url: API_CONFIG.baseUrl + '/payscore/pre-create',
    method: 'POST',
    header: {
      'Content-Type': 'application/json',
      'accessToken': getToken()
    },
    data: { deviceId: deviceId.value },
    success: (apiRes: any) => {
      uni.hideLoading();

      const body = apiRes.data;
      if (body.code !== 200 && body.code !== 0) {
        opening.value = false;
        uni.showToast({ title: body.message || '创建失败', icon: 'none' });
        return;
      }

      const data = body.data;
      if (!data || !data.package) {
        opening.value = false;
        uni.showToast({ title: data?.errorMsg || '创建支付分订单失败', icon: 'none' });
        return;
      }

      logger.log('[商品页] 预创建成功，直接拉起官方授权页');

      pollingOutOrderNo = data.outOrderNo;

      // 在原生回调中调用 openBusinessView，保持在手势链内
      wx.openBusinessView({
        businessType: 'wxpayScoreUse',
        extraData: {
          package: data.package,
        },
        success: () => {
          logger.log('[商品页] 从授权页返回，轮询确认状态');
          startPolling();
        },
        fail: (err: any) => {
          opening.value = false;
          const errMsg = err?.errMsg || JSON.stringify(err);
          logger.error('[商品页] openBusinessView fail:', errMsg);

          // 用户主动取消，静默处理
          if (errMsg.includes('cancel')) {
            return;
          }

          // 根据错误原因给出不同提示
          const lowScore = errMsg.includes('分') || errMsg.includes('credit') || errMsg.includes('score');
          const notEnabled = errMsg.includes('未开通') || errMsg.includes('未授权') || errMsg.includes('not signed') || errMsg.includes('not enabled');

          if (lowScore) {
            uni.showModal({
              title: '支付分不足',
              content: '您的微信支付分未达到使用门槛（550分），暂无法使用本服务。\n\n请保持良好的信用记录，后续再试。',
              showCancel: false,
              confirmText: '我知道了',
            });
          } else if (notEnabled) {
            uni.showModal({
              title: '未开通微信支付分',
              content: '您尚未开通微信支付分，请先开通后再使用本服务。',
              showCancel: false,
              confirmText: '去开通',
              success: (res: any) => {
                if (res.confirm) {
                  uni.navigateTo({ url: '/pages/payscore/enable' });
                }
              },
            });
          } else {
            uni.showModal({
              title: '调起支付分失败',
              content: '支付分服务暂不可用，请稍后重试。',
              showCancel: false,
              confirmText: '我知道了',
            });
          }
        },
      });
    },
    fail: (err: any) => {
      uni.hideLoading();
      opening.value = false;
      logger.error('[商品页] API 请求失败', err);
      uni.showToast({ title: '网络异常，请重试', icon: 'none' });
    }
  });
};

const startPolling = () => {
  uni.showLoading({ title: '确认结果...', mask: true });

  let attempts = 0;
  const maxAttempts = 10;

  if (pollTimer) clearInterval(pollTimer);

  pollTimer = setInterval(async () => {
    attempts++;
    try {
      const res = await queryPayscoreByOutNo(pollingOutOrderNo);
      const state = res?.state;

      logger.log(`[商品页] 轮询第 ${attempts} 次, state:`, state);

      if (state === 'DOING') {
        if (pollTimer) { clearInterval(pollTimer); pollTimer = null; }
        uni.hideLoading();
        opening.value = false;
        logger.log('[商品页] 用户已确认，开门');
        doOpenDoor();
        return;
      }

      if (attempts >= maxAttempts) {
        if (pollTimer) { clearInterval(pollTimer); pollTimer = null; }
        uni.hideLoading();
        opening.value = false;
        logger.log('[商品页] 轮询超时，用户未确认');
      }
    } catch (e) {
      logger.error('[商品页] 轮询异常', e);
      if (attempts >= maxAttempts) {
        if (pollTimer) { clearInterval(pollTimer); pollTimer = null; }
        uni.hideLoading();
        opening.value = false;
      }
    }
  }, 1000);
};

const doOpenDoor = () => {
  uni.showLoading({ title: '正在开门...', mask: true });

  scanDoor(deviceId.value).then(response => {
    uni.hideLoading();
    uni.showToast({ title: '开门成功', icon: 'success' });

    uni.setStorageSync('currentDeviceId', response.deviceId);
    uni.setStorageSync('currentOutTradeNo', response.outTradeNo);
    uni.setStorageSync('currentOrderNo', response.orderNo);
    uni.removeStorageSync('shoppingPollingActive');

    setTimeout(() => {
      uni.redirectTo({ url: '/pages/shopping/shopping' });
    }, 1000);
  }).catch((error: any) => {
    uni.hideLoading();
    opening.value = false;
    logger.error('开门失败:', error);
  });
};

const goBack = () => {
  if (!isLoggedIn()) {
    uni.reLaunch({ url: '/pages/login/login' });
    return;
  }
  uni.navigateBack({
    fail: () => {
      uni.reLaunch({ url: '/pages/index/index' });
    }
  });
};
</script>

<style lang="scss" scoped>
.products-page {
  min-height: 100vh;
  background: $color-bg-secondary;
}

/* 加载状态 */
.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 60vh;
}

.loading-spinner {
  width: 60rpx;
  height: 60rpx;
  border: 4rpx solid $color-border;
  border-top-color: $color-primary;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

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

.loading-text {
  margin-top: $spacing-sm;
  font-size: 28rpx;
  color: $color-text-secondary;
}

/* 错误状态 */
.error-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 60vh;
  padding: 0 60rpx;
}

.error-icon {
  width: 80rpx;
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  background: $color-error;
  color: $color-bg-primary;
  border-radius: 50%;
  font-size: 40rpx;
  font-weight: 700;
}

.error-text {
  margin-top: $spacing-md;
  font-size: 28rpx;
  color: $color-text-secondary;
  text-align: center;
}

.error-btn {
  margin-top: $spacing-xl;
  padding: $spacing-sm 60rpx;
  background: $color-primary;
  color: $color-text-primary;
  border-radius: $radius-xl;
  font-size: 28rpx;
  font-weight: 600;
}

/* 门Tab切换 */
.door-tabs {
  display: flex;
  background: $color-bg-primary;
  border-bottom: 1rpx solid $color-border;
}

.door-tab {
  flex: 1;
  text-align: center;
  padding: 24rpx 0;
  font-size: 28rpx;
  color: $color-text-secondary;
  position: relative;
}

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

  &::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 60rpx;
    height: 4rpx;
    background: $color-primary;
    border-radius: 2rpx;
  }
}

/* 楼层列表 */
.floors-list {
  padding: $spacing-sm;
}

.floor-card {
  background: $color-bg-primary;
  border-radius: $radius-md;
  margin-bottom: $spacing-sm;
  overflow: hidden;
  box-shadow: $shadow-sm;
}

.floor-header {
  display: flex;
  align-items: center;
  padding: 20rpx 24rpx;
  border-bottom: 1rpx solid $color-border;
}

.floor-badge {
  width: 44rpx;
  height: 44rpx;
  line-height: 44rpx;
  text-align: center;
  background: $color-primary;
  color: $color-text-primary;
  border-radius: $radius-sm;
  font-size: 24rpx;
  font-weight: 600;
  margin-right: $spacing-sm;
}

.floor-title {
  font-size: 28rpx;
  font-weight: 600;
  color: $color-text-primary;
  flex: 1;
}

.floor-count {
  font-size: 24rpx;
  color: $color-text-secondary;
}

/* 空楼层 */
.empty-floor {
  padding: 40rpx 0;
  text-align: center;
}

.empty-text {
  font-size: 26rpx;
  color: $color-text-tertiary;
}

/* 商品列表 */
.goods-list {
  padding: 0 24rpx;
}

.goods-item {
  display: flex;
  padding: 20rpx 0;
  border-bottom: 1rpx solid $color-bg-secondary;

  &:last-child {
    border-bottom: none;
  }
}

/* 商品图片 */
.goods-image-wrap {
  width: 140rpx;
  height: 140rpx;
  border-radius: 12rpx;
  overflow: hidden;
  flex-shrink: 0;
  background: $color-bg-tertiary;
}

.goods-image {
  width: 100%;
  height: 100%;
}

.goods-image-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: $color-bg-tertiary;
}

.placeholder-text {
  font-size: 20rpx;
  color: $color-text-tertiary;
}

/* 商品信息 */
.goods-info {
  flex: 1;
  margin-left: 20rpx;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

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

.goods-type {
  font-size: 22rpx;
  color: $color-text-secondary;
  margin-top: 6rpx;
}

.goods-price-row {
  display: flex;
  align-items: baseline;
  gap: 12rpx;
  margin-top: 8rpx;
}

.goods-price {
  font-size: 32rpx;
  color: $color-error;
  font-weight: 600;
}

.goods-discount-price {
  font-size: 24rpx;
  color: $color-text-secondary;
  text-decoration: line-through;
}

/* 无数据 */
.empty-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: $spacing-xxl 0;
}

.empty-icon {
  font-size: 80rpx;
}

.empty-main-text {
  margin-top: $spacing-md;
  font-size: 28rpx;
  color: $color-text-primary;
  font-weight: 600;
}

.empty-sub-text {
  margin-top: $spacing-xs;
  font-size: 24rpx;
  color: $color-text-secondary;
}

/* 底部占位 */
.bottom-placeholder {
  height: 180rpx;
}

/* 底部操作栏 */
.bottom-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: $spacing-md 30rpx;
  padding-bottom: calc($spacing-md + env(safe-area-inset-bottom));
  background: $color-bg-primary;
  box-shadow: 0 -2rpx 16rpx rgba(0, 0, 0, 0.04);
}

.bottom-trust {
  display: flex;
  justify-content: center;
  margin-top: $spacing-sm;
}

.bottom-actions {
  display: flex;
  justify-content: center;
}

.btn-open {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10rpx;
  padding: 22rpx 120rpx;
  border-radius: $radius-xl;
  font-size: 30rpx;
  font-weight: 600;
  color: $color-bg-primary;
  background: linear-gradient(135deg, #00B74B, #009A3F);
  box-shadow: 0 6rpx 20rpx rgba(0, 183, 75, 0.3);
  animation: btn-breathe 2.4s $ease-in-out infinite;

  &:active {
    opacity: 0.9;
    transform: scale(0.98);
    animation: none;
  }
}

.btn-open__logo {
  width: 36rpx;
  height: 36rpx;
  flex-shrink: 0;
}

.btn-open-door {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22rpx 120rpx;
  border-radius: $radius-xl;
  font-size: 30rpx;
  font-weight: 600;
  color: #333;
  background: linear-gradient(135deg, #FFC107, #FFB300);
  box-shadow: 0 6rpx 20rpx rgba(255, 193, 7, 0.35);
  animation: btn-breathe 2.4s $ease-in-out infinite;

  &:active {
    opacity: 0.9;
    transform: scale(0.98);
    animation: none;
  }
}

@keyframes btn-breathe {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.04);
  }
}
</style>
