<template>
  <!-- 确认支付页面：订单信息、菜品清单、价格明细、确认支付 -->
  <view class="content">
    <view class="card">
      <view class="card-header">
        <view class="tag"></view>
        <view class="card-header-title">订单信息</view>
      </view>
      <view class="card-content">
        <view class="info-item">
          <view class="info-item-label">就餐桌号</view>
          <view class="info-item-value">{{ orderInfo.tableNumber || orderInfo.tableId || '—' }}</view>
        </view>
        <view class="info-item info-item--diners">
          <view class="info-item-label">用餐人数</view>
          <view class="diner-stepper">
            <view
              class="diner-stepper__btn"
              :class="{ 'diner-stepper__btn--disabled': dinerCount <= 1 }"
              hover-class="diner-stepper__btn--active"
              @tap.stop="adjustDiners(-1)"
            >
              <view class="diner-stepper__icon diner-stepper__icon--minus" />
            </view>
            <text class="diner-stepper__value">{{ dinerCount }}</text>
            <view
              class="diner-stepper__btn"
              :class="{ 'diner-stepper__btn--disabled': dinerCount >= MAX_DINERS }"
              hover-class="diner-stepper__btn--active"
              @tap.stop="adjustDiners(1)"
            >
              <view class="diner-stepper__icon diner-stepper__icon--plus" />
            </view>
          </view>
        </view>
        <view class="info-item">
          <view class="info-item-label">联系电话</view>
          <view class="info-item-value">{{ orderInfo.contactPhone || '—' }}</view>
        </view>
        <view class="info-item">
          <view class="info-item-label">备注信息</view>
          <view class="info-item-value remark-text">{{ orderInfo.remark || '—' }}</view>
        </view>
      </view>
    </view>

    <view class="card" v-if="displayFoodList.length > 0">
      <view class="card-header">
        <view class="tag"></view>
        <view class="card-header-title">菜品清单</view>
      </view>
      <view class="card-content">
        <view class="info-food">
          <view v-for="(item, index) in displayFoodList" :key="item.id || index" class="food-item">
            <image :src="getItemImage(item)" mode="aspectFill" class="food-item__image"></image>
            <view class="food-item__info">
              <view class="food-item__name">{{ item.name }}</view>
              <view class="food-item__desc" v-if="item.tags && item.tags.length > 0">
                <text v-for="(tag, tagIndex) in item.tags" :key="tagIndex" class="food-item__tag"
                  :class="tag.type">{{ tag.text }}<text v-if="tagIndex < item.tags.length - 1">,</text>
                </text>
              </view>
            </view>
            <view class="food-item__right">
              <view class="food-item__price">
                <text class="price-main">¥{{ formatPrice(item.price) }}</text>
              </view>
              <view class="food-item__quantity">{{ item.quantity || 1 }}份</view>
            </view>
          </view>
        </view>
      </view>
    </view>

    <view class="card">
      <view class="card-header">
        <view class="tag"></view>
        <view class="card-header-title">价格明细</view>
      </view>
      <view class="card-content">
        <view class="info-item">
          <view class="info-item-label">菜品总价</view>
          <view class="info-item-value">¥{{ formatPrice(foodSubtotalForDisplay) }}</view>
        </view>
        <!-- 本版本不参与服务费
        <view class="info-item">
          <view class="info-item-label">服务费</view>
          <view class="info-item-value">¥{{ formatPrice(orderInfo.serviceFee ?? 0) }}</view>
        </view>
        -->
        <view class="info-item info-item--coupon info-item--clickable" @click="onCouponRowClick">
          <view class="info-item-label">优惠券</view>
          <view class="info-item-value coupon-value">
            <text v-if="(orderInfo.discountAmount ?? 0) > 0" class="coupon-amount">{{ couponDisplayText }}</text>
            <text v-else class="coupon-placeholder">请选择</text>
            <text class="coupon-arrow">›</text>
          </view>
        </view>
        <view v-if="(orderInfo.discountAmount ?? 0) > 0" class="info-item info-item--coupon">
          <view class="info-item-label">优惠金额</view>
          <view class="info-item-value coupon-value">
            <text class="coupon-amount">-¥{{ formatPrice(orderInfo.discountAmount) }}</text>
          </view>
        </view>
        <view class="price-line">
          <view class="price-line-label">应付金额</view>
          <view class="price-line-value">¥{{ formatPrice(orderInfo.payAmount ?? 0) }}</view>
        </view>
      </view>
    </view>

    <view class="bottom-button">
      <view class="bottom-button-text" hover-class="hover-active" @click="handleConfirmPay">确认支付 ¥{{ formatPrice(orderInfo.payAmount ?? 0) }}</view>
    </view>

    <!-- 选择优惠券弹窗 -->
    <view class="coupon-modal-wrapper">
      <SelectCouponModal
        v-model:open="couponModalOpen"
        :coupon-list="couponList"
        :selected-coupon-id="selectedCouponId"
        :view-only="false"
        @select="handleCouponSelect"
        @close="couponModalOpen = false"
      />
    </view>
  </view>
