<template>
  <section class="checkout-wrap max-w-full overflow-x-hidden min-w-0" v-if="!loading && product">
    <div class="mx-auto w-full max-w-[min(100%,760px)] mb-2 flex">
      <button type="button" class="ghost shrink-0 self-start w-auto px-3 py-1.5 text-sm sm:text-[15px]" @click="goBack">返回商品</button>
    </div>

    <div
      v-if="!orderResult"
      class="mx-auto w-full max-w-[min(100%,760px)] mb-3 flex flex-col gap-3"
    >
      <div class="min-w-0 w-full">
        <CheckoutProductSummary :product="product" />
      </div>
      <div class="min-w-0 w-full">
        <CheckoutOrderFormPanel
          :product="product"
          :form="form"
          :logged-in="loggedIn"
          :login-url="loginUrl"
          :submitting="submitting"
          :error="error"
          @submit="submitOrder"
        />
      </div>
    </div>

    <div
      v-if="orderResult && !confirmed && needPayChannel && isMengyaPendingPay"
      class="flex items-center gap-3 rounded-xl border border-white/40 bg-white/75 px-3 py-2.5 mb-4 max-w-lg mx-auto sm:max-w-none"
    >
      <img
        :src="product.coverUrl"
        :alt="product.name"
        class="w-12 h-12 sm:w-14 sm:h-14 shrink-0 object-cover rounded-lg border border-white/30"
      />
      <div class="min-w-0 flex-1 text-left">
        <p class="font-bold text-apptext text-[15px] sm:text-base leading-tight truncate m-0">{{ product.name }}</p>
        <p class="tag m-0 mt-0.5">应付 <span class="font-semibold text-accent2">¥ {{ paidAmountSnapshot.toFixed(2) }}</span></p>
      </div>
    </div>

    <section
      v-if="orderResult"
      class="max-w-full min-w-0 px-0"
      :class="showMengyaTimeoutCancelledOnly
        ? 'flex min-h-[min(58vh,calc(100dvh-15rem))] items-center justify-center text-center'
        : 'mt-4 text-left sm:text-center'"
    >
      <template v-if="showMengyaTimeoutCancelledOnly">
        <p
          class="text-[#d64848] m-0 font-semibold leading-snug max-w-xl mx-auto text-[clamp(1.2rem,4vw,1.85rem)] sm:text-[1.45rem] md:text-[1.7rem]"
          role="alert"
        >
          {{ confirmError }}
        </p>
      </template>
      <template v-else>
        <CheckoutOrderHeader
          :order-id="orderResult.orderId"
          :is-mengya-pending-pay="isMengyaPendingPay"
          :copy-hint="orderIdCopyHint"
          @copy-order-id="copyOrderId"
        />

        <CheckoutOrderDone
          v-if="confirmed"
          :delivered-codes="deliveredCodes"
          :is-manual-delivery="isManualDelivery"
        />

        <CheckoutAwaitingFulfillment
          v-else
          :order-result="orderResult"
          :need-pay-channel="needPayChannel"
          :is-mengya-pending-pay="isMengyaPendingPay"
          :paid-amount-snapshot="paidAmountSnapshot"
          :mengya-qr-urls="mengyaQrUrls"
          v-model:mengya-qr-index="mengyaQrIndex"
          v-model:show-order-token-qr="showOrderTokenQr"
          :show-payment-countdown="showPaymentCountdown"
          :payment-countdown-urgent="paymentCountdownUrgent"
          :payment-countdown-display="paymentCountdownDisplay"
          :payment-countdown-expired="paymentCountdownExpired"
          :confirming="confirming"
          :cancelling="cancelling"
          :confirm-button-label="confirmButtonLabel"
          :confirm-hint="confirmHint"
          :confirm-error="confirmError"
          @confirm="doConfirm"
          @cancel="doCancel"
        />
      </template>
    </section>
  </section>

  <section v-else-if="!loading">
    <h2>未找到该商品</h2>
    <p class="tag mt-2">该商品无法下单，请返回商店页。</p>
    <div class="flex gap-3 mt-[18px]">
      <button class="ghost" @click="goBack">返回商品</button>
    </div>
  </section>

  <section v-else>
    <div class="py-6 text-muted">加载中...</div>
  </section>
</template>

<script setup>
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { fetchProducts, createOrder, confirmOrder, cancelOrder } from '../shared/api'
import { authState, isLoggedIn, getLoginUrl } from '../shared/auth'
import { useClipboardFeedback } from './composables/useClipboardFeedback.js'
import { usePaymentCountdown } from './composables/usePaymentCountdown.js'
import { useMengyaPaymentPolling } from './composables/useMengyaPaymentPolling.js'
import CheckoutProductSummary from './components/CheckoutProductSummary.vue'
import CheckoutOrderFormPanel from './components/CheckoutOrderFormPanel.vue'
import CheckoutOrderHeader from './components/CheckoutOrderHeader.vue'
import CheckoutAwaitingFulfillment from './components/CheckoutAwaitingFulfillment.vue'
import CheckoutOrderDone from './components/CheckoutOrderDone.vue'

/** Shown alone when mengya poll reports cancelled (timeout). Keep in sync with onCancelled below. */
const MENGYA_PAYMENT_TIMEOUT_CANCEL_MSG = '订单未在时限内到账，已自动取消'

const route = useRoute()
const router = useRouter()
const product = ref(null)
const loading = ref(true)
const submitting = ref(false)
const error = ref('')
const orderResult = ref(null)
const confirmed = ref(false)
const confirming = ref(false)
const cancelling = ref(false)
const confirmError = ref('')
const deliveredCodes = ref([])
const paidAmountSnapshot = ref(0)
const showOrderTokenQr = ref(false)
const mengyaQrIndex = ref(0)

