<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import {
  createMohongOrder,
  fetchMohongProduct,
  queryMohongPayment,
  startMohongPayment,
  type MohongProduct,
} from '@/features/mohong/api/mohong'
import MohongCartPanel from '@/features/mohong/components/MohongCartPanel.vue'
import { useMohongCart } from '@/features/mohong/composables/useMohongCart'
import type { PaymentPayWay } from '@/features/orders/api/orders'
import { useOrderPaymentCashier } from '@/features/orders/composables/useOrderPaymentCashier'
import { useSessionStore } from '@/stores/session'
import { formatCent } from '@/shared/utils/money'
import { readError } from '@/shared/utils/error'

const route = useRoute()
const router = useRouter()
const session = useSessionStore()
const { addProduct, openCart, totalCount: cartCount } = useMohongCart()
const product = ref<MohongProduct | null>(null)
const loading = ref(true)
const quantity = ref(1)
const submitting = ref(false)
const activeImage = ref('')
const payWayDialogVisible = ref(false)
let payWayResolver: ((value: PaymentPayWay | null) => void) | null = null

const cashier = useOrderPaymentCashier({
  notifySuccess: msg => ElMessage.success(msg),
  notifyError: msg => ElMessage.error(msg),
  notifyInfo: msg => ElMessage.info(msg),
  notifyFallback: msg => ElMessage.warning(msg),
  paidMessage: '支付成功',
  pollIntervalMs: 3000,
  qrWidth: 240,
  queryPayment: queryMohongPayment,
})

const images = computed(() => {
  if (!product.value) return [] as string[]
  const list = [...(product.value.image_urls || [])]
  if (product.value.cover_url && !list.includes(product.value.cover_url)) {
    list.unshift(product.value.cover_url)
  }
  return list
})

const totalPrice = computed(() => {
  if (!product.value) return '0.0'
  return formatCent(product.value.price_cent * quantity.value)
})

const canBuy = computed(() => {
  if (!product.value) return false
  if (product.value.stock === 0) return false
  if (product.value.stock > 0 && quantity.value > product.value.stock) return false
  return true
})

const activePayWayLabel = computed(() => {
  const map: Record<string, string> = { WXZF: '微信', ZFBZF: '支付宝' }
  return map[cashier.activePayment.value?.pay_way || ''] || '微信/支付宝'
})

onMounted(loadProduct)

async function loadProduct() {
  loading.value = true
  try {
    product.value = await fetchMohongProduct(String(route.params.id))
    activeImage.value = images.value[0] || ''
  } catch (error) {
    ElMessage.error(readError(error, '商品不存在'))
  } finally {
    loading.value = false
  }
}

function selectPayWay(): Promise<PaymentPayWay | null> {
  payWayDialogVisible.value = true
  return new Promise(resolve => {
    payWayResolver = resolve
  })
}

function choosePayWay(payWay: PaymentPayWay) {
  payWayResolver?.(payWay)
  payWayResolver = null
  payWayDialogVisible.value = false
}

function handlePayWayDialogClosed() {
  payWayResolver?.(null)
  payWayResolver = null
}

async function ensureAuthReady() {
  if (!session.isLoggedIn) {
    router.push({ path: '/login', query: { redirect: route.fullPath } })
    return false
  }
  try {
    await session.loadMe()
  } catch {
    // ignore
  }
  if (session.realnameStatus !== 'verified') {
    router.push({ path: '/realname', query: { redirect: route.fullPath } })
    return false
  }
  return true
}

function handleAddCart() {
  if (!product.value) return
  if (!canBuy.value) {
    ElMessage.warning('库存不足')
    return
  }
  const result = addProduct(product.value, quantity.value)
  if (result.ok) {
    ElMessage.success(result.message)
  } else {
    ElMessage.warning(result.message)
  }
}

async function handleBuy() {
  if (!product.value || submitting.value) return
  if (!(await ensureAuthReady())) return
  if (!canBuy.value) {
    ElMessage.warning('库存不足')
    return
  }
  const payWay = await selectPayWay()
  if (!payWay) return

  submitting.value = true
  try {
    const order = await createMohongOrder(product.value.id, quantity.value)
    const payment = await startMohongPayment(order.id, payWay)
    if (payment.paid || payment.status === 'paid') {
      ElMessage.success('支付成功')
      await router.push(`/mohong/orders/${order.id}`)
      return
    }
    await cashier.openPaymentCashier(payment, async () => {
      await router.push(`/mohong/orders/${order.id}`)
    })
  } catch (error) {
    ElMessage.error(readError(error, '下单失败'))
  } finally {
    submitting.value = false
  }
}
</script>