</template>

<script setup>
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app';
import { ref, computed } from 'vue';
import { go } from '@/utils/utils.js';
import { getFileUrl } from '@/utils/file.js';
import { useUserStore } from '@/store/user.js';
import * as diningApi from '@/api/dining.js';
import SelectCouponModal from '@/pages/orderFood/components/SelectCouponModal.vue';

const orderId = ref('');
/** 用餐人数上限（与选人数页「查看更多」一致） */
const MAX_DINERS = 16;
const MIN_DINERS = 1;

const orderInfo = ref({
  orderNo: '',
  storeId: '',
  tableId: '',
  tableNumber: '',
  diners: '',
  contactPhone: '',
  remark: '',
  totalAmount: 0,
  dishTotal: null,
  couponId: null,
  couponName: '',
  couponType: null,   // 1 满减 2 折扣
  discountRate: null, // 折扣券力度，如 5.5 表示 5.5折
  nominalValue: null, // 满减券面额
  discountAmount: 0,
  payAmount: 0,
  serviceFee: 0
});

const foodList = ref([]);

/** 服务费估算接口返回的 feeType；为 1 表示按人数计费，修改人数时需重新估算 */
const estimateFeeType = ref(null);

// 优惠券选择（结算页）
const couponModalOpen = ref(false);
const couponList = ref([]);
const selectedCouponId = ref(null);

// 菜品清单展示（排除特殊占位 id=-1）
const displayFoodList = computed(() =>
  (foodList.value ?? []).filter((it) => Number(it?.id ?? it?.cuisineId) !== -1)
);

function parseDinerCount(val) {
  const n = Number(val);
  if (!Number.isFinite(n) || n < MIN_DINERS) return MIN_DINERS;
  return Math.min(MAX_DINERS, Math.floor(n));
}

/** 当前用餐人数（数字，用于步进器展示） */
const dinerCount = computed(() => parseDinerCount(orderInfo.value.diners));

function adjustDiners(delta) {
  const cur = parseDinerCount(orderInfo.value.diners);
  const next = cur + delta;
  if (next < MIN_DINERS || next > MAX_DINERS) return;
  orderInfo.value.diners = String(next);
  uni.setStorageSync('currentDiners', String(next));
  // 本版本不参与服务费（恢复按人数重算时取消注释）
  // if (Number(estimateFeeType.value) === 1) {
  //   fetchServiceFeeEstimate().catch((err) => console.warn('按人数重算服务费失败:', err));
  // }
}

// 展示用菜品小计：有明细时与行成交价一致；否则用接口 dishTotal 或 totalAmount − 服务费
const foodSubtotalForDisplay = computed(() => {
  const list = displayFoodList.value;
  if (list.length > 0) {
    const sum = list.reduce((s, it) => s + (Number(it.lineSubtotal) || 0), 0);
    return Math.max(0, Math.round(sum * 100) / 100);
  }
  const dt = orderInfo.value.dishTotal;
  if (dt != null && dt !== '') {
    const d = Number(dt);
    if (!Number.isNaN(d)) return Math.max(0, d);
  }
  const total = Number(orderInfo.value.totalAmount) || 0;
  const fee = Number(orderInfo.value.serviceFee) || 0;
  return Math.max(0, total - fee);
});