const { hint: orderIdCopyHint, copy: copyToClipboard, dispose: disposeClipboard } = useClipboardFeedback()
const copyOrderId = () => copyToClipboard(orderResult.value?.orderId)

const loggedIn = computed(() => isLoggedIn())
const loginUrl = computed(() => getLoginUrl())

const form = reactive({ note: '', contactPhone: '', contactEmail: '' })
const isManualDelivery = ref(false)

const getPayPrice = (p) => {
  if (!p) return 0
  if (p.price === 0) return 0
  if (p.discountPrice > 0 && p.discountPrice < p.price) return p.discountPrice
  return p.price
}

const unitPrice = computed(() => getPayPrice(product.value))

const needPayChannel = computed(() => paidAmountSnapshot.value > 0.0001)

const mengyaQrUrls = computed(() =>
  (orderResult.value?.paymentQrUrls || []).map((u) => (u || '').trim()).filter(Boolean)
)

const isMengyaPendingPay = computed(
  () =>
    orderResult.value?.paymentMethod === 'mengya' &&
    orderResult.value?.status === 'pending_payment'
)

const showMengyaTimeoutCancelledOnly = computed(
  () =>
    !!orderResult.value &&
    !confirmed.value &&
    confirmError.value === MENGYA_PAYMENT_TIMEOUT_CANCEL_MSG
)

async function finalizeOrderFromServer() {
  if (!orderResult.value?.orderId) return false
  try {
    const result = await confirmOrder(orderResult.value.orderId)
    deliveredCodes.value = result.deliveredCodes || []
    isManualDelivery.value = result.isManual || result.deliveryMode === 'manual'
    confirmed.value = true
    orderResult.value = { ...orderResult.value, ...result }
    stopPollingPayment()
    stopPaymentCountdown()
    return true
  } catch {
    return false
  }
}

const { stopPollingPayment } = useMengyaPaymentPolling(orderResult, {
  onCompleted: finalizeOrderFromServer,
  onCancelled: () => {
    confirmError.value = MENGYA_PAYMENT_TIMEOUT_CANCEL_MSG
  }
})

const {
  showPaymentCountdown,
  paymentCountdownDisplay,
  paymentCountdownExpired,
  paymentCountdownUrgent,
  stopPaymentCountdown
} = usePaymentCountdown(orderResult, isMengyaPendingPay)

const confirmButtonLabel = computed(() => {
  if (!needPayChannel.value) return '确认领取'
  return '刷新订单状态'
})

const confirmHint = computed(() => {
  if (!needPayChannel.value) return '点击确认以查看购买内容'
  return '到账后会自动完成；若未更新，可点击「刷新订单状态」。'
})

const goBack = () => router.push('/')

const submitOrder = async () => {
  if (!product.value) return
  error.value = ''
  submitting.value = true
  confirmError.value = ''
  orderResult.value = null
  confirmed.value = false
  deliveredCodes.value = []
  paidAmountSnapshot.value = unitPrice.value
  mengyaQrIndex.value = 0
  showOrderTokenQr.value = false
  orderIdCopyHint.value = ''
  stopPollingPayment()
  stopPaymentCountdown()
  disposeClipboard()
  try {
    const payload = {
      productId: product.value.id,
      quantity: 1,
      note: form.note || '',
      contactPhone: form.contactPhone || '',
      contactEmail: form.contactEmail || '',
      notifyEmail: authState.email || ''
    }
    const token = isLoggedIn() ? authState.token : null
    const response = await createOrder(payload, token)
    orderResult.value = response
    if (typeof response.paymentExpectedTotal === 'number') {
      paidAmountSnapshot.value = response.paymentExpectedTotal
    } else {
      paidAmountSnapshot.value = unitPrice.value
    }
  } catch (err) {
    error.value = err?.response?.data?.error || '下单失败，请稍候再试'
  } finally {
    submitting.value = false
  }
}

const doConfirm = async () => {
  if (!orderResult.value?.orderId) return
  confirmError.value = ''
  confirming.value = true
  try {
    const result = await confirmOrder(orderResult.value.orderId)
    deliveredCodes.value = result.deliveredCodes || []
    isManualDelivery.value = result.isManual || result.deliveryMode === 'manual'
    confirmed.value = true
    orderResult.value = { ...orderResult.value, ...result }
    stopPollingPayment()
    stopPaymentCountdown()
  } catch (err) {
    confirmError.value = err?.response?.data?.error || '确认失败，请重试'
  } finally {
    confirming.value = false
  }
}

const doCancel = async () => {
  if (!orderResult.value?.orderId) return
  if (!window.confirm('确认要取消这笔订单吗？')) return
  confirmError.value = ''
  cancelling.value = true
  try {
    await cancelOrder(orderResult.value.orderId)
    stopPollingPayment()
    stopPaymentCountdown()
    confirmError.value = '订单已取消'
    orderResult.value = { ...orderResult.value, status: 'cancelled' }
  } catch (err) {
    confirmError.value = err?.response?.data?.error || '取消失败，请稍候再试'
  } finally {
    cancelling.value = false
  }
}

onUnmounted(() => {
  disposeClipboard()
  stopPollingPayment()
  stopPaymentCountdown()
})

onMounted(async () => {
  try {
    const list = await fetchProducts()
    product.value = list.find((item) => item.id === route.params.id) || null
  } finally {
    loading.value = false
  }
})
</script>
