<template>
  <view class="hotel-customer-theme pay-page">
    <!-- 加载中 -->
    <view v-if="loading" class="pay-loading">
      <text>加载中...</text>
    </view>

    <!-- 金额展示 -->
    <view v-else class="pay-hero">
      <text class="pay-label">支付金额</text>
      <view class="pay-amount">
        <text class="pay-yen">¥</text>
        <text class="pay-num">{{ amount }}</text>
      </view>
      <text class="pay-desc">客房送餐服务</text>
    </view>

    <!-- 倒计时 -->
    <view v-if="!loading && remainSeconds > 0" class="pay-countdown">
      <text class="pc-label">请在</text>
      <text class="pc-time">{{ countdownText }}</text>
      <text class="pc-label">内完成支付，超时订单将自动取消</text>
    </view>
    <view v-else-if="!loading && remainSeconds <= 0" class="pay-countdown pay-countdown--expired">
      <text class="pc-label">订单已超时，请重新下单</text>
    </view>

    <!-- 订单信息 -->
    <view v-if="!loading && orderId" class="pay-info-card">
      <view class="pi-line">
        <text class="pi-label">订单编号</text>
        <text class="pi-value">{{ orderNo }}</text>
      </view>
      <view class="pi-line">
        <text class="pi-label">送至</text>
        <text class="pi-value">{{ roomNo }}</text>
      </view>
    </view>

    <!-- 支付按钮 -->
    <view
      v-if="!loading && remainSeconds > 0 && !paying && !paySuccess"
      class="pay-btn"
      @click="doPay"
    >立即支付 ¥{{ amount }}</view>
    <view v-else-if="!loading && paying" class="pay-btn pay-btn--disabled">支付中...</view>
    <view v-else-if="!loading && paySuccess" class="pay-btn pay-btn--success">支付成功 ✓</view>
    <view v-else-if="!loading" class="pay-btn pay-btn--disabled">订单已超时</view>

    <!-- 返回修改 -->
    <view v-if="!loading && !paying && !paySuccess" class="pay-back" @click="goBack">← 返回修改</view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useHotelOrderStore } from '@/store'
import api from '@/api'

const orderStore = useHotelOrderStore()

const orderId = ref('')
const orderNo = ref('')
const roomNo = ref('')
const amount = ref('0.00')
const paying = ref(false)
const paySuccess = ref(false)
const remainSeconds = ref(900) // 15分钟 = 900秒
const loading = ref(true)
let countdownTimer = null
let pollTimer = null

// 支付环境自动识别（paySource 用于 doPay 判断支付渠道）
const paySource = ref('MOCK')

onMounted(() => {
  const pages = getCurrentPages()
  const currentPage = pages[pages.length - 1]
  const options = currentPage?.$page?.options || currentPage?.options || {}
  orderId.value = options.orderId || ''
  const tenantId = orderStore.tenantId

  // 从后端查询订单详情，获取真实金额和订单信息
  if (orderId.value && tenantId) {
    api.hotelOrderDetail(orderId.value, tenantId).then(function(res) {
      var data = res?.data || res
      if (data) {
        orderNo.value = data.orderNo || ''
        roomNo.value = data.roomNo || orderStore.roomInfo?.roomNo || ''
        amount.value = data.totalAmount ? String(data.totalAmount) : '0.00'
        // 如果订单已支付成功（从支付宝返回后重新进入），直接跳转
        if (data.payStatus === 1) {
          loading.value = false
          paySuccess.value = true
          stopCountdown()
          uni.showToast({ title: '支付成功', icon: 'success' })
          setTimeout(function() {
            uni.redirectTo({
              url: '/pages/hotel/customer/order-status?orderId=' + orderId.value,
            })
          }, 1200)
          return
        }
        // 根据后端返回的支付截止时间计算剩余秒数
        if (data.payExpireTime) {
          var expireTime = new Date(data.payExpireTime).getTime()
          var now = Date.now()
          var diff = Math.floor((expireTime - now) / 1000)
          remainSeconds.value = diff > 0 ? diff : 0
        }
      }
      loading.value = false
      startCountdown()
      // 订单未支付时，自动启动轮询检测支付状态（用于从支付宝返回后的场景）
      startPayPolling()
    }).catch(function() {
      loading.value = false
      uni.showToast({ title: '加载订单信息失败', icon: 'none' })
    })
  } else {
    loading.value = false
  }

  // 自动识别支付环境
  // #ifdef MP-WEIXIN
  paySource.value = 'WECHAT'
  // #endif
  // #ifdef MP-ALIPAY
  paySource.value = 'ALIPAY'
  // #endif
  // #ifdef H5
  const ua = navigator.userAgent.toLowerCase()
  if (ua.includes('micromessenger')) {
    paySource.value = 'WECHAT'
  } else {
    paySource.value = 'ALIPAY'
  }
  // #endif

  startCountdown()
})

onUnmounted(() => {
  stopCountdown()
  stopPolling()
})