// 优惠券展示：满减券显示 nominalValue+元，折扣券显示 discountRate+折，否则显示 couponName 或 已使用优惠券
const couponDisplayText = computed(() => {
  const o = orderInfo.value;
  if ((o.discountAmount ?? 0) <= 0) return '';
  const type = Number(o.couponType);
  if (type === 1 && (o.nominalValue != null && o.nominalValue !== '')) {
    const val = Number(o.nominalValue);
    return Number.isNaN(val) ? (o.couponName || '已使用优惠券') : val + '元';
  }
  if (type === 2 && (o.discountRate != null && o.discountRate !== '')) {
    const rate = Number(o.discountRate);
    return Number.isNaN(rate) ? (o.couponName || '已使用优惠券') : rate + '折';
  }
  return o.couponName || '已使用优惠券';
});

// 规范化优惠券项（供 SelectCouponModal 使用）
function normalizeCouponItem(item) {
  if (!item || typeof item !== 'object') return null;
  const raw = item;
  const couponType = Number(raw.couponType) || 0;
  const nominalValue = Number(raw.nominalValue ?? raw.amount ?? 0) || 0;
  const discountRate = ((Number(raw.discountRate) || 0) / 10) || 0;
  const minAmount = Number(raw.minimumSpendingAmount ?? raw.minAmount ?? 0) || 0;
  let amountDisplay = nominalValue + '元';
  if (couponType === 1) amountDisplay = nominalValue + '元';
  else if (couponType === 2 && discountRate > 0) amountDisplay = (discountRate % 1 === 0 ? discountRate : discountRate.toFixed(1)) + '折';
  return {
    id: raw.userCouponId ?? raw.id ?? raw.couponId ?? '',
    couponId: raw.couponId ?? raw.id ?? raw.userCouponId ?? '',
    amount: nominalValue,
    minAmount,
    name: raw.name ?? raw.title ?? raw.couponName ?? '',
    expireDate: raw.expirationTime ?? raw.endGetDate ?? raw.expireDate ?? '',
    couponType,
    discountRate,
    amountDisplay
  };
}

// 点击优惠券行：打开选择弹窗
const onCouponRowClick = () => {
  openCouponModal();
};

// 打开优惠券弹窗并拉取用户可用券
const openCouponModal = async () => {
  const storeId = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
  couponModalOpen.value = false;
  if (!storeId) {
    uni.showToast({ title: '暂无门店信息', icon: 'none' });
    return;
  }
  try {
    const res = await diningApi.GetUserOwnedCouponList({ storeId });
    const list = Array.isArray(res) ? res : (res?.data ?? res?.records ?? res?.list ?? []);
    const normalized = (Array.isArray(list) ? list : []).map(normalizeCouponItem).filter(Boolean);
    couponList.value = normalized;
    couponModalOpen.value = true;
  } catch (err) {
    console.error('获取优惠券失败:', err);
    uni.showToast({ title: '获取优惠券失败', icon: 'none' });
  }
};

// 选择优惠券后更新订单优惠与应付金额
const handleCouponSelect = ({ coupon, selectedId }) => {
  const hasSelected = selectedId != null && selectedId !== '';
  selectedCouponId.value = hasSelected ? String(selectedId) : null;
  orderInfo.value.couponId = hasSelected ? (coupon?.couponId ?? coupon?.id ?? selectedCouponId.value) : null;
  if (!hasSelected) {
    orderInfo.value.discountAmount = 0;
    orderInfo.value.couponName = '';
    orderInfo.value.couponType = null;
    orderInfo.value.discountRate = null;
    orderInfo.value.nominalValue = null;
  } else if (coupon) {
    orderInfo.value.couponName = coupon.name ?? '';
    orderInfo.value.couponType = Number(coupon.couponType) ?? null;
    orderInfo.value.discountRate = coupon.discountRate != null ? coupon.discountRate : null;
    orderInfo.value.nominalValue = coupon.amount != null ? coupon.amount : null;
    const food = foodSubtotalForDisplay.value;
    const fee = Number(orderInfo.value.serviceFee) || 0;
    const baseForDiscount = food + fee;
    const couponType = Number(coupon.couponType) || 0;
    if (couponType === 2 && coupon.discountRate != null && baseForDiscount > 0) {
      const rate = Number(coupon.discountRate) || 0;
      orderInfo.value.discountAmount = Math.round(baseForDiscount * (1 - rate / 10) * 100) / 100;
    } else {
      orderInfo.value.discountAmount = Number(coupon.amount) || 0;
    }
  }
  updateCheckoutPayAmount();
  couponModalOpen.value = false;
};