<template>
  <section v-loading="loading" class="mohong-detail-page">
    <template v-if="product">
      <div class="detail-layout">
        <div class="gallery-panel">
          <div class="main-image">
            <img v-if="activeImage" :src="activeImage" :alt="product.title" />
            <div v-else class="empty-image">暂无图片</div>
          </div>
          <div v-if="images.length > 1" class="thumbs">
            <button
              v-for="(url, idx) in images"
              :key="idx"
              type="button"
              class="thumb"
              :class="{ active: url === activeImage }"
              @click="activeImage = url"
            >
              <img :src="url" :alt="`${product.title}-${idx + 1}`" />
            </button>
          </div>
        </div>

        <div class="info-panel">
          <p class="eyebrow">摸大红商品</p>
          <h1>{{ product.title }}</h1>
          <p class="desc">{{ product.description || '暂无说明' }}</p>

          <div class="price-box">
            <div>
              <small>售价</small>
              <strong>¥{{ product.price || formatCent(product.price_cent) }}</strong>
              <em>/ {{ product.unit || '份' }}</em>
            </div>
            <span v-if="product.original_price" class="origin">
              原价 ¥{{ product.original_price }}
            </span>
          </div>

          <div class="meta-rows">
            <div class="meta-row">
              <span>库存</span>
              <strong>
                <template v-if="product.stock < 0">充足</template>
                <template v-else>{{ product.stock }}</template>
              </strong>
            </div>
            <div class="meta-row">
              <span>数量</span>
              <el-input-number
                v-model="quantity"
                :min="1"
                :max="product.stock > 0 ? product.stock : 99"
              />
            </div>
            <div class="meta-row">
              <span>合计</span>
              <strong class="total">¥{{ totalPrice }}</strong>
            </div>
          </div>

          <div class="actions">
            <el-button size="large" class="btn-outline" :disabled="!canBuy" @click="handleAddCart">
              加入购物车
            </el-button>
            <el-button
              type="primary"
              size="large"
              color="#ff6a00"
              :loading="submitting"
              :disabled="!canBuy"
              @click="handleBuy"
            >
              {{ canBuy ? '立即购买' : '暂时缺货' }}
            </el-button>
            <el-button size="large" class="btn-outline" @click="openCart">
              购物车{{ cartCount > 0 ? `(${cartCount})` : '' }}
            </el-button>
            <el-button size="large" class="btn-outline" @click="router.push('/mohong')">
              返回列表
            </el-button>
          </div>

          <div class="tips">
            <p>购买须知</p>
            <ul>
              <li>下单需登录并完成实名认证</li>
              <li>可加入购物车多选，一起结账；支付后一键复制整单信息</li>
              <li>支付成功后可在订单详情扫码联系客服</li>
            </ul>
          </div>
        </div>
      </div>
    </template>
    <el-empty v-else-if="!loading" description="商品不存在" />

    <MohongCartPanel
      :select-pay-way="selectPayWay"
      :start-cashier="(payment, onPaid) => cashier.openPaymentCashier(payment, onPaid)"
    />

    <el-dialog
      v-model="payWayDialogVisible"
      title="选择支付方式"
      width="420px"
      append-to-body
      @closed="handlePayWayDialogClosed"
    >
      <p class="pay-way-tip">选择渠道后将生成对应的支付二维码</p>
      <div class="pay-way-options">
        <button type="button" class="pay-way-option wechat" @click="choosePayWay('WXZF')">
          <strong>微信支付</strong>
          <small>使用微信扫码完成支付</small>
        </button>
        <button type="button" class="pay-way-option alipay" @click="choosePayWay('ZFBZF')">
          <strong>支付宝支付</strong>
          <small>使用支付宝扫码完成支付</small>
        </button>
      </div>
    </el-dialog>

    <el-dialog
      v-model="cashier.paymentPopupVisible.value"
      title="订单支付"
      width="520px"
      append-to-body
      @closed="cashier.stopPaymentPolling"
    >
      <div v-if="cashier.activePayment.value" class="pay-dialog-body">
        <div class="pay-amount">
          支付金额
          <strong>¥{{ formatCent(cashier.activePayment.value.amount_cent) }}</strong>
        </div>
        <div v-if="cashier.payURL.value" class="pay-qr">
          <img
            v-if="cashier.paymentQRCodeURL.value"
            :src="cashier.paymentQRCodeURL.value"
            alt="支付二维码"
          />
          <p>请使用{{ activePayWayLabel }}扫码支付</p>
        </div>
        <p v-else class="pay-hint">支付单已创建，请完成付款后刷新状态。</p>
      </div>
      <template #footer>
        <el-button
          type="primary"
          :loading="cashier.checkingPayment.value"
          @click="cashier.refreshPaymentStatus(false)"
        >
          我已支付，刷新状态
        </el-button>
      </template>
    </el-dialog>
  </section>