/** 启动倒计时 */
function startCountdown() {
  stopCountdown()
  countdownTimer = setInterval(() => {
    if (remainSeconds.value > 0) {
      remainSeconds.value--
    } else {
      stopCountdown()
    }
  }, 1000)
}

function stopCountdown() {
  if (countdownTimer) {
    clearInterval(countdownTimer)
    countdownTimer = null
  }
}

function stopPolling() {
  if (pollTimer) {
    clearTimeout(pollTimer)
    pollTimer = null
  }
}

/** 倒计时格式化 */
const countdownText = computed(() => {
  const m = Math.floor(remainSeconds.value / 60)
  const s = remainSeconds.value % 60
  return String(m).padStart(2, '0') + ':' + String(s).padStart(2, '0')
})

/** 执行支付 */
async function doPay() {
  if (paying.value || paySuccess.value) return
  if (remainSeconds.value <= 0) {
    uni.showToast({ title: '订单已超时', icon: 'none' })
    return
  }

  paying.value = true

  try {
    var tenantId = orderStore.tenantId

    // 先调用后端创建支付流水，获取 tradeNo
    var createRes = await api.hotelPayCreate(orderId.value, tenantId, paySource.value)
    var createData = createRes?.data || createRes

    if (!createData) {
      paying.value = false
      uni.showToast({ title: '创建支付失败', icon: 'none' })
      return
    }

    // 根据支付渠道拉起支付
    if (paySource.value === 'ALIPAY' && createData.payForm) {
      // 支付宝 H5 手机网站支付：后端返回 payForm（HTML 表单），渲染后自动提交跳转支付宝收银台
      // #ifdef H5
      var payContainer = document.getElementById('alipay-pay-form')
      if (!payContainer) {
        payContainer = document.createElement('div')
        payContainer.id = 'alipay-pay-form'
        payContainer.style.display = 'none'
        document.body.appendChild(payContainer)
      }
      payContainer.innerHTML = createData.payForm
      var form = payContainer.querySelector('form')
      if (form) {
        form.submit()
      } else {
        paying.value = false
        uni.showToast({ title: '支付表单异常', icon: 'none' })
      }
      // 提交后页面会跳转到支付宝收银台，用户支付完成后通过 return-url 返回
      // 同时启动轮询，用户返回后自动检测支付状态
      startPayPolling()
      // #endif
      // #ifdef MP-ALIPAY
      // 支付宝小程序：调用 my.tradePay 拉起收银台
      my.tradePay({
        tradeNO: createData.tradeNo,
        success: function(res) {
          startPayPolling()
        },
        fail: function(err) {
          paying.value = false
          uni.showToast({ title: '支付取消或失败', icon: 'none' })
        }
      })
      // #endif
    } else if (paySource.value === 'ALIPAY' && createData.tradeNo) {
      // 支付宝小程序环境：有 tradeNo 无 payForm，用 my.tradePay
      // #ifdef MP-ALIPAY
      my.tradePay({
        tradeNO: createData.tradeNo,
        success: function(res) {
          startPayPolling()
        },
        fail: function(err) {
          paying.value = false
          uni.showToast({ title: '支付取消或失败', icon: 'none' })
        }
      })
      // #endif
      // #ifdef H5
      // H5 环境不应只有 tradeNo，启动轮询兜底
      startPayPolling()
      // #endif
    } else {
      // MOCK 模式：直接调用模拟支付（开发调试用）
      var mockRes = await api.hotelPayMockSuccess(orderId.value, tenantId)
      var mockData = mockRes?.data || mockRes

      if (mockData && mockData.payStatus === 1) {
        paySuccess.value = true
        stopCountdown()
        uni.showToast({ title: '支付成功', icon: 'success' })
        setTimeout(function() {
          uni.redirectTo({
            url: '/pages/hotel/customer/order-status?orderId=' + orderId.value,
          })
        }, 1200)
      } else {
        paying.value = false
        uni.showToast({ title: '支付失败，请重试', icon: 'none' })
      }
    }
  } catch (err) {
    paying.value = false
    uni.showToast({ title: err?.message || '支付失败', icon: 'none' })
  }
}

/** 支付后轮询后端查询真实支付状态 */
function startPayPolling() {
  stopPolling()
  var pollCount = 0
  var maxPoll = 60 // 最多轮询60次，每次2秒，共120秒
  // 延迟3秒后开始第一次轮询，给支付宝异步回调留出处理时间
  pollTimer = setTimeout(function poll() {
    pollCount++
    api.hotelPayStatus(orderId.value, orderStore.tenantId).then(function(res) {
      var data = res?.data || res
      if (data && data.payStatus === 1) {
        // 支付成功
        stopPolling()
        paySuccess.value = true
        paying.value = false
        stopCountdown()
        uni.showToast({ title: '支付成功', icon: 'success' })
        setTimeout(function() {
          uni.redirectTo({
            url: '/pages/hotel/customer/order-status?orderId=' + orderId.value,
          })
        }, 1200)
      } else if (pollCount >= maxPoll) {
        // 轮询超时，主动查询支付宝侧订单状态（底机制）
        stopPolling()
        paying.value = false
        queryAlipayTradeStatus()
      } else {
        // 未支付，继续轮询
        pollTimer = setTimeout(poll, 2000)
      }
    }).catch(function() {
      // 静默失败，继续轮询
      if (pollCount < maxPoll) {
        pollTimer = setTimeout(poll, 2000)
      } else {
        // 轮询超时且请求失败，也尝试主动查询支付宝
        stopPolling()
        paying.value = false
        queryAlipayTradeStatus()
      }
    })
  }, pollCount === 0 ? 3000 : 2000)
}