// 应付金额 = 菜品总价 + 服务费 − 优惠金额
const updateCheckoutPayAmount = () => {
  const food = Number(foodSubtotalForDisplay.value) || 0;
  const fee = Number(orderInfo.value.serviceFee) || 0;
  const discount = Number(orderInfo.value.discountAmount) || 0;
  orderInfo.value.payAmount = Math.max(0, Math.round((food + fee - discount) * 100) / 100);
};

/** 服务费变化后：折扣券（按菜品+服务费为基数）需重算优惠金额 */
function recalcDiscountAfterServiceFeeChange() {
  const ct = Number(orderInfo.value.couponType) || 0;
  if (ct !== 2 || orderInfo.value.discountRate == null || !orderInfo.value.couponId) return;
  const food = Number(foodSubtotalForDisplay.value) || 0;
  const fee = Number(orderInfo.value.serviceFee) || 0;
  const base = food + fee;
  const rate = Number(orderInfo.value.discountRate) || 0;
  if (base <= 0) return;
  orderInfo.value.discountAmount = Math.round(base * (1 - rate / 10) * 100) / 100;
}

/**
 * 从估算接口 data 解析 feeType：后端可能放在顶层，也可能在 items[].feeType（如按人数规则）
 * 任一为 1 则视为按人数计费，修改人数需重新请求 estimate
 */
function parseEstimateFeeType(res) {
  if (res == null || typeof res !== 'object') return null;
  const top = res.feeType != null && res.feeType !== '' ? Number(res.feeType) : NaN;
  if (top === 1) return 1;
  const items = Array.isArray(res.items) ? res.items : [];
  for (const it of items) {
    const ft = it?.feeType != null && it.feeType !== '' ? Number(it.feeType) : NaN;
    if (ft === 1) return 1;
  }
  if (!Number.isNaN(top)) return top;
  for (const it of items) {
    const ft = it?.feeType != null && it.feeType !== '' ? Number(it.feeType) : NaN;
    if (!Number.isNaN(ft)) return ft;
  }
  return null;
}

/**
 * 服务费估算（本版本关闭：不参与服务费）
 */
async function fetchServiceFeeEstimate() {
  orderInfo.value.serviceFee = 0;
  estimateFeeType.value = null;
  recalcDiscountAfterServiceFeeChange();
  updateCheckoutPayAmount();
  /* 原 /store/dining/service-fee/estimate 逻辑（恢复时整段移出注释）
  const storeId = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
  const tableId = getTableIdForServiceFeeEstimate();
  if (!storeId || !tableId) return;
  const dinerCount = parseDinerCount(orderInfo.value.diners);
  const goodsSubtotal = Math.max(0, Math.round((Number(foodSubtotalForDisplay.value) || 0) * 100) / 100);
  try {
    const res = await diningApi.GetServiceFeeEstimate({
      storeId: String(storeId),
      tableId,
      dinerCount,
      goodsSubtotal
    });
    estimateFeeType.value = parseEstimateFeeType(res);
    const fee =
      Number(
        res?.serviceFee ??
          res?.estimatedServiceFee ??
          res?.fee ??
          res?.amount ??
          (typeof res === 'number' ? res : 0)
      ) || 0;
    orderInfo.value.serviceFee = fee;
    recalcDiscountAfterServiceFeeChange();
    updateCheckoutPayAmount();
  } catch (e) {
    console.warn('结算页服务费估算失败:', e);
  }
  */
}

function formatPrice(price) {
  const num = Number(price);
  return Number.isNaN(num) ? '0.00' : num.toFixed(2);
}

// 取第一张图：逗号分隔取首段，数组取首项，对象取 url/path/src（与 orderDetail 一致）
function firstImage(val) {
  if (val == null || val === '') return '';
  if (Array.isArray(val)) {
    const first = val[0];
    if (first != null && first !== '') {
      if (typeof first === 'object' && first !== null) return first.url ?? first.path ?? first.src ?? first.link ?? '';
      return String(first).split(/[,，]/)[0].trim();
    }
    return '';
  }
  if (typeof val === 'object') return val.url ?? val.path ?? val.src ?? val.link ?? '';
  const str = String(val).trim();
  return str ? str.split(/[,，]/)[0].trim() : '';
}