</template>

<style scoped>
.mohong-detail-page {
  width: 100%;
}

.detail-layout {
  display: grid;
  /* 左图固定合理宽度，右侧信息铺满剩余空间，避免整页右侧大片空白 */
  grid-template-columns: minmax(320px, 420px) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  width: 100%;
}

.gallery-panel,
.info-panel {
  background: #fff;
  border: 1px solid #eef1f5;
  border-radius: 16px;
  padding: 18px;
  min-width: 0;
}

.main-image {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  background: #111;
}

.main-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.empty-image {
  display: flex;
  height: 100%;
  align-items: center;
  justify-content: center;
  color: #a0aec0;
}

.thumbs {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.thumb {
  width: 64px;
  height: 64px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  background: #f3f6fb;
  cursor: pointer;
}

.thumb.active {
  border-color: #ff6a00;
}

.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.eyebrow {
  margin: 0 0 8px;
  color: #ff6a00;
  font-size: 13px;
  font-weight: 700;
}

.info-panel h1 {
  margin: 0 0 12px;
  font-size: 28px;
  color: #17233d;
  line-height: 1.25;
}

.desc {
  margin: 0 0 18px;
  color: #6b7a90;
  font-size: 14px;
  line-height: 1.7;
  white-space: pre-wrap;
}

.price-box {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  padding: 16px;
  border-radius: 12px;
  background: #fff7ed;
}

.price-box small {
  display: block;
  color: #9a3412;
  font-size: 12px;
  margin-bottom: 4px;
}

.price-box strong {
  color: #ff6a00;
  font-size: 32px;
  font-weight: 900;
}

.price-box em {
  margin-left: 6px;
  color: #9a3412;
  font-style: normal;
  font-size: 14px;
}

.origin {
  color: #b0b8c4;
  text-decoration: line-through;
  font-size: 13px;
}

.meta-rows {
  display: grid;
  gap: 14px;
  margin-bottom: 20px;
}

.meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: #6b7a90;
  font-size: 14px;
}

.meta-row .total {
  color: #ff6a00;
  font-size: 22px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 20px;
}

.actions :deep(.el-button--primary) {
  --el-button-bg-color: #ff6a00;
  --el-button-border-color: #ff6a00;
  --el-button-hover-bg-color: #e55d00;
  --el-button-hover-border-color: #e55d00;
}

.actions :deep(.btn-outline) {
  --el-button-bg-color: #fff8f2;
  --el-button-border-color: rgba(255, 106, 0, 0.32);
  --el-button-text-color: #ff6a00;
  --el-button-hover-bg-color: #fff3e8;
  --el-button-hover-border-color: #ff6a00;
  --el-button-hover-text-color: #ff6a00;
}

.tips {
  padding-top: 16px;
  border-top: 1px solid #eef1f5;
  color: #6b7a90;
  font-size: 13px;
}

.tips p {
  margin: 0 0 8px;
  color: #17233d;
  font-weight: 700;
}

.tips ul {
  margin: 0;
  padding-left: 18px;
  line-height: 1.7;
}

.pay-way-tip {
  margin: 0 0 14px;
  color: #6b7a90;
  font-size: 13px;
}

.pay-way-options {
  display: grid;
  gap: 10px;
}

.pay-way-option {
  display: grid;
  gap: 4px;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid #e7edf6;
  border-radius: 12px;
  background: #fff;
  text-align: left;
  cursor: pointer;
}

.pay-way-option:hover {
  border-color: #ff6a00;
}

.pay-way-option strong {
  color: #17233d;
}

.pay-way-option small {
  color: #8a94a6;
}

.pay-dialog-body {
  display: grid;
  gap: 16px;
  justify-items: center;
  text-align: center;
}

.pay-amount {
  color: #6b7a90;
}

.pay-amount strong {
  display: block;
  margin-top: 6px;
  color: #ff6a00;
  font-size: 28px;
}

.pay-qr img {
  width: 220px;
  height: 220px;
  border-radius: 12px;
  background: #f7f9fc;
}

.pay-hint {
  color: #6b7a90;
}

@media (max-width: 960px) {
  .detail-layout {
    grid-template-columns: 1fr;
  }

  .gallery-panel {
    max-width: 420px;
  }
}
</style>
