<template>
  <view class="container">
    <!-- 顶部品牌区 -->
    <view class="brand-section">
      <text class="brand-title">AI零售柜</text>
      <text class="brand-slogan">智能视觉 · 即拿即走</text>
    </view>

    <!-- 核心操作区 -->
    <view class="action-section">
      <button class="scan-button" @click="scanCode" :disabled="busy">
        <view class="scan-button-inner">
          <image class="scan-icon" src="/static/icons/scan.svg" mode="aspectFill"></image>
          <text class="scan-text">{{ busy ? '处理中...' : '扫码开门' }}</text>
        </view>
        <view class="scan-button-ripple"></view>
      </button>
    </view>

    <!-- 快捷功能区 -->
    <view class="quick-actions">
      <view class="quick-action-item" @click="goToMy">
        <view class="action-icon">
          <image src="/static/icons/my.svg" mode="aspectFit"></image>
        </view>
        <text class="action-label">我的</text>
      </view>
      <view class="quick-action-item" @click="goToOrders">
        <view class="action-icon">
          <image src="/static/icons/orders.svg" mode="aspectFit"></image>
        </view>
        <text class="action-label">订单</text>
      </view>
      <view class="quick-action-item" @click="goToCouponCenter">
        <view class="action-icon">
          <image src="/static/icons/coupon.svg" mode="aspectFit"></image>
        </view>
        <text class="action-label">优惠券</text>
      </view>
      <!-- TODO: 调试入口，上线前移除 -->
      <!-- <view class="quick-action-item" @click="goToOrderComplete">
        <view class="action-icon debug-icon">
          <text class="debug-icon-text">🧪</text>
        </view>
        <text class="action-label">结算页</text>
      </view> -->
    </view>

    <!-- 底部信息卡片 -->
    <view class="info-card">
      <view class="info-item">
        <image class="info-icon payscore-icon" src="/static/icons/pay-socre-logo.png" mode="aspectFit"></image>
        <text class="info-text">微信支付分 | 550分及以上优享</text>
      </view>
      <view class="info-item">
        <CustomerServiceButton
          mode="inline"
          title="首页-联系客服"
          :path="'/pages/index/index'"
          @contact="onContactSuccess"
        >
          <text class="info-icon">💬</text>
          <text class="info-text">在线客服</text>
        </CustomerServiceButton>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { API_CONFIG } from '../../utils/config'
import { scanDoor } from '../../api/device'
import { queryPayscoreByOutNo } from '../../api/payscore'
import { isLoggedIn, getToken } from '../../utils/auth'
import { logger } from '../../utils/logger'

const busy = ref(false)
let pollingDeviceId = ''
let pollingOutOrderNo = ''
let pollTimer: ReturnType<typeof setInterval> | null = null

onShow(() => {
  const token = getToken()
  logger.log('[首页 onShow] token:', token ? '存在' : '不存在')
})

const scanCode = () => {
  if (busy.value) return

  if (!isLoggedIn()) {
    uni.showModal({
      title: '提示',
      content: '请先登录后再扫码开门',
      showCancel: false,
      success: () => {
        uni.reLaunch({ url: '/pages/login/login?redirect=/pages/index/index' });
      }
    });
    return;
  }

  uni.scanCode({
    success: function (res) {
      logger.log('扫码结果:', res.result);

      let deviceId = '';
      try {
        const urlPattern = /\/([A-Z0-9]+)(\?|$)/;
        const match = res.result.match(urlPattern);
        if (match && match[1]) {
          deviceId = match[1];
        } else {
          try {
            const qrData = JSON.parse(res.result);
            if (qrData.deviceId) deviceId = qrData.deviceId;
          } catch (e) {
            deviceId = res.result;
          }
        }
        if (!deviceId) throw new Error('无法解析设备ID');
        logger.log('提取到设备ID:', deviceId);
      } catch (error) {
        logger.error('解析设备ID失败:', error);
        uni.showToast({ title: '二维码格式错误', icon: 'none' });
        return;
      }

      // 关键：在 scanCode 回调中直接调用 API + openBusinessView
      // 全程不用 async/await，保持在用户手势链中
      preCreateAndOpenBusinessView(deviceId);
    },
    fail: function (err) {
      logger.log('扫码取消:', err);
    }
  });
};

/**
 * 预创建支付分订单 → 直接拉起官方确认页
 * 使用 uni.request 回调方式，避免 async/await 打破手势链
 */
const preCreateAndOpenBusinessView = (deviceId: string) => {
  busy.value = true;
  uni.showLoading({ title: '准备中...', mask: true });

  uni.request({
    url: API_CONFIG.baseUrl + '/payscore/pre-create',
    method: 'POST',
    header: {
      'Content-Type': 'application/json',
      'accessToken': getToken()
    },
    data: { deviceId },
    success: (apiRes: any) => {
      uni.hideLoading();

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

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

      logger.log('[支付分] 预创建成功, 直接拉起官方授权页');

      // 记录信息供轮询使用
      pollingDeviceId = deviceId;
      pollingOutOrderNo = data.outOrderNo;

      // 在 uni.request 的 success 回调中调用 openBusinessView
      // 这里是原生回调，仍处于用户手势上下文中
      wx.openBusinessView({
        businessType: 'wxpayScoreUse',
        extraData: {
          package: data.package,
        },
        success: () => {
          logger.log('[支付分] 从授权页返回，开始轮询确认状态');
          startPolling();
        },
        fail: (err: any) => {
          busy.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();
      busy.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') {
        clearPollTimer();
        uni.hideLoading();
        busy.value = false;
        logger.log('[支付分] 用户已确认，开门');
        doOpenDoor(pollingDeviceId);
        return;
      }

      if (attempts >= maxAttempts) {
        clearPollTimer();
        uni.hideLoading();
        busy.value = false;
        logger.log('[支付分] 轮询超时，用户取消或未确认');
      }
    } catch (e) {
      logger.error('[支付分] 轮询异常', e);
      if (attempts >= maxAttempts) {
        clearPollTimer();
        uni.hideLoading();
        busy.value = false;
      }
    }
  }, 1000);
};

const clearPollTimer = () => {
  if (pollTimer) {
    clearInterval(pollTimer);
    pollTimer = null;
  }
};

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

  scanDoor(deviceId).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.navigateTo({ url: '/pages/shopping/shopping' });
    }, 1000);
  }).catch((error: any) => {
    uni.hideLoading();
    logger.error('开门失败:', error);
  });
};