function getItemImage(item) {
  const raw = item?.image ?? item?.cuisineImage ?? item?.imageUrl ?? item?.images ?? item?.pic ?? item?.cover ?? '';
  const url = firstImage(raw) || (typeof raw === 'string' ? raw.split(/[,，]/)[0]?.trim() : '');
  if (url && typeof url === 'string' && (url.startsWith('http') || url.startsWith('//'))) return url;
  return getFileUrl(url || 'img/icon/shop.png');
}

// 将 tags 统一为 [{ text, type }] 格式
function normalizeTags(raw) {
  if (raw == null) return [];
  let arr = [];
  if (Array.isArray(raw)) arr = raw;
  else if (typeof raw === 'string') {
    const t = raw.trim();
    if (t.startsWith('[')) { try { arr = JSON.parse(t); if (!Array.isArray(arr)) arr = []; } catch { arr = t ? [t] : []; } }
    else arr = t ? t.split(/[,，、\s]+/).map(s => s.trim()).filter(Boolean) : [];
  } else if (raw && typeof raw === 'object') arr = Array.isArray(raw.list) ? raw.list : Array.isArray(raw.items) ? raw.items : [];
  return arr.map((it) => {
    if (it == null) return { text: '', type: '' };
    if (typeof it === 'string') return { text: it, type: '' };
    if (typeof it === 'number') return { text: String(it), type: '' };
    return { text: it.text ?? it.tagName ?? it.name ?? it.label ?? it.title ?? '', type: it.type ?? it.tagType ?? '' };
  }).filter((t) => t.text !== '' && t.text != null);
}

// 接口订单项转列表项：图片取首张（逗号/数组/对象与 orderDetail 一致）
function normalizeOrderItem(item) {
  const rawTags = item?.tags ?? item?.tagList ?? item?.tagNames ?? item?.labels ?? item?.tag;
  const rawImg = item?.images ?? item?.image ?? item?.cuisineImage ?? item?.imageUrl ?? item?.pic ?? item?.cover ?? '';
  const imageUrl = firstImage(rawImg) || (typeof rawImg === 'string' ? rawImg.split(/[,，]/)[0]?.trim() : '') || 'img/icon/shop.png';
  const qty = Number(item?.quantity ?? 1) || 1;
  /** 行成交价小计（元）：与购物车/服务费估算 goodsSubtotal 一致 */
  let lineSubtotal = 0;
  if (item?.subtotalAmount != null && item.subtotalAmount !== '') {
    lineSubtotal = Number(item.subtotalAmount) || 0;
  } else if (item?.totalPrice != null && item.totalPrice !== '') {
    lineSubtotal = Number(item.totalPrice) || 0;
  } else {
    const unit = Number(item?.unitPrice ?? item?.price ?? 0) || 0;
    lineSubtotal = unit * qty;
  }
  const unitForDisplay =
    Number(item?.unitPrice ?? item?.price ?? 0) ||
    (qty > 0 ? lineSubtotal / qty : 0);
  return {
    id: item?.id ?? item?.cuisineId,
    name: item?.cuisineName ?? item?.name ?? '',
    price: unitForDisplay,
    lineSubtotal,
    image: imageUrl,
    quantity: qty,
    tags: normalizeTags(rawTags)
  };
}

/** 桌台主键：store_table.id，不可用桌号展示文案代替 */
function getTableIdForServiceFeeEstimate() {
  const t = orderInfo.value.tableId;
  if (t != null && String(t).trim() !== '') return String(t).trim();
  return String(uni.getStorageSync('currentTableId') || '').trim();
}