/** 轮询超时后，主动查询支付宝侧订单状态（底机制） */
function queryAlipayTradeStatus() {
  uni.showLoading({ title: '正在确认支付结果...' })
  api.hotelPayAlipayQuery(orderStore.tenantId, orderId.value).then(function(res) {
    uni.hideLoading()
    var data = res?.data || res
    if (data && data.payStatus === 1) {
      // 支付宝侧已支付，补偿成功
      paySuccess.value = true
      paying.value = false
      stopCountdown()
      uni.showToast({ title: '支付成功', icon: 'success' })
      setTimeout(function() {
        uni.redirectTo({
          url: '/pages/hotel/customer/order-status?orderId=' + orderId.value,
        })
      }, 1200)
    } else {
      // 支付宝侧也未支付
      uni.showModal({
        title: '支付结果未知',
        content: '暂时无法确认支付状态，请稍后在订单列表中查看。如已扣款请联系客服。',
        showCancel: false
      })
    }
  }).catch(function() {
    uni.hideLoading()
    uni.showModal({
      title: '查询失败',
      content: '网络异常，请稍后在订单列表中查看支付结果。',
      showCancel: false
    })
  })
}

function goBack() {
  // 购物车已清空，返回菜单页重新点餐
  uni.redirectTo({ url: '/pages/hotel/customer/menu' })
}
</script>

<style lang="scss" scoped>
.pay-page {
  min-height: 100vh;
  background: var(--h-bg, #F7F7F7);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 28rpx;
}

/* 加载中 */
.pay-loading {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400rpx;
  color: var(--h-txt-light, #999);
  font-size: 28rpx;
}

/* 金额区 */
.pay-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 60rpx 0 32rpx;
}

.pay-label {
  font-size: 26rpx;
  color: var(--h-txt-sub, #666);
  margin-bottom: 16rpx;
}

.pay-amount {
  display: flex;
  align-items: baseline;
  margin-bottom: 12rpx;
}

.pay-yen {
  font-size: 48rpx;
  font-weight: 700;
  color: var(--h-pri, #2D5016);
}

.pay-num {
  font-size: 88rpx;
  font-weight: 800;
  color: var(--h-pri, #2D5016);
  line-height: 1;
}

.pay-desc {
  font-size: 24rpx;
  color: var(--h-txt-light, #999);
}

/* 倒计时 */
.pay-countdown {
  display: flex;
  align-items: center;
  gap: 8rpx;
  padding: 16rpx 32rpx;
  background: #FFF7ED;
  border-radius: 40rpx;
  margin-bottom: 24rpx;
  border: 1rpx solid #FED7AA;
}

.pay-countdown--expired {
  background: #FEF2F2;
  border-color: #FECACA;
}

.pc-label {
  font-size: 22rpx;
  color: var(--h-txt-sub, #666);
}

.pc-time {
  font-size: 28rpx;
  font-weight: 700;
  color: var(--h-warn, #D97706);
  font-variant-numeric: tabular-nums;
}

/* 订单信息 */
.pay-info-card {
  width: 100%;
  background: #fff;
  border-radius: var(--h-rad, 20rpx);
  padding: 24rpx 28rpx;
  margin-bottom: 32rpx;
  box-shadow: var(--h-shd, 0 2rpx 8rpx rgba(0, 0, 0, 0.04));
}

.pi-line {
  display: flex;
  justify-content: space-between;
  padding: 8rpx 0;
  font-size: 26rpx;
}

.pi-label {
  color: var(--h-txt-light, #999);
}

.pi-value {
  color: var(--h-txt, #1A1A1A);
  font-weight: 500;
}

/* 支付按钮 */
.pay-btn {
  width: 100%;
  box-sizing: border-box;
  padding: 28rpx;
  border-radius: 48rpx;
  background: #07C160;
  color: #fff;
  font-size: 32rpx;
  font-weight: 700;
  text-align: center;
  box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.3);
  margin-top: 8rpx;
}

.pay-btn:active {
  opacity: 0.85;
}

.pay-btn--disabled {
  opacity: 0.6;
  background: #9CA3AF;
  box-shadow: none;
}

.pay-btn--success {
  background: #16A34A;
  box-shadow: 0 8rpx 24rpx rgba(22, 163, 74, 0.3);
}

.pay-back {
  margin-top: 32rpx;
  font-size: 24rpx;
  color: var(--h-txt-light, #999);
  padding: 16rpx;
}
</style>