const goToMy = () => uni.navigateTo({ url: '/pages/my/my' })
const goToOrders = () => uni.navigateTo({ url: '/pages/orders/orders' })
const goToCouponCenter = () => uni.navigateTo({ url: '/pages/couponCenter/couponCenter' })
// TODO: 调试入口，上线前移除
// const goToOrderComplete = () => uni.navigateTo({ url: '/pages/orderComplete/orderComplete?orderNo=202607011423352789341668' })
const onContactSuccess = () => logger.log('[首页] 客服会话已打开')
</script>

<style lang="scss">
.container {
  min-height: 100vh;
  background: $color-bg-secondary;
  display: flex;
  flex-direction: column;
  padding: $spacing-xxl $spacing-lg;
  padding-bottom: calc(100rpx + constant(safe-area-inset-bottom));
  padding-bottom: calc(100rpx + env(safe-area-inset-bottom));
  box-sizing: border-box;
}

.brand-section {
  text-align: center;
  padding: $spacing-xxl 0 $spacing-xl;

  .brand-title {
    font-size: 56rpx;
    font-weight: 300;
    color: $color-text-primary;
    letter-spacing: 8rpx;
    display: block;
    margin-bottom: $spacing-sm;
  }

  .brand-slogan {
    font-size: 24rpx;
    color: $color-text-secondary;
    letter-spacing: 4rpx;
  }
}

/* ========== 操作区 ========== */
.action-section {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: $spacing-xl 0;
}

.scan-button {
  position: relative;
  width: 400rpx;
  height: 400rpx;
  min-width: 400rpx;
  max-width: 400rpx;
  min-height: 400rpx;
  max-height: 400rpx;
  border-radius: 50%;
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  overflow: hidden;
  box-sizing: border-box;
  flex-shrink: 0;

  &::after { border: none; }

  &[disabled] {
    opacity: 0.9;
  }

  &-inner {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: linear-gradient(135deg, $color-primary-light 0%, $color-primary 100%);
    box-shadow: $shadow-primary;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: all $duration-normal $ease-out;

    &:active {
      transform: scale(0.95);
      box-shadow: 0 4rpx 16rpx rgba(255, 193, 7, 0.3);
    }
  }

  &-ripple {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: $color-primary;
    transform: translate(-50%, -50%);
    animation: pulse 3s cubic-bezier(0.42, 0, 0.58, 1) infinite;
    opacity: 0.2;
    z-index: -1;
  }
}

.scan-icon {
  width: 160rpx;
  height: 160rpx;
  margin-bottom: $spacing-md;
  flex-shrink: 0;
  display: block;
}

.scan-text {
  font-size: 40rpx;
  font-weight: 600;
  color: $color-text-primary;
  letter-spacing: 4rpx;
}

/* ========== 快捷功能区 ========== */
.quick-actions {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: $spacing-xl;
  margin: $spacing-xxl 0;

  &-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: $spacing-md;
    position: relative;
    flex: 0 0 auto;

    &:active { opacity: 0.8; }
  }

  .action-icon {
    width: 120rpx;
    height: 120rpx;
    background: $color-bg-primary;
    border-radius: $radius-lg;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
    margin-bottom: $spacing-sm;
    border: 2rpx solid $color-border;
    flex-shrink: 0;

    image {
      width: 64rpx;
      height: 64rpx;
      display: block;
    }

    &:active {
      box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
      border-color: $color-primary-light;
    }
  }

  .action-label {
    font-size: 28rpx;
    color: $color-text-primary;
    font-weight: 500;
    text-align: center;
    display: block;
    width: auto;
  }
}

/* ========== 底部信息卡片 ========== */
.info-card {
  background: $color-bg-primary;
  border-radius: $radius-lg;
  padding: $spacing-lg;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
  margin-top: auto;
  width: 100%;
  box-sizing: border-box;

  .info-item {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: $spacing-sm 0;
    min-height: 60rpx;

    &:not(:last-child) {
      border-bottom: 1rpx solid $color-border;
      padding-bottom: $spacing-md;
      margin-bottom: $spacing-md;
    }
  }

  .info-icon {
    font-size: 28rpx;
    margin-right: $spacing-sm;
    flex-shrink: 0;
    line-height: 1;

    &.payscore-icon {
      width: 36rpx;
      height: 36rpx;
    }
  }

  .info-text {
    font-size: 24rpx;
    color: $color-text-secondary;
    line-height: 1.5;
    text-align: center;
  }
}
</style>