const fetchOrderDetail = async () => {
  const id = orderId.value || '';
  if (!id) return;
  try {
    const res = await diningApi.GetOrderInfo(id);
    const raw = res?.data ?? res ?? {};
    orderInfo.value.orderNo = raw?.orderNo ?? raw?.orderId ?? '';
    orderInfo.value.storeId = raw?.storeId ?? raw?.store_id ?? '';
    // tableId 须为门店桌台表主键（store_table.id），勿用 tableNumber（展示用桌号）冒充
    orderInfo.value.tableId =
      raw?.tableId ??
      raw?.storeTableId ??
      raw?.store_table_id ??
      raw?.diningTableId ??
      '';
    orderInfo.value.tableNumber = raw?.tableNumber ?? raw?.tableNo ?? '';
    const dc = raw?.dinerCount ?? raw?.diners ?? '';
    orderInfo.value.diners =
      dc !== '' && dc != null ? String(parseDinerCount(dc)) : String(MIN_DINERS);
    orderInfo.value.contactPhone = raw?.contactPhone ?? raw?.phone ?? '';
    orderInfo.value.remark = raw?.remark ?? '';
    const total = Number(raw?.totalAmount ?? raw?.orderAmount ?? raw?.foodAmount ?? 0) || 0;
    orderInfo.value.totalAmount = total;
    orderInfo.value.dishTotal = raw?.dishTotal != null ? Number(raw.dishTotal) : null;
    orderInfo.value.couponId = raw?.couponId ?? null;
    orderInfo.value.couponName = raw?.couponName ?? '';
    orderInfo.value.couponType = raw?.couponType ?? null;
    const rawRate = raw?.discountRate;
    orderInfo.value.discountRate = rawRate != null && rawRate !== '' ? (Number(rawRate) || 0) / 10 : null;
    orderInfo.value.nominalValue = raw?.nominalValue ?? null;
    orderInfo.value.discountAmount = Number(raw?.discountAmount ?? raw?.couponAmount ?? raw?.couponDiscount ?? 0) || 0;
    orderInfo.value.payAmount = Number(raw?.payAmount ?? raw?.totalAmount ?? raw?.totalPrice ?? 0) || 0;
    // 本版本不参与服务费：不从订单拉取服务费
    // orderInfo.value.serviceFee =
    //   Number(raw?.serviceFee ?? raw?.serviceCharge ?? raw?.tablewareFee ?? 0) || 0;
    orderInfo.value.serviceFee = 0;
    const list = raw?.orderItemList ?? raw?.orderItems ?? raw?.items ?? raw?.detailList ?? [];
    foodList.value = (Array.isArray(list) ? list : []).map(normalizeOrderItem);
    selectedCouponId.value = orderInfo.value.couponId != null && orderInfo.value.couponId !== '' ? String(orderInfo.value.couponId) : null;
    updateCheckoutPayAmount();
    await fetchServiceFeeEstimate(); // 本版为 no-op（不参与服务费）
  } catch (err) {
    console.error('获取订单详情失败:', err);
    uni.showToast({ title: '加载失败', icon: 'none' });
  }
};

const handleConfirmPay = async () => {
  const id = orderId.value || '';
  if (!id) {
    uni.showToast({ title: '缺少订单ID', icon: 'none' });
    return;
  }
  const userStore = useUserStore();
  const openid = userStore.getOpenId || '';
  if (!openid) {
    uni.showToast({ title: '请先登录', icon: 'none' });
    return;
  }
  const payAmountVal = Math.round((Number(orderInfo.value.payAmount ?? 0) || 0) * 100) / 100;
  if (payAmountVal <= 0) {
    uni.showToast({ title: '订单金额异常', icon: 'none' });
    return;
  }
  const orderNo = orderInfo.value.orderNo || '';
  if (!orderNo) {
    uni.showToast({ title: '缺少订单号', icon: 'none' });
    return;
  }
  const price = Math.round(payAmountVal * 100);
  uni.showLoading({ title: '拉起支付...' });
  try {
    const storeId = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
    const u = userStore.getUserInfo || {};
    const payerId = u.id ?? u.userId ?? u.user_id ?? '';
    const couponIdVal =
      orderInfo.value.couponId != null && orderInfo.value.couponId !== ''
        ? String(orderInfo.value.couponId)
        : selectedCouponId.value != null && selectedCouponId.value !== ''
          ? String(selectedCouponId.value)
          : '';
    const discountAmountVal = Number(orderInfo.value.discountAmount) || 0;
    // const serviceFeeVal = Math.round((Number(orderInfo.value.serviceFee ?? 0) || 0) * 100) / 100;
    const res = await diningApi.PostOrderPay({
      orderNo,
      payer: openid,
      price,
      subject: '订单支付',
      storeId: storeId || undefined,
      couponId: couponIdVal || undefined,
      payerId: payerId ? String(payerId) : undefined,
      discountAmount: discountAmountVal,
      payAmount: payAmountVal
      // serviceFee: serviceFeeVal // 本版本不参与服务费
    });
    uni.hideLoading();
    uni.requestPayment({
      provider: 'wxpay',
      timeStamp: res.timestamp,
      nonceStr: res.nonce,
      package: res.prepayId,
      signType: res.signType,
      paySign: res.sign,
      success: () => {
        uni.showToast({ title: '支付成功', icon: 'success' });
        const oid = orderId.value || '';
        if (oid) {
          diningApi.PostOrderSettlementUnlock({ orderId: oid }).catch((e) => console.warn('解锁订单失败:', e));
        }
        const payType = 'wechatPayPartnerMininProgram';
        // 查询支付结果需用 prePay 返回的 transactionId，与订单号 orderNo 可能不同
        const prePayTid =
          res?.transactionId ??
          res?.transaction_id ??
          res?.outTradeNo ??
          orderNo;
        const sid = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
        const q = [`id=${encodeURIComponent(oid)}`, `payType=${encodeURIComponent(payType)}`, `transactionId=${encodeURIComponent(String(prePayTid ?? ''))}`];
        if (sid) q.push(`storeId=${encodeURIComponent(sid)}`);
        setTimeout(() => go(`/pages/paymentSuccess/index?${q.join('&')}`), 1500);
      },
      fail: (err) => {
        const msg = err?.errMsg ?? err?.message ?? '支付失败';
        if (String(msg).includes('cancel')) {
          uni.showToast({ title: '已取消支付', icon: 'none' });
        } else {
          uni.showToast({ title: msg || '支付失败', icon: 'none' });
        }
      }
    });
  } catch (e) {
    uni.hideLoading();
    uni.showToast({ title: e?.message || '获取支付参数失败', icon: 'none' });
  }
};

onLoad(async (options) => {
  const id = options?.orderId ?? options?.id ?? '';
  orderId.value = id;
  if (options?.orderNo) orderInfo.value.orderNo = options.orderNo;
  if (options?.tableId) orderInfo.value.tableId = options.tableId;
  if (options?.tableNumber) orderInfo.value.tableNumber = options.tableNumber;
  if (options?.diners != null && options?.diners !== '') {
    orderInfo.value.diners = String(parseDinerCount(options.diners));
    uni.setStorageSync('currentDiners', orderInfo.value.diners);
  }
  if (options?.remark != null && options?.remark !== '') orderInfo.value.remark = decodeURIComponent(options.remark);
  if (options?.totalAmount != null && options?.totalAmount !== '') {
    orderInfo.value.payAmount = Number(options.totalAmount) || 0;
  }
  if (id) {
    await fetchOrderDetail();
  }
});

onShow(() => {
  const id = orderId.value || '';
  if (id) {
    diningApi.PostOrderSettlementLock({ orderId: id }).catch((e) => console.warn('锁定订单失败:', e));
  }
});

onUnload(() => {
  const id = orderId.value || '';
  if (id) {
    diningApi.PostOrderSettlementUnlock({ orderId: id }).catch((e) => console.warn('解锁订单失败:', e));
  }
});
</script>

<style lang="scss" scoped>
.content {
  padding: 0 30rpx 300rpx;
}

.card {
  background-color: #fff;
  border-radius: 24rpx;
  padding: 30rpx 0;
  margin-top: 20rpx;

  .card-header {
    display: flex;
    align-items: center;
    padding: 0 30rpx;
    height: 40rpx;
    position: relative;
    font-size: 27rpx;
    color: #151515;
    font-weight: bold;
  }

  .tag {
    width: 10rpx;
    height: 42rpx;
    background: linear-gradient(35deg, #FCB73F 0%, #FC733D 100%);
    border-radius: 0;
    position: absolute;
    left: 0;
    top: 0;
  }

  .card-content {
    padding: 0 30rpx;
  }

  .info-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 20rpx;
    font-size: 27rpx;

    .info-item-label {
      color: #666666;
    }

    .info-item-value {
      color: #151515;

      &.remark-text {
        flex: 1;
        text-align: right;
        word-break: break-all;
      }
    }

    &--coupon .coupon-value {
      display: flex;
      align-items: center;
      gap: 8rpx;
    }
    .coupon-amount {
      color: #E61F19;
    }
    .coupon-placeholder {
      color: #999999;
    }
    .coupon-arrow {
      color: #999;
      margin-left: 4rpx;
    }
    &--clickable {
      cursor: pointer;
    }

    &--diners {
      align-items: center;
    }
  }

  /* 用餐人数：胶囊步进器（与设计稿一致） */
  .diner-stepper {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    background: #f2f3f5;
    border-radius: 999rpx;
    padding: 3rpx 6rpx;
    min-width: 196rpx;
    box-sizing: border-box;
  }

  .diner-stepper__btn {
    width: 44rpx;
    height: 44rpx;
    border-radius: 50%;
    background: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.06);
  }

  .diner-stepper__btn--active:active {
    opacity: 0.88;
  }

  .diner-stepper__btn--disabled {
    opacity: 0.35;
    pointer-events: none;
  }

  .diner-stepper__value {
    flex: 1;
    text-align: center;
    font-size: 26rpx;
    font-weight: 500;
    color: #151515;
    line-height: 44rpx;
    min-width: 36rpx;
  }

  .diner-stepper__icon--minus {
    width: 20rpx;
    height: 2rpx;
    background: #c8c8c8;
    border-radius: 2rpx;
  }

  .diner-stepper__icon--plus {
    position: relative;
    width: 18rpx;
    height: 18rpx;
  }

  .diner-stepper__icon--plus::before,
  .diner-stepper__icon--plus::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    background: #fc743d;
    border-radius: 2rpx;
  }

  .diner-stepper__icon--plus::before {
    width: 18rpx;
    height: 2rpx;
    transform: translate(-50%, -50%);
  }

  .diner-stepper__icon--plus::after {
    width: 2rpx;
    height: 18rpx;
    transform: translate(-50%, -50%);
  }

  .price-line {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 24rpx;
    padding-top: 24rpx;
    border-top: 1rpx solid #f0f0f0;
    font-size: 28rpx;
    font-weight: bold;

    .price-line-label {
      color: #151515;
    }

    .price-line-value {
      color: #E61F19;
    }
  }

  .info-food {
    .food-item {
      display: flex;
      align-items: center;
      padding: 20rpx 0;
      border-bottom: 1rpx solid #f5f5f5;

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

      &__image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 12rpx;
        flex-shrink: 0;
        background: #f5f5f5;
      }

      &__info {
        flex: 1;
        margin-left: 24rpx;
        min-width: 0;
      }

      &__name {
        font-size: 28rpx;
        color: #151515;
        font-weight: 500;
      }

      &__desc {
        font-size: 22rpx;
        color: #999;
        margin-top: 6rpx;
      }

      &__tag {
        margin-right: 4rpx;
        &.signature {
          color: #FC793D;
        }
        &.spicy {
          color: #2E2E2E;
        }
      }

      &__right {
        flex-shrink: 0;
        text-align: right;
      }

      &__price .price-main {
        font-size: 28rpx;
        color: #151515;
        font-weight: 600;
      }

      &__quantity {
        font-size: 24rpx;
        color: #999;
        margin-top: 6rpx;
      }
    }
  }
}

.bottom-button {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 20rpx 30rpx;
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  background: #fff;
  box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);

  .bottom-button-text {
    height: 88rpx;
    line-height: 88rpx;
    text-align: center;
    background: linear-gradient(90deg, #FCB73F 0%, #FC733D 100%);
    color: #fff;
    font-size: 32rpx;
    font-weight: bold;
    border-radius: 44rpx;
  }

  .hover-active {
    opacity: 0.9;
  }
}

.coupon-modal-wrapper {
  position: relative;
  z-index: 99999;
  :deep(.uni-popup) {
    z-index: 99999 !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
  }
  :deep(.uni-popup__wrapper) {
    z-index: 99999 !important;
  }
  :deep(.select-coupon-modal__list) {
    padding-bottom: calc(60rpx + env(safe-area-inset-bottom));
  }
  :deep(.select-coupon-modal__empty) {
    margin-bottom: 60rpx;
  }
}
</style>
