<script setup lang="ts">
import { useConfigStore, useUserStore } from "@/store";
import { dayjs } from "@/plugin/index";
import Config from '@/config/index'
import ChooseImage from '@/components/choose-image/choose-image.vue'
import CheckoutSkeleton from "./components/checkout-skeleton.vue";
import ChangePhone from "./components/change-phone.vue";
import PriceDetail from "./components/price-detail.vue";
import VisitMethod from "@/components/visit-method/index.vue";
import {ref} from "vue";
import {
  appMerchantCartListByMerchantIdPost,
  appMerchantCartCalculateSavingsPost,
  appMerchantDetailMerchantIdGet,
  appUserAddressListPost,
  type MerchantCartVo,
  type MerchantVo,
  appMerchantOrderCalculatePriceCartPost,
  appUserCardSelectDefaultPost, appMerchantOrderCreateOrderCartPost, appMerchantOrderPayOrderPost,
  appMerchantOrderCreateOrderCartBatchPost,
  appMerchantOrderCalculatePriceCartBatchPost,
  appMerchantCartListMerchantPost,
  appMerchantOrderPayOrderBatchPost,
  appMerchantOrderZipPayVoucherPost
} from "@/service";
import useEventEmit from "@/hooks/useEventEmit";
import {EventEnum} from "@/constant/enums";
import { getDistanceInMiles, parseMerchantCartPayload } from "@/utils/utils";
import {
  buildReservationTimeUrl,
  buildDayAppointmentSlot,
  findNearestDeliveryScheduleDate,
  loadCheckoutMerchantAppointments,
  type MerchantAppointmentSlot,
} from "@/utils/deliverySchedule";
const { t } = useI18n();
const configStore = useConfigStore();
const userStore = useUserStore();

const appDisplayName = computed(() => {
  const name = String((Config as any)?.appName ?? "").trim();
  return name || "CHEFLINK";
});

// 送达偏好
const visitMethodRef = ref();
// value 与 visit-method 组件保持一致：0-亲自送达 1-放门口
const visitMethod = ref({
  value: 1,
  label: t("components.visit.putItAtTheDoor"),
});
function chooseVisitMethod() {
  visitMethodRef.value?.onOpen(visitMethod.value.value);
}
function handleVisitMethodConfirm(data: { value: number; label: string }) {
  visitMethod.value = data;
}

// 联系方式(这里默认值取用户信息的手机号区号)
const contact = ref({
  phone: userStore.userInfo.phone,
  areaCode: "+1",
});
const changePhoneRef = ref<InstanceType<typeof ChangePhone>>();
function openChangePhone() {
  if (changePhoneRef.value) {
    changePhoneRef.value.onOpen(contact.value);
  }
}
function confirmPhone(data: { phone: string; areaCode: string }) {
  contact.value = data;
  formData.value.phone = data.phone;
}

// 配送时间 1 即刻配送 2 预约配送
// 当前业务仅支持预约配送，默认值设置为 2
const deliveryTimeType = ref(2);
// 配送时间配置
const deliveryMinutes = ref(0); // 预计送达时间（分钟）
// 自取时间配置
const selfPickupMinutes = ref(0); // 自取时间（分钟）
const deliveryWindowMinutes = ref(30); // 配送时间窗口（分钟）
// 预约配送日期配送
const userSelectedDeliveryTimeDate = ref(null);
// 预约自取时间
const userSelectedSelfPickupTimeDate = ref(null);
// 显示用的配送时间(即刻配送=当前时间加预计时间)(预约配送=预约时间+预计时间分钟)
const showDeliveryTime = computed(() => {
  // 配送
  if (deliveryTimeType.value === 1) {
    // 即刻配送：当前时间 + 预计送达时间
    let time = 0
    if(deliveryMethod.value === 0) {
      time = deliveryMinutes.value
    } else {
      time = selfPickupMinutes.value
    }
    const deliveryStart = dayjs().add(Number(time), "minute");
    const deliveryEnd = deliveryStart.add(
        deliveryWindowMinutes.value,
        "minute"
    );

    return `${deliveryStart.format("HH:mm")}-${deliveryEnd.format("HH:mm")}`;
  }
  if (deliveryTimeType.value === 2) {
    return deliveryMethod.value === 0 ? userSelectedDeliveryTimeDate : '123';
  }
  return "";
});
const merchantAppointmentMap = ref<Record<string, MerchantAppointmentSlot>>({});
const merchantAppointmentDisplay = ref<Record<string, string>>({});
const selectingMerchantId = ref<string | null>(null);

function ensureDefaultMerchantAppointment(merchant: {
  id?: string | number;
  deliveryScheduleTimes?: string;
}) {
  const key = String(merchant.id ?? "");
  if (!key || merchantAppointmentMap.value[key]?.startTime) return;

  const nearest = findNearestDeliveryScheduleDate(
    merchant.deliveryScheduleTimes
  );
  if (!nearest) return;

  const slot = buildDayAppointmentSlot(nearest);
  merchantAppointmentMap.value[key] = slot;
  syncAppointmentDisplay(key, { date: nearest, timeSlot: "" });
}

function syncAppointmentDisplay(merchantId: string, data: any) {
  const label =
    dayjs(data.date).format("MM-DD") +
    (data.timeSlot ? ` ${data.timeSlot}` : "");
  merchantAppointmentDisplay.value[merchantId] = label;
  if (deliveryMethod.value === 0) {
    userSelectedDeliveryTimeDate.value = label;
  } else {
    userSelectedSelfPickupTimeDate.value = label;
  }
}

async function openReservationForMerchant(merchant: {
  id?: string | number;
  businessHours?: string;
  deliveryScheduleTimes?: string;
}) {
  if (!merchant?.id) return;
  selectingMerchantId.value = String(merchant.id);
  let schedule = merchant.deliveryScheduleTimes;
  let hours = merchant.businessHours;
  if (!schedule || !hours) {
    try {
      const res: any = await appMerchantDetailMerchantIdGet({
        params: { merchantId: merchant.id as any },
      });
      schedule = res.data?.deliveryScheduleTimes ?? schedule;
      hours = res.data?.businessHours ?? hours;
      const mid = String(merchant.id);
      const found = cartDataList.value.find(
        (m: any) => String(m.id) === mid
      ) as any;
      if (found) {
        found.deliveryScheduleTimes = schedule;
        found.businessHours = hours;
      }
      if (String(storeId.value) === mid) {
        storeDetail.value = {
          ...storeDetail.value,
          deliveryScheduleTimes: schedule,
          businessHours: hours,
        } as MerchantVo;
      }
    } catch {
      /* ignore */
    }
  }
  uni.navigateTo({
    url: buildReservationTimeUrl({
      merchantId: merchant.id,
      deliveryScheduleTimes: schedule,
      businessHours: hours,
    }),
  });
}

// 切换配送时间点击事件（目前仅支持预约配送）
function toggleDeliveryTimeType(
  _type: number,
  merchant?: { id?: string | number; businessHours?: string; deliveryScheduleTimes?: string }
) {
  deliveryTimeType.value = 2;
  if (orderType.value === "batch" && merchant) {
    void openReservationForMerchant(merchant);
    return;
  }
  void openReservationForMerchant({
    id: storeId.value,
    businessHours: (storeDetail.value as any)?.businessHours,
    deliveryScheduleTimes: storeDetail.value?.deliveryScheduleTimes,
  });
}

function getMerchantPillText(merchantId: string | number) {
  const key = String(merchantId);
  if (merchantAppointmentDisplay.value[key]) {
    return `${merchantAppointmentDisplay.value[key]} >`;
  }
  const ap = merchantAppointmentMap.value[key];
  if (ap?.startTime) {
    const d = dayjs(Number(ap.startTime));
    if (d.isValid()) {
      return `${d.format("dddd")}, ${d.format("MM/DD")} >`;
    }
  }
  return t("pages-store.checkout.chooseTime");
}

const diyTime = ref<MerchantAppointmentSlot | Record<string, never>>({});
useEventEmit(EventEnum.CHOOSE_APPOINTMENT_TIME, (data: any) => {
  if (!data?.startTime || !data?.endTime) return;
  const merchantId = String(
    data.merchantId || selectingMerchantId.value || storeId.value || ""
  );
  if (!merchantId) return;

  merchantAppointmentMap.value[merchantId] = {
    date: data.date,
    timeSlot: data.timeSlot,
    startTime: data.startTime,
    endTime: data.endTime,
  };
  diyTime.value = merchantAppointmentMap.value[merchantId];
  deliveryTimeType.value = 2;
  syncAppointmentDisplay(merchantId, data);
  selectingMerchantId.value = null;
});

// 设置配送时间（分钟）
const setDeliveryMinutes = (minutes: number) => {
  deliveryMinutes.value = minutes;
};

// 设置配送时间窗口（分钟）
const setDeliveryWindowMinutes = (minutes: number) => {
  deliveryWindowMinutes.value = minutes;
};

const deliveryMethod = ref(0);
// 配送方式
const showDeliverySwitch = ref(false)
const deliveryMethodOptions = [
  t("pages-store.store.delivery"),
  t("pages-store.store.pickup"),
];
function handleClickSegmented(index: number) {
  console.log("切换配送方式:", index);
  if(+storeDetail.value.deliveryService !== 1 && index === 0) {
    uni.showToast({
      title: t('pages-store.store.toast.deliveryService'),
      icon: 'none'
    })
    return
  }
  if(+storeDetail.value.selfPickup !== 1 && index === 1) {
    uni.showToast({
      title: t('pages-store.store.toast.selfPickup'),
      icon: 'none'
    })
    return
  }

  if(index !== deliveryMethod.value) {
    deliveryMethod.value = index
    // 重置配送类型为预约配送
    deliveryTimeType.value = 2
    void appMerchantOrderCalculatePriceCart()
  }
}

// 折叠面板
const collapseValue = ref([""]);

// 单个订单的小费（与设计稿一致：默认 $2）
const selectedTipIndex = ref(2);
const diyTipValue = ref('')
// 批量订单：每个店铺的小费索引映射 merchantId -> tipIndex
const merchantTipIndexMap = ref<Record<string, number>>({})
// 批量订单：每个店铺的自定义小费值映射 merchantId -> diyTipValue
const merchantDiyTipValueMap = ref<Record<string, string>>({})

const tipOptions = ref([
  { label: "$ 2", value: 2 },
  { label: "$ 3", value: 3 },
  { label: "$ 4", value: 4 },
]);

// 单个订单的小费选择
function selectedTipChange(item: any) {
  if(item.value === selectedTipIndex.value) return
  diyTipValue.value = ''
  selectedTipIndex.value = item.value
  void appMerchantOrderCalculatePriceCart()
}

// 批量订单：选择某个店铺的小费
function selectedTipChangeForMerchant(merchantId: string, item: any) {
  if(item.value === merchantTipIndexMap.value[merchantId]) return
  merchantDiyTipValueMap.value[merchantId] = ''
  merchantTipIndexMap.value[merchantId] = item.value
  void appMerchantOrderCalculatePriceCart()
}

// 单个订单的自定义小费确认（金额，单位：美元）
function handleConfirmTip() {
  // 如果未填写其他小费金额，失去焦点时默认填充为 0
  const val = String(diyTipValue.value || '').trim()
  if (!val) {
    diyTipValue.value = '0'
  }
  // 使用自定义小费时，选中"其他"这一项
  if (selectedTipIndex.value !== 0) {
    selectedTipIndex.value = 0
  }
  void appMerchantOrderCalculatePriceCart()
}

// 批量订单：确认某个店铺的自定义小费（金额，单位：美元）
function handleConfirmTipForMerchant(merchantId: string) {
  const val = String(merchantDiyTipValueMap.value[merchantId] || '').trim()
  if (!val) {
    merchantDiyTipValueMap.value[merchantId] = '0'
  }
  // 使用自定义小费时，选中"其他"这一项
  if (merchantTipIndexMap.value[merchantId] !== 0) {
    merchantTipIndexMap.value[merchantId] = 0
  }
  void appMerchantOrderCalculatePriceCart()
}

// 是否选择了配送周卡
const isWeeklyDelivery = ref(false);
// 切换配送周卡
const toggleWeeklyDelivery = (value: boolean) => {
  if(value === isWeeklyDelivery.value) return
  isWeeklyDelivery.value = value;
  void appMerchantOrderCalculatePriceCart()
};

// 价格明细
const priceDetailRef = ref<InstanceType<typeof PriceDetail>>();
// 打开价格明细
const openPriceDetail = () => {
  priceDetailRef.value?.onOpen(priceData.value, cartSavingsData.value?.savings || 0);
};

function navigateTo(url: string) {
  uni.navigateTo({ url })
}
function chooseCardForCheckout() {
  payMethodSelected.value = 1
  uni.navigateTo({
    url: '/pages-user/pages/select-credit-card/index',
    events: {
      selectedCard: function(data: any) {
        if (data) {
          payMethodOptions.value.cardId = data.cardId || ''
          payMethodOptions.value.cardNumber = data.cardNumber || ''
        }
      },
    },
  })
}

// 支付参数
const payMethodOptions = ref({
  orderId: '',
  cardId: '',
  cardNumber: '',
  payMethod: 1, // 支付方式 1信用卡 2余额
  payPassword: '',
})
const payMethodPopupVisible = ref(false)
const payMethodSelected = ref(1)
const zellePopupVisible = ref(false)
const zelleOrderIdForVoucher = ref('')
const voucherChooseRef = ref<InstanceType<typeof ChooseImage>>()
const voucherSubmitting = ref(false)
const zellePayPath = Config.zellePayPath;

function openPayMethodPopup() {
  payMethodSelected.value = Number(payMethodOptions.value.payMethod || 1)
  payMethodPopupVisible.value = true
}
function confirmPayMethodForSettle() {
  payMethodOptions.value.payMethod = Number(payMethodSelected.value || 1)
  payMethodPopupVisible.value = false
  handleGoSettle()
}
function openUploadVoucher() {
  if (!zelleOrderIdForVoucher.value) {
    uni.showToast({ title: t('pages-store.order.voucherUploadFailed'), icon: 'none' })
    return
  }
  voucherChooseRef.value?.init()
}
function normalizeVoucherUrl(payload: unknown): string {
  if (Array.isArray(payload)) {
    const first = payload[0]
    return typeof first === 'string' ? first : ''
  }
  return typeof payload === 'string' ? payload : ''
}
async function onVoucherImageUploaded(urls: unknown) {
  const zipPayVoucher = normalizeVoucherUrl(urls)
  if (!zipPayVoucher || !zelleOrderIdForVoucher.value) {
    uni.showToast({ title: t('pages-store.order.voucherUploadFailed'), icon: 'none' })
    return
  }
  if (voucherSubmitting.value) return
  voucherSubmitting.value = true
  try {
    await appMerchantOrderZipPayVoucherPost({
      body: {
        orderId: zelleOrderIdForVoucher.value,
        zipPayVoucher,
      }
    })
    uni.showToast({ title: t('pages-store.order.voucherSubmitSuccess'), icon: 'none' })
    zellePopupVisible.value = false
    setTimeout(() => {
      if (zelleOrderIdForVoucher.value) {
        uni.reLaunch({
          url: `/pages-store/pages/order/index?id=${zelleOrderIdForVoucher.value}`
        })
      }
    }, 500)
  } catch {
    uni.showToast({ title: t('pages-store.order.voucherSubmitFailed'), icon: 'none' })
  } finally {
    voucherSubmitting.value = false
  }
}
useEventEmit(EventEnum.CHOOSE_PAYMENT_METHOD, (data) => {
  if(data) {
    if(data.payMethod === 1) {
      payMethodOptions.value.cardId = data.cardId
      payMethodOptions.value.cardNumber = data.cardNumber
      payMethodOptions.value.payMethod = 1
    } else {
      payMethodOptions.value.payMethod = 2
    }
  }
})


const storeId = ref('')
const orderType = ref('') // 订单类型：batch-批量下单，normal-普通下单
const batchCartIds = ref([]) // 批量下单的购物车ID列表
const formData = ref<CreateOrderCartBo>({
  orderRemark: '',
  phone: '',
  receiveMethod: 0,
  startScheduledTime: 0,
  endScheduledTime: 0,
  tipDiscount: 0,
  weeklyDeliveryFee: 0,
})
// 是否需要餐具
const needTableware = ref(false)

async function safeAwait<T>(label: string, task: () => Promise<T>): Promise<T | undefined> {
  try {
    return await task()
  } catch (e) {
    console.error(`[checkout] ${label} failed`, e)
    return undefined
  }
}
onLoad(async (options: any)=> {
  loading.value = true

  try {
    // 判断是批量下单还是普通下单
    if(options.type == 'batch' && options.cartIds) {
      // 批量下单模式
      orderType.value = 'batch'
      batchCartIds.value = options.cartIds.split(',')
      console.log("下单类型",options.type);

      // 默认取用户信息中的手机号作为收货手机号
      formData.value.phone = userStore.userInfo.phone || ''
      contact.value.areaCode = userStore.userInfo.areaCode || ''

      // 严格按顺序执行
      await safeAwait('getAddressList', getAddressList)
      await safeAwait('getBatchCartInfo', getBatchCartInfo)
      merchantAppointmentMap.value = loadCheckoutMerchantAppointments()
      cartDataList.value.forEach((m: any) => {
        const key = String(m.id);
        const ap = merchantAppointmentMap.value[key];
        if (ap?.startTime) {
          syncAppointmentDisplay(key, {
            date: ap.date ? new Date(ap.date as any) : new Date(Number(ap.startTime)),
            timeSlot: ap.timeSlot,
          });
        } else {
          ensureDefaultMerchantAppointment(m);
        }
      });
      await safeAwait('appUserCardSelectDefault', appUserCardSelectDefault)
    } else if(options.storeId) {
      // 普通下单模式
      orderType.value = 'normal'
      storeId.value = options.storeId as string
      formData.value.orderRemark = options.orderRemark as string

      needTableware.value = options.needTableware === 'true'

      // 默认取用户信息中的手机号作为收货手机号
      formData.value.phone = userStore.userInfo.phone || ''
      contact.value.areaCode = userStore.userInfo.areaCode || ''

      // 严格按顺序执行
      await safeAwait('getAddressList', getAddressList)
      await safeAwait('getCartInfo', getCartInfo)
      await safeAwait('getStoreDetail', getStoreDetail)
      await safeAwait('appUserCardSelectDefault', appUserCardSelectDefault)
    }
  } finally {
    loading.value = false
  }
})

onShow(async ()=> {
  // 刷新地址，并在必要时重新计算价格
  await safeAwait('getAddressList', getAddressList)
  const hasCart =
    orderType.value === 'batch'
      ? (batchCartIds.value?.length || 0) > 0
      : (cartDataList.value?.length || 0) > 0
  if (hasCart) {
    await safeAwait('appMerchantOrderCalculatePriceCart', appMerchantOrderCalculatePriceCart)
  }
})

// 页面加载状态
const loading = ref(true);
onMounted(() => {
  userStore.getUserInfo()
  const currentHour = dayjs().hour();
  if (currentHour >= 11 && currentHour <= 14) {
    setDeliveryMinutes(60);
  } else if (currentHour >= 17 && currentHour <= 20) {
    // 晚餐高峰期，配送时间延长
    setDeliveryMinutes(50);
  } else {
    // 非高峰期，正常配送时间
    setDeliveryMinutes(40);
  }
});

const cartDataList = ref<MerchantCartVo[]>([])
async function getCartInfo() {
  const res: any = await appMerchantCartListByMerchantIdPost({
    params: {
      merchantId: storeId.value,
    }
  })

  console.log('购物车列表', res)
  cartDataList.value = parseMerchantCartPayload(res?.data).items as MerchantCartVo[]

  // 购物车有菜品，查询菜品会员折扣价 + 计算价格（严格串行）
  if(cartDataList.value.length > 0) {
    await appMerchantCartCalculateSavings()
    await appMerchantOrderCalculatePriceCart()
  }
}

// 批量下单：查询购物车详情
async function getBatchCartInfo() {
  try {
    // 根据购物车ID列表，按店铺分组查询
    const cartIds = batchCartIds.value
    console.log('批量购物车ID列表', cartIds)
    
    // 1. 先获取所有店铺列表
    const merchantRes = await appMerchantCartListMerchantPost({});
    console.log('批量模式-购物车店铺列表', merchantRes);
    
    if (!merchantRes.data || merchantRes.data.length === 0) {
      cartDataList.value = [];
      return;
    }
    
    // 2. 对每个店铺查询完整的商品信息
    const merchantPromises = merchantRes.data.map(async (merchant: any) => {
      try {
        const cartRes = await appMerchantCartListByMerchantIdPost({
          params: {
            merchantId: merchant.id
          }
        });
        console.log(`批量模式-店铺 ${merchant.merchantName} 的商品列表`, cartRes);

        const payload = parseMerchantCartPayload(cartRes?.data);
        const filteredItems = payload.items.filter((item: any) =>
          cartIds.includes(String(item.id))
        );
        
        // 如果该店铺有选中的商品，才返回
        if (filteredItems.length > 0) {
          return {
            ...merchant,
            deliveryScheduleTimes:
              payload.deliveryScheduleTimes ?? merchant.deliveryScheduleTimes,
            merchantCartVoList: filteredItems
          };
        }
        return null;
      } catch (error) {
        console.error(`获取店铺 ${merchant.id} 商品失败`, error);
        return null;
      }
    });
    
    // 3. 等待所有店铺的商品信息加载完成，并过滤掉 null
    const results = await Promise.all(merchantPromises);
    cartDataList.value = results.filter(item => item !== null);
    console.log('批量模式-最终购物车数据', cartDataList.value);
    cartDataList.value.forEach((m: any) => {
      const id = String(m.id);
      if (merchantTipIndexMap.value[id] === undefined) {
        merchantTipIndexMap.value[id] = 2;
      }
      ensureDefaultMerchantAppointment(m);
    });

    // 批量模式：查询菜品会员折扣价 + 计算价格（严格串行）
    if(cartIds.length > 0) {
      await appMerchantCartCalculateSavings()
      await appMerchantOrderCalculatePriceCart()
    }
  } catch (error) {
    console.error('获取批量购物车详情失败', error)
    cartDataList.value = [];
  }
}

// 查询菜品会员折扣价
const cartSavingsData = ref({})
async function appMerchantCartCalculateSavings() {
  const cartIds = orderType.value == 'batch' ? batchCartIds.value : cartDataList.value.map(item => item.id)
  const res: any = await appMerchantCartCalculateSavingsPost({
    body: cartIds
  })
  console.log('菜品会员折扣价', res)
  cartSavingsData.value = res.data
}

// 获取商家详情信息
// 商家是否支持配送
const storeIsDeliveryService = computed(()=> {
  if(!storeDetail.value) return false
  return +storeDetail.value.deliveryService === 1
})
// 商家是否支持自提
const storeIsSelfPickup = computed(()=> {
  if(!storeDetail.value) return false
  return +storeDetail.value.selfPickup === 1
})
const storeDetail = ref<MerchantVo>({})
// 用户距离商家的距离信息
const storeDistance = ref(null)
async function getStoreDetail() {
  const res: any = await appMerchantDetailMerchantIdGet({
    params: {
      merchantId: storeId.value,
    }
  })

  console.log('商家详情', res)
  storeDetail.value = res.data as MerchantVo

  // 配送时间(是否支持配送)
  if(+storeDetail.value.deliveryService === 1) {
    // 配送时间
    deliveryMinutes.value = res.data.deliveryTime || 0
  }
  if(+storeDetail.value.selfPickup === 1) {
    // 自提时间
    selfPickupMinutes.value = res.data.pickupTime
  }
  // 商户的经纬度存在,并且用户的经纬度也存在
  if(res.data.latitude && res.data.longitude && userStore.userLocation.latitude && userStore.userLocation.longitude) {
    let distance = getDistanceInMiles(res.data.latitude, res.data.longitude, userStore.userLocation.latitude, userStore.userLocation.longitude)
    console.log('距离商家距离', distance)
    storeDistance.value = distance
  }

  // 判断配送和自取的开通状态
  const hasDelivery = +storeDetail.value.deliveryService === 1
  const hasPickup = +storeDetail.value.selfPickup === 1

  if (!hasDelivery && !hasPickup) {
    // 两个都没开通，不显示切换组件
    showDeliverySwitch.value = false
  } else if (!hasDelivery && hasPickup) {
    // 只开通自取，默认选中自取
    deliveryMethod.value = 1
    showDeliverySwitch.value = true
  } else if (hasDelivery && !hasPickup) {
    // 只开通配送，默认选中配送
    deliveryMethod.value = 0
    showDeliverySwitch.value = true
  } else {
    // 两个都开通，默认选中配送
    deliveryMethod.value = 0
    showDeliverySwitch.value = true
  }

  ensureDefaultMerchantAppointment({
    id: storeId.value,
    deliveryScheduleTimes: storeDetail.value?.deliveryScheduleTimes,
  });
}

const priceData = ref({})
async function appMerchantOrderCalculatePriceCart() {
  // 优先使用新选择的地址id
  const targetAddressId = selectedAddressId.value || currentAddressId.value
  // if(!targetAddressId) return
  
  const cartIds = orderType.value == 'batch' ? batchCartIds.value : cartDataList.value.map(item => item.id)
  
  // 批量模式使用批量计算价格接口
  if(orderType.value == 'batch') {
    // 构建 merchantCouponMap: { merchantId: couponId }
    const couponMap: Record<string, number> = {}
    Object.keys(merchantCouponMap.value).forEach(merchantId => {
      if(merchantCouponMap.value[merchantId]?.id) {
        couponMap[merchantId] = merchantCouponMap.value[merchantId].id
      }
    })
    
    // 构建 merchantTipMap: { merchantId: tipAmount } (小费金额，单位：美元)
    const tipMap: Record<string, number> = {}
    cartDataList.value.forEach((merchant: any) => {
      const merchantId = String(merchant.id)
      if(deliveryMethod.value === 1) {
        // 自取订单不需要小费
        tipMap[merchantId] = 0
      } else {
        // 配送订单需要小费
        const diyTip = merchantDiyTipValueMap.value[merchantId]
        const tipIndex = merchantTipIndexMap.value[merchantId] || 0
        if(diyTip) {
          // 自定义小费金额（美元）
          tipMap[merchantId] = Number(diyTip) || 0
        } else if(tipIndex > 0) {
          // 选择固定金额选项
          tipMap[merchantId] = tipIndex
        } else {
          tipMap[merchantId] = 0
        }
      }
    })
    
    const startMap: Record<string, number> = {}
    const endMap: Record<string, number> = {}
    cartDataList.value.forEach((m: any) => {
      const ap = merchantAppointmentMap.value[String(m.id)]
      if (ap?.startTime && ap?.endTime) {
        startMap[String(m.id)] = ap.startTime
        endMap[String(m.id)] = ap.endTime
      }
    })

    const res: any = await appMerchantOrderCalculatePriceCartBatchPost({
      body: {
        addressId: targetAddressId,
        cartIds: cartIds,
        receiveMethod: deliveryMethod.value === 0 ? 1 : 2,
        merchantCouponMap: couponMap,
        merchantTipMap: tipMap,
        merchantStartScheduledTimeMap: startMap,
        merchantEndScheduledTimeMap: endMap,
        phone: formData.value.phone,
        areaCode: contact.value.areaCode,
      }
    })
    console.log('批量购物车下单价格', res)
    priceData.value = res.data
  } else {
    // 普通模式使用单店铺计算价格接口
    // 计算小费金额（美元）
    let tipAmount = 0
    if(deliveryMethod.value === 0) {
      // 配送订单需要小费
      if(diyTipValue.value) {
        tipAmount = Number(diyTipValue.value) || 0
      } else if(selectedTipIndex.value > 0) {
        tipAmount = selectedTipIndex.value
      }
    }
    
    const res: any = await appMerchantOrderCalculatePriceCartPost({
      body: {
        addressId: targetAddressId,
        cartIds: cartIds,
        receiveMethod: deliveryMethod.value === 0 ? 1 : 2,
        couponId: couponInfo.value ? couponInfo.value.id : '',
        tipDiscount: tipAmount, // 小费金额（美元），自取订单不需要小费
        // weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
        phone: formData.value.phone,
        areaCode: contact.value.areaCode,
      }
    })
    console.log('购物车下单价格', res)
    priceData.value = res.data
  }
}

// 获取用户地址列表
const addressesList = ref([])
// 当前选中的地址id
const currentAddressId = ref('')
// 新选择的地址id（优先使用）
const selectedAddressId = ref('')
// 当前选中的地址信息
const addressInfo = computed(()=> {
  if(addressesList.value.length === 0) return {}
  // 优先使用新选择的地址id，如果没有则使用默认的地址id
  const targetId = selectedAddressId.value || currentAddressId.value
  return addressesList.value.find(item => String(item.id) === String(targetId)) || {};
});

async function getAddressList() {
  const res: any = await appUserAddressListPost({
    params: {
      pageNum: 1,
      pageSize: 100,
    }
  })
  console.log('获取用户地址列表', res)
  addressesList.value = res.rows
  if(addressesList.value.length > 0) {
    currentAddressId.value = addressesList.value[0].id
    // 结算页配送偏好默认「放门口」，不按地址簿 deliveryType 回显
  }
}

function chooseAddress() {
  // 优先使用新选择的地址id
  const targetAddressId = selectedAddressId.value || currentAddressId.value
  uni.navigateTo({
    url: '/pages-store/pages/order/choose-address?id=' + targetAddressId,
    events: {
      // 为指定事件添加一个监听器，获取被打开页面传送到当前页面的数据
      acceptDataFromOpenedPage: function(data) {
        console.log('获取被打开页面传送到当前页面的数据', data)
        // 将新选择的地址id存储到selectedAddressId中
        selectedAddressId.value = data.data
        // 配送偏好默认「放门口」，切换地址时保持用户在本页已选或默认值，不回写地址簿

        // 重新计算价格
        void appMerchantOrderCalculatePriceCart()
      },
    },
  })
}

function appUserCardSelectDefault() {
  return appUserCardSelectDefaultPost({}).then((res: any)=> {
    console.log('查询用户默认信用卡', res)
    payMethodOptions.value.cardId = res.data?.cardId || ''
    payMethodOptions.value.cardNumber = res.data?.cardNumber || ''
    return res
  })
}

// 是否显示周配送费选项
const isShowWeeklyDelivery = computed(()=> {
  let time = userStore?.userInfo?.weeklyDeliveryExpire;
  // 如果值为null，返回true
  if (time === null) return true;
  // 如果值不存在（如undefined），也返回true（根据你的需求可调整）
  if (!time) return true;
  // 检测是否到期：已过期返回true，未过期返回false
  return dayjs().isAfter(dayjs(Number(time)));
})

const passwordInputRef = ref(null)
const resOrderId = ref('')
const resOrderIds = ref([]) // 批量下单返回的订单ID列表
function handleGoSettle() {
  // 优先使用新选择的地址id
  const targetAddressId = selectedAddressId.value || currentAddressId.value
  if(!targetAddressId) {
    uni.showToast({
      title: t('pages-store.checkout.pleaseSelectAddress'),
      icon: 'none'
    })
    return
  }
  if(payMethodOptions.value.payMethod === 1 && !payMethodOptions.value.cardId) {
    uni.showToast({
      title: t('pages-store.checkout.pleaseSelectCreditCard'),
      icon: 'none'
    })
    return
  }

  if (deliveryTimeType.value === 2) {
    if (orderType.value === "batch") {
      for (const m of cartDataList.value as any[]) {
        const ap = merchantAppointmentMap.value[String(m.id)];
        if (!ap?.startTime || !ap?.endTime) {
          uni.showToast({
            title: t("pages-store.checkout.chooseTimeForStore", {
              name: m.merchantName || "",
            }),
            icon: "none",
          });
          return;
        }
      }
    } else {
      const ap = merchantAppointmentMap.value[String(storeId.value)];
      if (!ap?.startTime || !ap?.endTime) {
        uni.showToast({
          title: t("pages-store.checkout.chooseTime"),
          icon: "none",
        });
        return;
      }
    }
  }
  
  // 批量下单
  if(orderType.value == 'batch') {
    if(resOrderIds.value.length === 0) {
      // 构建 merchantCouponMap: { merchantId: couponId }
      const couponMap: Record<string, number> = {}
      Object.keys(merchantCouponMap.value).forEach(merchantId => {
        if(merchantCouponMap.value[merchantId]?.id) {
          couponMap[merchantId] = merchantCouponMap.value[merchantId].id
        }
      })
      
      // 构建 merchantTipMap: { merchantId: tipAmount } (小费金额，单位：美元)
      const tipMap: Record<string, number> = {}
      cartDataList.value.forEach((merchant: any) => {
        const merchantId = String(merchant.id)
        if(deliveryMethod.value === 1) {
          // 自取订单不需要小费
          tipMap[merchantId] = 0
        } else {
          // 配送订单需要小费
          const diyTip = merchantDiyTipValueMap.value[merchantId]
          const tipIndex = merchantTipIndexMap.value[merchantId] || 0
          if(diyTip) {
            // 自定义小费金额（美元）
            tipMap[merchantId] = Number(diyTip) || 0
          } else if(tipIndex > 0) {
            // 选择固定金额选项
            tipMap[merchantId] = tipIndex
          } else {
            tipMap[merchantId] = 0
          }
        }
      })
      
      let data = {
        addressId: targetAddressId,
        phone: formData.value.phone,
        areaCode: contact.value.areaCode,
        cartIds: batchCartIds.value,
        merchantCouponMap: couponMap,
        merchantTipMap: tipMap,
        deliveryMethod: visitMethod.value.label, // 派送方式(如放门口或者交到顾客手中)
        deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
        orderRemark: formData.value.orderRemark,
        receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
        startScheduledTime: '', //
        endScheduledTime: '', //
        needTableware: needTableware.value ? 1 : 2, // 餐具  1是 2否
      }

      if (deliveryTimeType.value === 1) {
        const result = getTimeStamps(showDeliveryTime.value);
        data.startScheduledTime = result.startTimestamp
        data.endScheduledTime = result.endTimestamp
      } else {
        const startMap: Record<string, number> = {}
        const endMap: Record<string, number> = {}
        cartDataList.value.forEach((m: any) => {
          const ap = merchantAppointmentMap.value[String(m.id)]
          if (ap?.startTime && ap?.endTime) {
            startMap[String(m.id)] = ap.startTime
            endMap[String(m.id)] = ap.endTime
          }
        })
        data.merchantStartScheduledTimeMap = startMap
        data.merchantEndScheduledTimeMap = endMap
      }
      console.log('批量下单参数', data)
      appMerchantOrderCreateOrderCartBatchPost({
        body: data
      }).then(res=> {
        console.log('批量下单成功', res)
        resOrderIds.value = res.data.orderIds || []
        // 如果是余额支付,弹出支付密码弹窗
        if(payMethodOptions.value.payMethod === 2) {
          passwordInputRef.value?.showPasswordInput()
        } else if (payMethodOptions.value.payMethod === 3) {
          zelleOrderIdForVoucher.value = resOrderIds.value?.[0] ? String(resOrderIds.value[0]) : ''
          zellePopupVisible.value = true
        } else {
          appMerchantOrderPayOrderBatch()
        }
      })
    } else {
      // 如果是余额支付,弹出支付密码弹窗
      if(payMethodOptions.value.payMethod === 2) {
        passwordInputRef.value?.showPasswordInput()
      } else if (payMethodOptions.value.payMethod === 3) {
        zelleOrderIdForVoucher.value = resOrderIds.value?.[0] ? String(resOrderIds.value[0]) : ''
        zellePopupVisible.value = true
      } else {
        appMerchantOrderPayOrderBatch()
      }
    }
  } else {
    // 普通下单
    if(!resOrderId.value) {
      // 计算小费金额（美元）
      let tipAmount = 0
      if(deliveryMethod.value === 0) {
        // 配送订单需要小费
        if(diyTipValue.value) {
          tipAmount = Number(diyTipValue.value) || 0
        } else if(selectedTipIndex.value > 0) {
          tipAmount = selectedTipIndex.value
        }
      }
      
      let data = {
        addressId: targetAddressId,
        phone: formData.value.phone,
        areaCode: contact.value.areaCode,
        cartIds: cartDataList.value.map(item => item.id),
        couponId: couponInfo.value ? couponInfo.value.id : '',
        deliveryMethod: visitMethod.value.label, // 派送方式(如放门口或者交到顾客手中)
        deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
        orderRemark: formData.value.orderRemark,
        receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
        startScheduledTime: '', //
        endScheduledTime: '', //
        tipDiscount: tipAmount, // 小费金额（美元），自取订单不需要小费
        // weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
        needTableware: needTableware.value ? 1 : 2, // 餐具  1是 2否
      }

      // 如果是预约派送
      if(deliveryTimeType.value === 1) {
        const result = getTimeStamps(showDeliveryTime.value);
        data.startScheduledTime = result.startTimestamp
        data.endScheduledTime = result.endTimestamp
      } else {
        const ap = merchantAppointmentMap.value[String(storeId.value)]
        data.startScheduledTime = ap?.startTime ?? (diyTime.value as any).startTime
        data.endScheduledTime = ap?.endTime ?? (diyTime.value as any).endTime
      }
      console.log('下单参数', data)
      appMerchantOrderCreateOrderCartPost({
        body: data
      }).then(res=> {
        console.log('下单成功', res)
        resOrderId.value = res.data || ''
        // 如果是余额支付,弹出支付密码弹窗
        if(payMethodOptions.value.payMethod === 2) {
          passwordInputRef.value?.showPasswordInput()
        } else if (payMethodOptions.value.payMethod === 3) {
          zelleOrderIdForVoucher.value = String(resOrderId.value || '')
          zellePopupVisible.value = true
        } else {
          appMerchantOrderPayOrder()
        }
      })
    } else {
      // 如果是余额支付,弹出支付密码弹窗
      if(payMethodOptions.value.payMethod === 2) {
        passwordInputRef.value?.showPasswordInput()
      } else if (payMethodOptions.value.payMethod === 3) {
        zelleOrderIdForVoucher.value = String(resOrderId.value || '')
        zellePopupVisible.value = true
      } else {
        appMerchantOrderPayOrder()
      }
    }
  }
}

function payPawSuccess(password: string) {
  payMethodOptions.value.payPassword = password
  if(orderType.value === 'batch') {
    appMerchantOrderPayOrderBatch()
  } else {
    appMerchantOrderPayOrder()
  }
}

function appMerchantOrderPayOrder() {
  appMerchantOrderPayOrderPost({
    body: {
      ...payMethodOptions.value,
      orderId: resOrderId.value
    }
  }).then(res=> {
    console.log('支付结果', res)
    uni.showToast({
      title: t('pages-store.checkout.paymentSuccess'),
      icon: 'none'
    })

    setTimeout(()=> {
      // 支付成功后跳转到当前订单详情页
      if (resOrderId.value) {
        uni.reLaunch({
          url: `/pages-store/pages/order/index?id=${resOrderId.value}`
        })
      } else {
        uni.navigateBack({
          delta: 2,
        })
      }
    }, 500)
  })
}

// 批量订单支付
function appMerchantOrderPayOrderBatch() {
  // 使用批量支付接口
  appMerchantOrderPayOrderBatchPost({
    body: {
      orderIds: resOrderIds.value,
      cardId: payMethodOptions.value.cardId,
      payMethod: payMethodOptions.value.payMethod,
      payPassword: payMethodOptions.value.payPassword
    }
  }).then(res=> {
    console.log('批量支付结果', res)
    uni.showToast({
      title: t('pages-store.checkout.paymentSuccess'),
      icon: 'none'
    })

    setTimeout(()=> {
      // 批量支付后，优先跳转到第一笔订单详情；若无订单ID则返回
      const firstOrderId = resOrderIds.value && resOrderIds.value.length > 0 ? resOrderIds.value[0] : ''
      if (firstOrderId) {
        uni.redirectTo({
          url: `/pages-store/pages/order/index?id=${firstOrderId}`
        })
      } else {
        uni.navigateBack({
          delta: 2,
        })
      }
    }, 500)
  }).catch(err => {
    console.error('批量支付失败', err)
    uni.showToast({
      title: '支付失败',
      icon: 'none'
    })
  })
}

function getTimeStamps(timeStr: string) {
  // 验证输入是否为空
  if (!timeStr || typeof timeStr !== 'string') {
    throw new Error('输入必须是有效的时间字符串，格式如 "HH:mm-HH:mm"');
  }

  // 验证格式是否正确
  const timeFormatRegex = /^([01]\d|2[0-3]):([0-5]\d)-([01]\d|2[0-3]):([0-5]\d)$/;
  if (!timeFormatRegex.test(timeStr)) {
    throw new Error('时间格式不正确，请使用 "HH:mm-HH:mm" 格式，例如 "17:57-18:27"');
  }

  // 分割时间字符串
  const [startTimeStr, endTimeStr] = timeStr.split('-');

  // 获取当前日期
  const today = dayjs().format('YYYY-MM-DD');

  // 解析开始和结束时间
  const startTime = dayjs(`${today} ${startTimeStr}`);
  const endTime = dayjs(`${today} ${endTimeStr}`);

  // 验证时间是否有效
  if (!startTime.isValid()) {
    throw new Error(`开始时间 ${startTimeStr} 无效`);
  }

  if (!endTime.isValid()) {
    throw new Error(`结束时间 ${endTimeStr} 无效`);
  }

  // 验证结束时间是否晚于开始时间
  if (endTime.isBefore(startTime)) {
    throw new Error('结束时间不能早于开始时间');
  }

  // 返回时间戳（毫秒）
  return {
    startTimestamp: startTime.valueOf(),
    endTimestamp: endTime.valueOf()
  };
}

/**
 * CreateOrderCartBo
 */
export interface CreateOrderCartBo {
  /**
   * 配送地址id
   */
  addressId?: number;
  /**
   * 区号
   */
  areaCode?: string;
  /**
   * 购物车id列表
   */
  cartIds?: number[];
  /**
   * 优惠券id
   */
  couponId?: number;
  /**
   * 派送方式(如放门口或者交到顾客手中)
   */
  deliveryMethod?: string;
  /**
   * 交付时间类型(1-立即交付 2-预约交付)
   */
  deliveryType?: number;
  /**
   * 订单备注
   */
  orderRemark?: string;
  /**
   * 手机号
   */
  phone: string;
  /**
   * 收货方式(1-派送 2-自取)
   */
  receiveMethod: number;
  /**
   * 预约时间- 开始
   */
  startScheduledTime?: number;
  /**
   * 预约时间- 结束
   */
  endScheduledTime?: number;
  /**
   * 小费比例
   */
  tipDiscount?: number;
  /**
   * 是否支付周配送费(1-是 2-否)
   */
  weeklyDeliveryFee?: number;
  [property: string]: any;
}

// 单个订单的优惠券信息
const couponInfo = ref(null)
// 批量订单：每个店铺的优惠券映射 merchantId -> couponInfo
const merchantCouponMap = ref<Record<string, any>>({})
// 批量订单：每个店铺的小费映射 merchantId -> tipAmount (小费金额，单位：美元)
const merchantTipMap = ref<Record<string, number>>({})
// 批量订单：每个店铺的小费比例映射 merchantId -> tipPercent (小费比例，0-100)
const merchantTipPercentMap = ref<Record<string, number>>({})

function navigateToCoupon(merchantId?: string) {
  const targetMerchantId = merchantId || storeId.value
  uni.navigateTo({
    url: '/pages-user/pages/coupon/list?id=' + targetMerchantId,
    events: {
      // 为指定事件添加一个监听器，获取被打开页面传送到当前页面的数据
      selectedCoupon: function(data) {
        console.log(data)
        if(data) {
          if(orderType.value === 'batch' && merchantId) {
            // 批量模式：存储到对应店铺的优惠券映射
            merchantCouponMap.value[merchantId] = data
          } else {
            // 单个订单模式
            couponInfo.value = data
          }
          // 重新计算价格
          void appMerchantOrderCalculatePriceCart()
        }
      },
    },
  })
}
const isUserMemberCheckout = computed(() => {
  const vo = userStore.userInfo.userMembershipVo;
  if (!vo) return false;
  const exp = vo.expireTime;
  if (exp) return dayjs().isBefore(dayjs(Number(exp)));
  return false;
});

const cartTotalPieceCount = computed(() => {
  if (orderType.value === 'batch') {
    let n = 0;
    cartDataList.value.forEach((m: any) => {
      (m.merchantCartVoList || []).forEach((item: any) => {
        n += Number(item.count) || 0;
      });
    });
    return n || batchCartIds.value.length;
  }
  return cartDataList.value.reduce(
    (sum, item: any) => sum + (Number(item.count) || 0),
    0,
  );
});

const serviceFeeAmount = computed(() => {
  const p: any = priceData.value;
  if (!p) return 0;
  const original =
    Number(p.actualAmount ?? p.totalActualAmount ?? 0) || 0;
  const ratio = Number(p.merchantVo?.platformServiceFeeRatio) || 0;
  return Math.round(original * ratio * 100) / 100;
});

const deliveryPillText = computed(() => {
  if (orderType.value === "batch") {
    return t("pages-store.checkout.chooseTime");
  }
  return getMerchantPillText(storeId.value);
});

function safeToNumber(val: unknown, fallback = 0) {
  const n = Number(val);
  return Number.isFinite(n) ? n : fallback;
}

function safeMoneyStr(val: unknown, fallback = 0) {
  return safeToNumber(val, fallback).toFixed(2);
}

const displayDeliveryFeeStr = computed(() => {
  const p: any = priceData.value;
  if (!p) return '0.00';
  if (orderType.value === 'batch') {
    return safeMoneyStr(p.totalDeliveryFee, 0);
  }
  return safeMoneyStr(p.deliveryFee, 0);
});

const displayGoodsAmountStr = computed(() => {
  const p: any = priceData.value;
  if (!p) return '0.00';
  if (orderType.value === 'batch') {
    return safeMoneyStr(p.totalActualAmount, 0);
  }
  return safeMoneyStr(p.actualAmount, 0);
});

const displayTaxStr = computed(() => {
  const p: any = priceData.value;
  if (!p) return '0.00';
  if (orderType.value === 'batch') {
    return safeMoneyStr(p.totalTax, 0);
  }
  return safeMoneyStr(p.tax, 0);
});

const displayTipStr = computed(() => {
  const p: any = priceData.value;
  if (!p) return '0.00';
  if (orderType.value === 'batch') {
    return safeMoneyStr(p.totalTip, 0);
  }
  return safeMoneyStr(p.tip, 0);
});

const displayPaidStr = computed(() => {
  const p: any = priceData.value;
  if (!p) return '0.00';
  if (orderType.value === 'batch') {
    return safeMoneyStr(p.totalPaidAmount, 0);
  }
  return safeMoneyStr(p.paidAmount, 0);
});

const scheduledServiceEndLabel = computed(() => {
  const slot = (diyTime.value as any)?.timeSlot;
  if (slot && String(slot).includes(' - ')) {
    return String(slot).split(' - ')[1]?.trim() || '';
  }
  return '';
});

const localDeliverySubtitleText = computed(() =>
  t('pages-store.checkout.localDeliverySubtitle', { name: appDisplayName.value })
);

const itemsGoodsTotalWithPriceText = computed(() =>
  t('pages-store.checkout.itemsGoodsTotalWithPrice', {
    count: cartTotalPieceCount.value,
    amount: displayGoodsAmountStr.value,
  })
);

const scheduledDeliveryWindowText = computed(() =>
  t('pages-store.checkout.scheduledDeliveryWindow', {
    time: scheduledServiceEndLabel.value,
  })
);

const deliverBeforeText = computed(() =>
  t('pages-store.checkout.deliverBefore', {
    time: deliveryMethod.value === 0
      ? String(userSelectedDeliveryTimeDate.value ?? '')
      : String(userSelectedSelfPickupTimeDate.value ?? ''),
  })
);

const memberThanksText = computed(() =>
  t('pages-store.checkout.memberThanks', { name: appDisplayName.value })
);

const subtotalWithPiecesText = computed(() =>
  t('pages-store.checkout.subtotalWithPieces', {
    count: cartTotalPieceCount.value,
  })
);

const subtotalOneLineText = computed(() =>
  t('pages-store.checkout.subtotalOneLine', {
    amount: displayPaidStr.value,
  })
);

const showAppointmentEntry = computed(() => {
  if (deliveryMethod.value === 0) {
    return storeIsDeliveryService.value || orderType.value === 'batch';
  }
  return storeIsSelfPickup.value || orderType.value === 'batch';
});

/** 商家标价配送费（用于划线价，实际运费可能因活动/距离更低） */
const listDeliveryFeeAmount = computed(() => {
  const p: any = priceData.value;
  const raw = p?.merchantVo?.deliveryFee;
  if (raw === undefined || raw === null || raw === '') return null;
  const n = Number(raw);
  return Number.isFinite(n) ? n : null;
});

const actualDeliveryFeeNum = computed(() => {
  const p: any = priceData.value;
  if (!p) return 0;
  if (orderType.value === 'batch') {
    return Number(p.totalDeliveryFee ?? 0);
  }
  return Number(p.deliveryFee ?? 0);
});

const showListDeliveryStrike = computed(() => {
  const list = listDeliveryFeeAmount.value;
  if (list == null) return false;
  return list > actualDeliveryFeeNum.value + 0.005;
});

const listDeliveryFeeStr = computed(() => {
  const list = listDeliveryFeeAmount.value;
  return list != null ? list.toFixed(2) : '';
});

function handleClose(merchantId?: string) {
  if(orderType.value === 'batch' && merchantId) {
    // 批量模式：清除对应店铺的优惠券
    delete merchantCouponMap.value[merchantId]
  } else {
    // 单个订单模式
    couponInfo.value = null
  }
  // 重新计算价格
  void appMerchantOrderCalculatePriceCart()
}
</script>

<template>
  <view class="checkout-root">
  <navbar
    :title="t('pages-store.checkout.title')"
    circle-back
    custom-class="checkout-page-navbar"
  />
  <view
    class="animate-in fade-in animate-ease-out animate-duration-300"
    v-show="loading"
  >
    <!-- 骨架屏 -->
    <CheckoutSkeleton
  /></view>
  <view
    class="checkout-page animate-in fade-in animate-ease-in animate-duration-300"
    v-if="!loading"
  >
    <view class="checkout-page-stack">
    <!-- 配送信息：主行（地址）+ 底部分栏（偏好 | 电话） -->
    <view class="checkout-block">
      <view class="checkout-section-label">{{ t('pages-store.checkout.deliveryInfo') }}</view>
      <view class="checkout-card checkout-gutter checkout-card--stacked">
        <template v-if="deliveryMethod === 0">
          <view @click="chooseAddress" class="checkout-delivery-main">
            <view class="flex-1 min-w-0 pr-16rpx">
              <template v-if="addressesList.length > 0 && addressInfo && addressInfo.formattedAddress">
                <text class="checkout-card-primary block line-clamp-2">{{ addressInfo.formattedAddress }}</text>
                <text v-if="addressInfo.displayName" class="checkout-card-secondary block mt-10rpx">{{ addressInfo.displayName }}</text>
              </template>
              <text v-else class="checkout-card-placeholder">{{ t('pages-store.checkout.fillAddressHint') }}</text>
            </view>
            <image src="@img/chef/142.png" mode="aspectFill" class="checkout-chevron" />
          </view>
          <view class="checkout-delivery-extras">
            <view @click.stop="chooseVisitMethod" class="checkout-delivery-extras-cell">
              <text class="checkout-delivery-extras-label">{{ t('pages-store.checkout.deliveryPreference') }}</text>
              <text class="checkout-delivery-extras-value line-clamp-1">{{ visitMethod.label }}</text>
            </view>
            <view class="checkout-delivery-extras-vline" />
            <view @click.stop="openChangePhone" class="checkout-delivery-extras-cell">
              <text class="checkout-delivery-extras-label">{{ t('pages-store.checkout.contactPhone') }}</text>
              <text class="checkout-delivery-extras-value line-clamp-1">{{ contact.areaCode }} {{ formData.phone }}</text>
            </view>
          </view>
        </template>
        <template v-else>
          <view class="checkout-pickup-info">
            <text class="checkout-pickup-name">{{ storeDetail?.merchantName }}</text>
            <text class="checkout-pickup-addr line-clamp-2">{{ storeDetail?.merchantAddress }}</text>
          </view>
          <view class="checkout-delivery-extras checkout-delivery-extras--full">
            <view class="checkout-delivery-extras-cell checkout-delivery-extras-cell--grow">
              <text class="checkout-delivery-extras-label">{{ t("pages-store.checkout.distance") }}</text>
              <text class="checkout-delivery-extras-value">
                <template v-if="storeDistance">{{ storeDistance }} {{ t('common.mile') }}</template>
                <template v-else>{{ t('pages-store.checkout.enableLocationForDistance') }}</template>
              </text>
            </view>
          </view>
        </template>
      </view>
    </view>

    <!-- 确认订单（单店） -->
    <view v-if="orderType === 'normal' && cartDataList.length > 0" class="checkout-block">
      <view class="checkout-section-label">{{ t('pages-store.checkout.confirmOrder') }}</view>
      <view class="checkout-card checkout-card--flush checkout-gutter overflow-hidden">
        <view class="checkout-confirm-inner">
          <view class="checkout-confirm-head">
            <view class="checkout-icon-circle">
              <view
                v-if="deliveryMethod === 0"
                class="i-carbon:delivery text-40rpx text-#333"
              />
              <view
                v-else
                class="i-carbon:store text-40rpx text-#333"
              />
            </view>
            <view class="checkout-confirm-head-text">
              <text class="checkout-card-title block">{{
                deliveryMethod === 0 ? t('pages-store.checkout.localDelivery') : t('pages-store.checkout.pickupTitle')
              }}</text>
              <text class="checkout-card-subtitle block">{{
                deliveryMethod === 0
                  ? localDeliverySubtitleText
                  : t('pages-store.checkout.pickupSubtitle')
              }}</text>
            </view>
          </view>
          <view v-if="showAppointmentEntry" class="checkout-confirm-band">
            <view
              @click.stop="toggleDeliveryTimeType(2)"
              class="checkout-date-pill"
            >
              {{ deliveryPillText }}
            </view>
            <view class="checkout-confirm-band-right">
              <text class="checkout-confirm-band-line1">
                {{ itemsGoodsTotalWithPriceText }}
              </text>
              <view v-if="deliveryMethod === 0" class="checkout-confirm-band-line2">
                <text>{{ t('pages-store.checkout.shippingFee') }}</text>
                <text v-if="showListDeliveryStrike" class="checkout-price-strike"> ${{ listDeliveryFeeStr }}</text>
                <text v-if="showListDeliveryStrike"> </text>
                <text class="checkout-confirm-meta-fee">${{ displayDeliveryFeeStr }}</text>
              </view>
            </view>
          </view>
        </view>
        <scroll-view
          v-if="deliveryMethod === 0"
          scroll-x
          class="checkout-schedule-scroll checkout-schedule-bleed"
          :show-scrollbar="false"
        >
          <view class="checkout-schedule-inner">
            <view class="checkout-schedule-card checkout-schedule-card--on">
              <view class="checkout-schedule-card-body">
                <view class="checkout-radio-dot" />
                <view class="flex-1 min-w-0">
                  <text class="checkout-schedule-title">{{ t('pages-store.checkout.scheduledDeliveryTitle') }}</text>
                  <text v-if="scheduledServiceEndLabel" class="checkout-schedule-mid">{{
                    scheduledDeliveryWindowText
                  }}</text>
                  <text class="checkout-schedule-hint">{{
                    t('pages-store.checkout.scheduledDeliveryHint')
                  }}</text>
                </view>
              </view>
              <text class="checkout-schedule-addon">{{ t('pages-store.checkout.scheduledDeliveryAddon') }}</text>
            </view>
            <view class="checkout-schedule-card checkout-schedule-card--off">
              <view class="checkout-schedule-card-body">
                <view class="checkout-radio-ring" />
                <view class="flex-1 min-w-0">
                  <text class="checkout-schedule-title checkout-schedule-title--muted">{{ t('pages-store.checkout.scheduledDeliveryStandardTitle') }}</text>
                  <text class="checkout-schedule-hint">{{ t('pages-store.checkout.scheduledDeliveryStandardDesc') }}</text>
                </view>
              </view>
            </view>
          </view>
        </scroll-view>

        <wd-collapse v-model="collapseValue" custom-class="checkout-order-collapse">
          <wd-collapse-item name="item3">
            <template #title="{ expanded }">
              <scroll-view scroll-x class="checkout-thumb-scroll checkout-thumb-strip" :show-scrollbar="false">
                <view class="flex items-center gap-16rpx py-20rpx pr-28rpx">
                  <view
                    v-for="cItem in cartDataList"
                    :key="cItem.id"
                    class="relative shrink-0 w-100rpx h-100rpx rounded-12rpx overflow-hidden"
                  >
                    <image
                      :src="(cItem.merchantDishVo?.dishImage || '').split(',')[0]"
                      mode="aspectFill"
                      class="w-full h-full"
                    />
                    <view
                      v-if="Number(cItem.count) > 1"
                      class="checkout-qty-badge"
                    >x{{ cItem.count }}</view>
                  </view>
                  <image
                    :class="[expanded ? 'rotate--90' : 'rotate-90']"
                    src="@img/chef/142.png"
                    mode="aspectFill"
                    class="w-32rpx h-32rpx shrink-0 transition-all duration-300 ml-8rpx"
                  />
                </view>
              </scroll-view>
            </template>
            <view
              v-for="(item, index) in cartDataList"
              :key="item.id"
              class="checkout-order-line"
            >
              <view class="flex items-center flex-1 min-w-0">
                <view
                  class="w-48rpx h-48rpx rounded-8rpx bg-#F2F2F2 center mr-24rpx shrink-0 text-24rpx"
                >{{ index + 1 }}</view>
                <view class="min-w-0 flex-1">
                  <view class="text-30rpx lh-36rpx text-#333 font-500 line-clamp-2"
                    >{{ item.merchantDishVo?.dishName }}</view
                  >
                  <view v-if="item.sideDishList?.length > 0"
                    class="text-24rpx lh-30rpx text-#7D7D7D font-400 mt-8rpx"
                    >
                    <view
                      v-for="(dish, dIdx) in item.sideDishList"
                      :key="dIdx"
                      class="inline"
                    >
                       <text class="mr-6rpx">{{ dish.merchantSideDishItemVo?.name }}</text>
                       <text class="text-#00A76D mx-6rpx">+${{ dish.merchantSideDishItemVo?.price }}</text>
                    </view>
                  </view>
                </view>
              </view>
              <view class="text-30rpx text-#333 font-500 shrink-0 ml-16rpx">${{ item.merchantDishVo?.discountPrice }}</view>
            </view>
          </wd-collapse-item>
        </wd-collapse>

        <view
          v-if="showAppointmentEntry && (userSelectedDeliveryTimeDate || userSelectedSelfPickupTimeDate)"
          class="checkout-deliver-hint"
        >
          {{ deliverBeforeText }}
        </view>
      </view>
    </view>
    
    <!-- 批量模式：多店铺列表 -->
    <view class="checkout-block" v-if="orderType === 'batch' && cartDataList.length > 0">
      <view class="checkout-gutter">
        <view
          v-for="merchant in cartDataList"
          :key="merchant.id"
          class="mb-24rpx checkout-card checkout-card--merchant overflow-hidden"
        >
          <!-- 店铺头部 -->
          <view class="checkout-merchant-head">
            <image
              class="w-60rpx h-60rpx rounded-50% mr-20rpx"
              :src="merchant.logo"
              mode="aspectFill"
            />
            <view class="flex-1 min-w-0">
              <view class="text-28rpx lh-28rpx text-#333 font-500"
                >{{ merchant.merchantName }}</view
              >
              <view
                class="text-24rpx lh-24rpx text-#7D7D7D font-400 mt-8rpx"
                >{{ merchant.merchantCartVoList.length }} {{ t('pages-user.cart.items') }}</view
              >
            </view>
          </view>
          <view
            v-if="showAppointmentEntry"
            class="checkout-merchant-schedule-row"
          >
            <view
              class="checkout-date-pill"
              @click.stop="toggleDeliveryTimeType(2, merchant)"
            >
              {{ getMerchantPillText(merchant.id) }}
            </view>
          </view>

          <!-- 商品列表 -->
          <view class="checkout-merchant-body">
            <view
              v-for="(item, itemIndex) in merchant.merchantCartVoList"
              :key="item.id"
              class="checkout-merchant-item"
              :class="itemIndex < merchant.merchantCartVoList.length - 1 ? 'is-divider' : ''"
            >
              <!-- 商品图片 -->
              <image
                :src="item.merchantDishVo?.dishImage?.split(',')[0]"
                mode="aspectFill"
                class="w-100rpx h-100rpx shrink-0 rounded-12rpx"
              ></image>

              <!-- 商品信息 -->
              <view class="ml-16rpx flex-1">
                <view class="text-[#333333] text-26rpx lh-36rpx font-500 line-clamp-2">{{
                    item.merchantDishVo?.dishName
                }}</view>
                
                <!-- 配菜信息 -->
                <view class="text-[#7D7D7D] text-22rpx lh-26rpx mt-8rpx" v-if="item.sideDishList?.length > 0">
                  <view
                    v-for="(dish, dIdx) in item.sideDishList"
                    :key="dIdx"
                    class="inline"
                  >
                    <text class="mr-6rpx">
                      {{ dish?.merchantSideDishItemVo?.name || '' }}
                    </text>
                    <text v-if="dish?.merchantSideDishItemVo?.price" class="text-#00A76D mr-10rpx">+${{ dish?.merchantSideDishItemVo?.price }}</text>
                  </view>
                </view>

                <!-- 价格和数量 -->
                <view class="flex items-center justify-between mt-12rpx">
                  <view class="flex items-center">
                    <text class="text-[#333333] text-28rpx font-500"
                    >${{ item.merchantDishVo?.discountPrice }}</text>
                    <text
                      v-if="item.merchantDishVo?.originalPrice && item.merchantDishVo?.originalPrice !== item.merchantDishVo?.discountPrice"
                      class="text-[#7D7D7D] text-22rpx line-through ml-8rpx"
                    >${{ item.merchantDishVo?.originalPrice }}</text>
                  </view>
                  <view class="text-[#7D7D7D] text-22rpx">
                    x{{ item.count }}
                  </view>
                </view>
              </view>
            </view>
          </view>

          <!-- 批量模式：每个店铺的优惠券和小费选择 -->
          <view v-if="merchant.id" class="checkout-merchant-footer">
            <!-- 优惠券 -->
            <view @click="navigateToCoupon(String(merchant.id))" class="flex-center-sb py-24rpx gap-20rpx">
              <view class="flex-center-sb flex-1">
                <view class="flex items-center">
                  <image
                      src="@img/chef/105.png"
                      mode="aspectFill"
                      class="w-36rpx h-36rpx relative z-1"
                  />
                  <view class="ml-20rpx text-26rpx lh-26rpx font-500 text-#333">
                    {{ merchantCouponMap[String(merchant.id)] ? merchantCouponMap[String(merchant.id)].snapshotNameZh : t('pages-store.checkout.couponInputPlaceholder') }}
                  </view>
                </view>
                <view v-if="merchantCouponMap[String(merchant.id)]" @click.stop="handleClose(String(merchant.id))" class="i-carbon:close-filled text-32rpx text-#7D7D7D"></view>
              </view>
              <image
                src="@img/chef/142.png"
                mode="aspectFill"
                class="w-24rpx h-24rpx shrink-0"
              />
            </view>

            <!-- 小费（仅配送时显示） -->
            <view v-if="deliveryMethod === 0" class="checkout-merchant-tip-block">
              <text class="checkout-driver-tip-desc">{{
                t('pages-store.checkout.driverTipNote')
              }}</text>
              <view class="flex items-center mb-20rpx">
                <image
                    src="@img/chef/1335.png"
                    mode="aspectFill"
                    class="w-36rpx h-36rpx relative z-1"
                />
                <view class="ml-20rpx text-26rpx lh-26rpx font-500 text-#333">
                  {{ t('pages-store.checkout.driverTip') }}
                </view>
              </view>

              <view class="checkout-tip-grid checkout-tip-grid--merchant">
                <view
                    v-for="(item, index) in tipOptions"
                    :key="index"
                    @click="selectedTipChangeForMerchant(String(merchant.id), item)"
                    :class="[
                      merchantTipIndexMap[String(merchant.id)] === item.value
                        ? 'checkout-tip-pill checkout-tip-pill--on'
                        : 'checkout-tip-pill',
                    ]"
                    class="checkout-tip-cell checkout-tip-cell--merchant"
                >
                  {{ item.label }}
                </view>
                <view
                    @click="selectedTipChangeForMerchant(String(merchant.id), { value: 0 })"
                    :class="[
                      merchantTipIndexMap[String(merchant.id)] === 0
                        ? 'checkout-tip-pill checkout-tip-pill--on'
                        : 'checkout-tip-pill',
                    ]"
                    class="checkout-tip-cell checkout-tip-cell--merchant checkout-tip-cell--input"
                >
                  <view class="px-10rpx center h-full w-full">
                    <wd-input
                        no-border
                        use-prefix-slot
                        @blur="handleConfirmTipForMerchant(String(merchant.id))"
                        custom-class="!center !text-24rpx !bg-transparent flex-1 !text-center"
                        placeholderStyle="font-size: 24rpx;color: #333; text-align: center;"
                        :placeholder="t('pages-store.checkout.other')"
                        v-model="merchantDiyTipValueMap[String(merchant.id)]"
                        @confirm="handleConfirmTipForMerchant(String(merchant.id))"
                    >
                      <template #suffix>
                        <text v-if="merchantDiyTipValueMap[String(merchant.id)] && merchantDiyTipValueMap[String(merchant.id)].length > 0">$</text>
                      </template>
                    </wd-input>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
    
    <!-- 批量模式且没有数据时的提示 -->
    <view class="checkout-block" v-if="orderType === 'batch' && cartDataList.length === 0">
      <view class="checkout-section-label">{{ t('pages-store.checkout.confirmOrder') }}</view>
      <view class="checkout-card checkout-gutter py-48rpx">
        <text class="block text-center text-28rpx text-#6d6d6d">已选择 {{ batchCartIds.length }} 件商品</text>
      </view>
    </view>

      <!-- 使用优惠（单店） -->
      <view class="checkout-block" v-if="orderType === 'normal'">
        <view class="checkout-section-label">{{ t('pages-store.checkout.useDiscount') }}</view>
        <view
          @click="navigateToCoupon()"
          class="checkout-card checkout-gutter checkout-pay-row"
        >
          <view class="flex items-center flex-1 min-w-0 pr-16rpx">
            <text class="flex-1 checkout-card-primary">{{
              couponInfo ? couponInfo.snapshotNameZh : t('pages-store.checkout.couponInputPlaceholder')
            }}</text>
            <view
              v-if="couponInfo"
              @click.stop="handleClose()"
              class="i-carbon:close-filled text-36rpx text-#7D7D7D mr-12rpx"
            ></view>
          </view>
          <image src="@img/chef/142.png" mode="aspectFill" class="checkout-chevron" />
        </view>
      </view>

      <!-- 司机小费（单店，仅配送） -->
      <view class="checkout-block" v-if="orderType === 'normal' && deliveryMethod === 0">
        <view class="checkout-section-label">{{ t('pages-store.checkout.driverTip') }}</view>
        <view class="checkout-card checkout-gutter checkout-tip-card">
          <text class="checkout-driver-tip-desc">{{
            t('pages-store.checkout.driverTipNote')
          }}</text>
          <view class="checkout-tip-grid">
            <view
              v-for="(item, index) in tipOptions"
              :key="index"
              @click="selectedTipChange(item)"
              :class="[
                selectedTipIndex === item.value
                  ? 'checkout-tip-pill checkout-tip-pill--on'
                  : 'checkout-tip-pill',
              ]"
              class="checkout-tip-cell"
            >
              {{ item.label }}
            </view>
            <view
              @click="selectedTipChange({ value: 0 })"
              :class="[
                selectedTipIndex === 0
                  ? 'checkout-tip-pill checkout-tip-pill--on'
                  : 'checkout-tip-pill',
              ]"
              class="checkout-tip-cell checkout-tip-cell--input"
            >
              <view class="px-10rpx center w-full h-full">
                <wd-input
                  no-border
                  use-prefix-slot
                  @blur="handleConfirmTip"
                  custom-class="!center !text-26rpx !bg-transparent flex-1 !text-center"
                  placeholderStyle="font-size: 26rpx;color: #333; text-align: center;"
                  :placeholder="t('pages-store.checkout.other')"
                  v-model="diyTipValue"
                  @confirm="handleConfirmTip"
                >
                  <template #suffix>
                    <text v-if="diyTipValue.length > 0">$</text>
                  </template>
                </wd-input>
              </view>
            </view>
          </view>
        </view>
      </view>

      <!-- 订单明细 -->
    <view class="checkout-block">
      <view class="checkout-section-label">{{ t('pages-store.checkout.orderBreakdown') }}</view>
      <view class="checkout-card checkout-breakdown checkout-gutter">
        <view v-if="isUserMemberCheckout" class="checkout-member-line">
          <text class="checkout-member-text">{{ memberThanksText }}</text>
          <text class="checkout-member-icon">◆</text>
        </view>
        <view class="checkout-breakdown-row">
          <text class="checkout-breakdown-label">{{ subtotalWithPiecesText }}</text>
          <text class="checkout-breakdown-value">${{ displayGoodsAmountStr }}</text>
        </view>
        <view class="checkout-breakdown-row">
          <text class="checkout-breakdown-label">{{ t('pages-store.checkout.priceDetail.taxation') }}</text>
          <text class="checkout-breakdown-value">${{ displayTaxStr }}</text>
        </view>
        <view class="checkout-breakdown-row checkout-breakdown-row--service">
          <view class="checkout-breakdown-label-wrap">
            <text class="checkout-breakdown-label" @click="openPriceDetail">{{ t('pages-store.checkout.serviceFee') }}</text>
            <image
              src="@img/chef/1336.png"
              class="checkout-breakdown-info-icon"
              mode="aspectFit"
              @click.stop="openPriceDetail"
            />
            
          </view>
          <text v-if="serviceFeeAmount > 0" class="checkout-breakdown-value">${{ serviceFeeAmount.toFixed(2) }}</text>
          <view
            v-else-if="serviceFeeAmount === 0"
            class="checkout-breakdown-value-placeholder checkout-breakdown-service-fee-free"
          >
            <text class="checkout-price-strike checkout-breakdown-strike-fee">$0.00</text>
            <view class="checkout-tag-free">{{ t('pages-store.checkout.freeTag') }}</view>
          </view>
        </view>
        <view
          v-if="deliveryMethod === 0"
          class="checkout-breakdown-row"
        >
          <text class="checkout-breakdown-label">{{ t('pages-store.checkout.shippingFee') }}</text>
          <view class="checkout-breakdown-value-wrap">
            <text v-if="showListDeliveryStrike" class="checkout-price-strike">${{ listDeliveryFeeStr }}</text>
            <text v-if="showListDeliveryStrike" class="checkout-price-gap"> </text>
            <text class="checkout-breakdown-value checkout-price-now">${{ displayDeliveryFeeStr }}</text>
          </view>
        </view>
        <view
          v-if="deliveryMethod === 0"
          class="checkout-breakdown-row"
        >
          <text class="checkout-breakdown-label">{{ t('pages-store.checkout.driverTip') }}</text>
          <text class="checkout-breakdown-value">${{ displayTipStr }}</text>
        </view>
        <view class="checkout-breakdown-row checkout-breakdown-row--emphasis">
          <text class="checkout-breakdown-label">{{ t('pages-store.checkout.orderTotalLine') }}</text>
          <text class="checkout-breakdown-value">${{ displayPaidStr }}</text>
        </view>
        <view class="checkout-breakdown-divider"></view>
        <view class="checkout-breakdown-row checkout-breakdown-row--total">
          <text class="checkout-breakdown-total-label">{{ subtotalWithPiecesText }}</text>
          <text class="checkout-breakdown-total-value">${{ displayPaidStr }}</text> 
        </view>
      </view>
    </view>

    </view>
    <!-- /checkout-page-stack -->

    <view class="checkout-page-bottom-spacer"></view>

    <!-- 底部支付：浮窗 + 毛玻璃（H5/App 全效果；小程序降级为半透明白底） -->
    <view class="checkout-bottom-dock">
      <view
        v-if="cartSavingsData && cartSavingsData.savings > 0"
        @click="navigateTo('/pages-user/pages/member/index')"
        class="checkout-savings-banner checkout-savings-banner--float"
      >
        <image
          src="@img/chef/1289.png"
          class="mr-10rpx w-32rpx h-32rpx shrink-0"
        ></image>
        <text class="checkout-savings-banner-text">
          {{ t('pages-store.store.use') }} {{ Config.appName }} {{ t('pages-store.store.tips3') }}  ${{ cartSavingsData?.savings }} {{ t('pages-store.store.discount') }}
        </text>
      </view>
      <view class="checkout-bottom-bar">
        <view class="checkout-bottom-bar-glass"></view>
        <view class="checkout-bottom-bar-inner">
          <view class="checkout-bottom-bar-price">
            <text class="checkout-bottom-bar-one-line">{{ subtotalOneLineText }}</text>
          </view>
          <wd-button
            @click="openPayMethodPopup"
            custom-class="checkout-pay-btn"
          >{{ t('pages-store.checkout.pay') }}
          </wd-button>
        </view>
        <view :style="[configStore.iosSafeBottomPlaceholder]"></view>
      </view>
    </view>

    <!--  修改配送偏好  -->
    <visit-method ref="visitMethodRef" @confirm="handleVisitMethodConfirm" />
    <!-- 修改手机号 -->
    <change-phone ref="changePhoneRef" @confirm="confirmPhone" />
    <!-- 价格明细 -->
    <price-detail ref="priceDetailRef" />
    <password-container @success="payPawSuccess" ref="passwordInputRef" />
    <choose-image ref="voucherChooseRef" :count="1" @change="onVoucherImageUploaded" />
    <wd-popup v-model="payMethodPopupVisible" position="bottom" @close="payMethodPopupVisible = false">
      <view class="checkout-paymethod-popup">
        <view class="checkout-paymethod-popup-title">{{ t('pages-store.checkout.payMethodSection') }}</view>

        <view
          class="checkout-paymethod-option"
          :class="{ 'is-active': payMethodSelected === 1 }"
          @click="payMethodSelected = 1"
        >
          <view class="checkout-paymethod-option-left">
            <view class="checkout-paymethod-dot">
              <view class="checkout-paymethod-dot-inner"></view>
            </view>
            <view class="checkout-paymethod-text-wrap">
              <view class="checkout-paymethod-name">{{ t('pages-user.choosePaymethod.creditCard') }}</view>
              <view class="checkout-paymethod-desc">{{ payMethodOptions.cardId ? payMethodOptions.cardNumber : t('pages-user.member.creditCard') }}</view>
            </view>
          </view>
          <view
            class="checkout-paymethod-replace-btn"
            @click.stop="chooseCardForCheckout"
          >
            {{ payMethodOptions.cardId ? t('pages-user.choosePaymethod.replace') : t('pages-user.member.creditCard') }}
          </view>
        </view>

        <view
          class="checkout-paymethod-option"
          :class="{ 'is-active': payMethodSelected === 2 }"
          @click="payMethodSelected = 2"
        >
          <view class="checkout-paymethod-option-left">
            <view class="checkout-paymethod-dot">
              <view class="checkout-paymethod-dot-inner"></view>
            </view>
            <view class="checkout-paymethod-text-wrap">
              <view class="checkout-paymethod-name">{{ t('pages-user.choosePaymethod.wallet') }}</view>
              <view class="checkout-paymethod-desc">Balance</view>
            </view>
          </view>
        </view>

        <view
          class="checkout-paymethod-option"
          :class="{ 'is-active': payMethodSelected === 3 }"
          @click="payMethodSelected = 3"
        >
          <view class="checkout-paymethod-option-left">
            <view class="checkout-paymethod-dot">
              <view class="checkout-paymethod-dot-inner"></view>
            </view>
            <view class="checkout-paymethod-text-wrap">
              <view class="checkout-paymethod-name">Zelle</view>
              <view class="checkout-paymethod-desc">Scan QR and upload voucher</view>
            </view>
          </view>
        </view>

        <wd-button @click="confirmPayMethodForSettle" custom-class="checkout-paymethod-confirm-btn" block>
          {{ t('common.confirm') }}
        </wd-button>
        <view :style="[configStore.iosSafeBottomPlaceholder]"></view>
      </view>
    </wd-popup>
    <wd-popup v-model="zellePopupVisible" custom-style="background: transparent;" @close="zellePopupVisible = false">
      <view class="w-620rpx rounded-24rpx bg-white p-28rpx">
        <view class="text-32rpx lh-32rpx text-#333 font-600 text-center mb-24rpx">Zelle</view>
        <image v-if="zellePayPath" :src="zellePayPath" mode="aspectFit" class="w-100% h-520rpx rounded-16rpx bg-#F7F7F7" />
        <view v-else class="h-220rpx rounded-16rpx bg-#F7F7F7 center text-#999 text-24rpx">
          zellePayPath is empty
        </view>
        <wd-button
          :loading="voucherSubmitting"
          :disabled="voucherSubmitting"
          @click="openUploadVoucher"
          custom-class="!h-92rpx !rounded-40rpx !text-30rpx !mt-26rpx !bg-#14181B"
          block
        >
          {{ t('pages-store.order.uploadPaidVoucher') }}
        </wd-button>
      </view>
    </wd-popup>
  </view>
  </view>
</template>

<style>
page {
  background-color: #f8f8f8;
}
</style>
<style scoped lang="scss">
/* 设计稿：浅灰底 #F8F8F8、主色 #000、次级字 #6D6D6D、卡片白底圆角约 12~20px、内边距 12~16px */
$checkout-bg: #f8f8f8;
$checkout-text: #000000;
$checkout-text-secondary: #6d6d6d;
$checkout-text-tertiary: #9e9e9e;
$checkout-card-bg: #ffffff;
$checkout-card-radius: 24rpx;
$checkout-border: #ebebeb;
$checkout-gutter: 32rpx;

.checkout-page {
  padding-top: 16rpx;
  padding-bottom: 32rpx;
  min-height: 100vh;
  box-sizing: border-box;
  background: $checkout-bg;
}

.checkout-page-stack {
  display: flex;
  flex-direction: column;
  gap: 40rpx;
  padding-bottom: 8rpx;
}

.checkout-block {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
}

.checkout-block > .checkout-section-label {
  margin-bottom: 0;
}

.checkout-gutter {
  margin-left: $checkout-gutter;
  margin-right: $checkout-gutter;
}

.checkout-section-label {
  padding: 0 $checkout-gutter;
  margin-bottom: 20rpx;
  font-size: 32rpx;
  font-weight: 700;
  color: $checkout-text;
  letter-spacing: 0.02em;
  line-height: 1.3;
}

.checkout-section-label--spaced {
  margin-top: 40rpx;
}

.checkout-card {
  background: $checkout-card-bg;
  border-radius: $checkout-card-radius;
  border: 1rpx solid $checkout-border;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.03);
}

.checkout-card--flush {
  border: 1rpx solid $checkout-border;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.03);
}

.checkout-card--merchant {
  border: 1rpx solid $checkout-border;
}

.checkout-card--stacked {
  padding: 0;
  overflow: hidden;
}

.checkout-delivery-main {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 32rpx 28rpx;
  min-height: 100rpx;
  box-sizing: border-box;
}

.checkout-delivery-extras {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  border-top: 1rpx solid $checkout-border;
  min-height: 100rpx;
}

.checkout-delivery-extras-cell {
  flex: 1;
  min-width: 0;
  padding: 20rpx 16rpx 24rpx 24rpx;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8rpx;
  box-sizing: border-box;
}

.checkout-delivery-extras-cell:first-of-type {
  padding-right: 12rpx;
}

.checkout-delivery-extras-cell:last-of-type {
  padding-left: 12rpx;
  padding-right: 24rpx;
}

.checkout-delivery-extras-vline {
  width: 1rpx;
  flex-shrink: 0;
  background: $checkout-border;
  align-self: stretch;
  margin: 16rpx 0;
}

.checkout-delivery-extras-label {
  font-size: 22rpx;
  color: $checkout-text-tertiary;
  line-height: 1.3;
}

.checkout-delivery-extras-value {
  font-size: 26rpx;
  font-weight: 500;
  color: $checkout-text;
  line-height: 1.35;
}

.checkout-delivery-extras--full {
  border-top: 1rpx solid $checkout-border;
}

.checkout-delivery-extras--full .checkout-delivery-extras-cell--grow {
  flex: 1;
  padding: 20rpx 24rpx 24rpx;
}

.checkout-pickup-info {
  padding: 32rpx 28rpx 24rpx;
  box-sizing: border-box;
}

.checkout-pickup-name {
  display: block;
  font-size: 30rpx;
  font-weight: 600;
  color: $checkout-text;
  line-height: 1.4;
}

.checkout-pickup-addr {
  display: block;
  margin-top: 10rpx;
  font-size: 26rpx;
  color: $checkout-text-secondary;
  line-height: 1.45;
}

.checkout-pay-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 32rpx 28rpx;
  min-height: 100rpx;
  box-sizing: border-box;
}

.checkout-paymethod-popup {
  padding: 36rpx 30rpx 20rpx;
  background: #fff;
  border-radius: 28rpx 28rpx 0 0;
}

.checkout-paymethod-popup-title {
  font-size: 34rpx;
  line-height: 1.3;
  font-weight: 700;
  color: #14181b;
  text-align: center;
  margin-bottom: 30rpx;
}

.checkout-paymethod-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 128rpx;
  padding: 0 24rpx;
  border: 2rpx solid #ececec;
  border-radius: 22rpx;
  background: #fff;
  margin-bottom: 18rpx;
  transition: all .2s ease;
}

.checkout-paymethod-option.is-active {
  border-color: #14181b;
  background: #f7f8fa;
  box-shadow: 0 6rpx 20rpx rgba(20, 24, 27, 0.08);
}

.checkout-paymethod-option-left {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
}

.checkout-paymethod-dot {
  width: 34rpx;
  height: 34rpx;
  border-radius: 50%;
  border: 2rpx solid #d0d0d0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 18rpx;
  flex-shrink: 0;
}

.checkout-paymethod-dot-inner {
  width: 16rpx;
  height: 16rpx;
  border-radius: 50%;
  background: transparent;
}

.checkout-paymethod-option.is-active .checkout-paymethod-dot {
  border-color: #14181b;
}

.checkout-paymethod-option.is-active .checkout-paymethod-dot-inner {
  background: #14181b;
}

.checkout-paymethod-text-wrap {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.checkout-paymethod-name {
  font-size: 30rpx;
  line-height: 1.25;
  font-weight: 600;
  color: #1f1f1f;
}

.checkout-paymethod-desc {
  font-size: 24rpx;
  line-height: 1.3;
  color: #8b8b8b;
}

.checkout-paymethod-replace-btn {
  margin-left: 16rpx;
  height: 50rpx;
  padding: 0 20rpx;
  border-radius: 25rpx;
  background: #ffffff;
  border: 1rpx solid #e6e6e6;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24rpx;
  color: #333333;
  flex-shrink: 0;
}

.checkout-paymethod-option:last-of-type {
  margin-bottom: 0;
}

.checkout-paymethod-confirm-btn {
  margin-top: 28rpx !important;
  height: 96rpx !important;
  border-radius: 46rpx !important;
  font-size: 30rpx !important;
  font-weight: 600 !important;
  background: #14181b !important;
}

.checkout-confirm-head {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 20rpx;
}

.checkout-confirm-head-text {
  flex: 1;
  min-width: 0;
}

.checkout-card-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 32rpx 28rpx;
  gap: 20rpx;
  min-height: 100rpx;
  box-sizing: border-box;
}

.checkout-card-row.is-divider {
  border-top: 1rpx solid $checkout-border;
}

.checkout-card-primary {
  font-size: 30rpx;
  font-weight: 500;
  color: $checkout-text;
  line-height: 1.45;
}

.checkout-card-secondary {
  font-size: 26rpx;
  font-weight: 400;
  color: $checkout-text-secondary;
  line-height: 1.4;
}

.checkout-card-placeholder {
  font-size: 30rpx;
  font-weight: 400;
  color: $checkout-text-secondary;
  line-height: 1.45;
}

.checkout-field-line {
  align-items: center;
}

.checkout-field-line--sub {
  min-height: auto;
  padding-top: 24rpx;
  padding-bottom: 24rpx;
}

.checkout-field-sub-label {
  display: block;
  font-size: 24rpx;
  color: $checkout-text-tertiary;
  margin-bottom: 8rpx;
}

.checkout-field-sub-value {
  display: block;
  font-size: 28rpx;
  font-weight: 500;
  color: $checkout-text;
  line-height: 1.35;
}

.checkout-chevron {
  width: 28rpx;
  height: 28rpx;
  flex-shrink: 0;
  opacity: 0.45;
}

.checkout-chevron--sub {
  width: 24rpx;
  height: 24rpx;
}

.checkout-price-strike {
  text-decoration: line-through;
  color: $checkout-text-tertiary;
  font-weight: 400;
}

.checkout-price-now {
  font-weight: 700;
}

.checkout-price-gap {
  display: inline;
  font-size: 20rpx;
}

.checkout-batch-shipping-line {
  margin-top: 12rpx;
  font-size: 24rpx;
  color: $checkout-text-secondary;
  line-height: 1.4;
}

.checkout-batch-shipping-now {
  font-weight: 700;
  color: $checkout-text;
}

.checkout-card-title {
  font-size: 32rpx;
  font-weight: 700;
  color: $checkout-text;
  line-height: 1.35;
}

.checkout-card-subtitle {
  font-size: 26rpx;
  font-weight: 400;
  color: $checkout-text-secondary;
  line-height: 1.45;
  margin-top: 8rpx;
}

.checkout-confirm-inner {
  padding: 32rpx 28rpx 12rpx;
}

.checkout-icon-circle {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  background: #ececec;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.checkout-confirm-band {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 24rpx;
  width: 100%;
  margin-top: 28rpx;
  box-sizing: border-box;
}

.checkout-confirm-band--compact {
  margin-top: 0;
}

.checkout-confirm-band-right {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  gap: 12rpx;
}

.checkout-confirm-band-line1 {
  font-size: 28rpx;
  font-weight: 400;
  color: $checkout-text;
  line-height: 1.45;
}

.checkout-confirm-band-line2 {
  font-size: 24rpx;
  color: $checkout-text-secondary;
  line-height: 1.35;
}

.checkout-confirm-meta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24rpx;
  margin-top: 28rpx;
}

.checkout-date-pill {
  display: inline-flex;
  align-items: center;
  padding: 18rpx 32rpx;
  font-size: 26rpx;
  color: #fff;
  background: #000;
  border-radius: 999rpx;
  font-weight: 600;
  line-height: 1.2;
  flex-shrink: 0;
}

.checkout-confirm-meta-right {
  flex: 1;
  min-width: 200rpx;
  text-align: right;
}

.checkout-confirm-meta-primary {
  font-size: 28rpx;
  font-weight: 400;
  color: $checkout-text;
  line-height: 1.45;
}

.checkout-confirm-meta-strong {
  font-weight: 700;
}

.checkout-confirm-meta-gap {
  font-size: 20rpx;
}

.checkout-confirm-meta-sub {
  margin-top: 12rpx;
  font-size: 24rpx;
  color: $checkout-text-secondary;
  line-height: 1.35;
}

.checkout-confirm-meta-fee {
  font-weight: 700;
  color: $checkout-text;
}

.checkout-schedule-scroll {
  width: 100%;
  white-space: nowrap;
  margin-top: 28rpx;
}

.checkout-schedule-scroll.checkout-schedule-bleed {
  margin-top: 8rpx;
}

.checkout-schedule-inner {
  display: inline-flex;
  flex-direction: row;
  align-items: stretch;
  padding: 0 0 8rpx 0;
  gap: 20rpx;
}

.checkout-schedule-bleed .checkout-schedule-inner {
  padding: 12rpx 28rpx 12rpx;
  box-sizing: border-box;
}

.checkout-schedule-card {
  display: inline-flex;
  flex-direction: column;
  justify-content: space-between;
  min-width: 460rpx;
  max-width: 560rpx;
  padding: 24rpx 24rpx 20rpx;
  border-radius: 20rpx;
  vertical-align: top;
  box-sizing: border-box;
}

.checkout-schedule-card-body {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 16rpx;
}

.checkout-schedule-card--on {
  border: 2rpx solid #000;
  background: #f0f0f0;
}

.checkout-schedule-card--off {
  border: 2rpx solid #e5e5e5;
  background: #fff;
}

.checkout-radio-dot {
  width: 36rpx;
  height: 36rpx;
  border-radius: 50%;
  border: 2rpx solid #000;
  flex-shrink: 0;
  margin-top: 4rpx;
  box-sizing: border-box;
  position: relative;
}

.checkout-radio-dot::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 18rpx;
  height: 18rpx;
  border-radius: 50%;
  background: #000;
}

.checkout-radio-ring {
  width: 36rpx;
  height: 36rpx;
  border-radius: 50%;
  border: 2rpx solid #c4c4c4;
  flex-shrink: 0;
  margin-top: 4rpx;
  box-sizing: border-box;
}

.checkout-schedule-title {
  display: block;
  font-size: 28rpx;
  font-weight: 700;
  color: $checkout-text;
  line-height: 1.35;
}

.checkout-schedule-title--muted {
  font-weight: 600;
  color: #444;
}

.checkout-schedule-mid {
  display: block;
  font-size: 26rpx;
  color: #444;
  margin-top: 12rpx;
  line-height: 1.35;
}

.checkout-schedule-hint {
  display: block;
  font-size: 22rpx;
  color: $checkout-text-tertiary;
  margin-top: 12rpx;
  line-height: 1.45;
}

.checkout-schedule-addon {
  display: block;
  margin-top: 20rpx;
  text-align: right;
  font-size: 28rpx;
  font-weight: 700;
  color: $checkout-text;
  letter-spacing: 0.02em;
}

.checkout-thumb-scroll {
  width: 100%;
  white-space: nowrap;
}

.checkout-thumb-strip {
  background: #f5f5f5;
  padding: 24rpx 28rpx;
  box-sizing: border-box;
}

.checkout-deliver-hint {
  padding: 16rpx 28rpx 28rpx;
  font-size: 24rpx;
  color: $checkout-text-secondary;
  line-height: 1.45;
}

.checkout-order-line {
  width: 100%;
  min-height: 120rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 28rpx;
  box-sizing: border-box;
  border-top: 1rpx solid $checkout-border;
  background: #fff;
}

.checkout-qty-badge {
  position: absolute;
  right: 8rpx;
  bottom: 8rpx;
  min-width: 36rpx;
  padding: 4rpx 10rpx;
  font-size: 22rpx;
  font-weight: 600;
  color: #fff;
  background: rgba(0, 0, 0, 0.82);
  border-radius: 8rpx;
  text-align: center;
}

.checkout-batch-pill-card {
  padding: 28rpx 28rpx;
  box-sizing: border-box;
}

.checkout-merchant-head {
  padding: 28rpx 24rpx;
  display: flex;
  align-items: center;
  background: #f3f3f3;
  border-bottom: 1rpx solid $checkout-border;
}

.checkout-merchant-schedule-row {
  padding: 20rpx 24rpx;
  border-bottom: 1rpx solid $checkout-border;
}

.checkout-confirm-band-right--full {
  width: 100%;
  text-align: right;
}

.checkout-merchant-body {
  padding: 8rpx 24rpx 16rpx;
}

.checkout-merchant-item {
  display: flex;
  align-items: flex-start;
  padding: 24rpx 0;
}

.checkout-merchant-item.is-divider {
  border-bottom: 1rpx solid $checkout-border;
}

.checkout-merchant-footer {
  padding: 8rpx 24rpx 28rpx;
  border-top: 1rpx solid $checkout-border;
  margin-top: 8rpx;
}

.checkout-merchant-tip-block {
  border-top: 1rpx solid $checkout-border;
  padding-top: 24rpx;
}

.checkout-page-bottom-spacer {
  /* 浮窗底栏 + 左右下边距 + 可选省钱条 */
  height: 300rpx;
}

.checkout-driver-tip-desc {
  display: block;
  font-size: 26rpx;
  color: $checkout-text-secondary;
  line-height: 1.55;
  margin-bottom: 28rpx;
}

.checkout-tip-card {
  padding: 28rpx 28rpx 32rpx;
  box-sizing: border-box;
}

.checkout-tip-card .checkout-driver-tip-desc {
  margin-bottom: 24rpx;
}

.checkout-tip-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16rpx;
  width: 100%;
  box-sizing: border-box;
}

.checkout-tip-grid--merchant {
  gap: 12rpx;
}

.checkout-tip-cell {
  min-width: 0;
  min-height: 72rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.checkout-tip-cell--merchant {
  min-height: 64rpx;
}

.checkout-tip-cell--input {
  padding: 0 4rpx;
}

.checkout-tip-grid .checkout-tip-pill {
  width: 100%;
}

.checkout-tip-pill {
  border-radius: 20rpx;
  border: 2rpx solid #000;
  background: #fff;
  color: $checkout-text;
  font-weight: 500;
  box-sizing: border-box;
}

.checkout-tip-pill--on {
  background: #000;
  color: #fff;
  border-color: #000;
}

.checkout-breakdown {
  padding: 32rpx 28rpx 36rpx;
  box-sizing: border-box;
}

.checkout-member-line {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20rpx;
  margin-bottom: 28rpx;
}

.checkout-member-icon {
  color: #e8954a;
  font-size: 32rpx;
  line-height: 1;
  flex-shrink: 0;
  margin-top: 2rpx;
}

.checkout-member-text {
  flex: 1;
  font-size: 28rpx;
  font-weight: 500;
  color: #ce7138;
  line-height: 1.45;
}

.checkout-breakdown-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 28rpx;
  font-size: 28rpx;
  line-height: 1.35;
}

.checkout-breakdown-row:last-of-type {
  margin-bottom: 0;
}

.checkout-breakdown-row--service .checkout-breakdown-label-wrap {
  flex: 1;
  min-width: 0;
}

.checkout-breakdown-strike-fee {
  font-size: 26rpx;
  margin-left: 4rpx;
}

.checkout-breakdown-value-wrap {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  text-align: right;
}

.checkout-breakdown-value-placeholder {
  min-width: 20rpx;
}

/* 服务费 $0.00 + 免费标签同一行（勿用 text 包 view，小程序易换行） */
.checkout-breakdown-service-fee-free {
  display: inline-flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
  flex-shrink: 0;
  max-width: 100%;
  gap: 8rpx;
  white-space: nowrap;
}

.checkout-breakdown-service-fee-free .checkout-breakdown-strike-fee {
  margin-left: 0;
  flex-shrink: 0;
}

.checkout-breakdown-service-fee-free .checkout-tag-free {
  flex-shrink: 0;
}

.checkout-breakdown-label {
  color: $checkout-text;
  font-weight: 400;
}

.checkout-breakdown-value {
  color: $checkout-text;
  font-weight: 500;
}

.checkout-breakdown-label-wrap {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10rpx;
}

.checkout-breakdown-info-icon {
  width: 28rpx;
  height: 28rpx;
  opacity: 0.55;
}

.checkout-tag-free {
  font-size: 20rpx;
  font-weight: 600;
  color: #b8860b;
  background: #fff4d4;
  padding: 6rpx 14rpx;
  border-radius: 8rpx;
  line-height: 1.2;
}

.checkout-breakdown-row--emphasis {
  margin-top: 8rpx;
  margin-bottom: 28rpx;
  // font-weight: 600;
}


.checkout-breakdown-divider {
  height: 1rpx;
  background: $checkout-border;
  margin: 28rpx 0;
}

.checkout-breakdown-row--total {
  margin-bottom: 0;
  align-items: baseline;
}

.checkout-breakdown-total-label {
  font-size: 30rpx;
  font-weight: 700;
  color: $checkout-text;
}

.checkout-breakdown-total-value {
  font-size: 34rpx;
  font-weight: 700;
  color: $checkout-text;
}

.checkout-bottom-dock {
  position: fixed;
  z-index: 9;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0 24rpx 20rpx;
  box-sizing: border-box;
  pointer-events: none;
}

.checkout-bottom-dock > * {
  pointer-events: auto;
}

.checkout-savings-banner {
  min-height: 76rpx;
  padding: 0 40rpx 0 36rpx;
  background: #ce7138;
  display: flex;
  align-items: center;
}

.checkout-savings-banner--float {
  margin-bottom: 16rpx;
  border-radius: 28rpx;
  box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.14);
}

.checkout-savings-banner-text {
  color: #fff;
  font-size: 24rpx;
  line-height: 1.4;
}

.checkout-bottom-bar {
  position: relative;
  border-radius: 78rpx;
  overflow: hidden;
  box-shadow:
    0 16rpx 48rpx rgba(0, 0, 0, 0.12),
    0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}

/* 毛玻璃层：半透明白 + 背景模糊 */
.checkout-bottom-bar-glass {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background: rgba(255, 255, 255, 0.62);
  border: 1rpx solid rgba(255, 255, 255, 0.92);
  box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.75);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}

.checkout-bottom-bar-inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  // gap: 28rpx;
  border-radius: 48rpx;
  padding: 24rpx 28rpx 20rpx;
  box-sizing: border-box;
}

.checkout-bottom-bar > view:last-child {
  position: relative;
  z-index: 1;
}

.checkout-bottom-bar-price {
  flex: 1;
  min-width: 0;
}

.checkout-bottom-bar-price-label {
  display: block;
  font-size: 26rpx;
  color: $checkout-text-secondary;
  margin-bottom: 8rpx;
  line-height: 1.2;
}

.checkout-bottom-bar-price-num {
  font-size: 40rpx;
  font-weight: 700;
  color: $checkout-text;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.checkout-bottom-bar-one-line {
  font-size: 30rpx;
  font-weight: 600;
  color: $checkout-text;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

:deep(.checkout-pay-btn) {
  flex-shrink: 0;
  min-width: 260rpx !important;
  height: 96rpx !important;
  padding: 0 48rpx !important;
  font-size: 32rpx !important;
  font-weight: 600 !important;
  color: #fff !important;
  background: #000 !important;
  border: none !important;
  border-radius: 48rpx !important;
  line-height: 96rpx !important;
}

:deep(.checkout-page-navbar) {
  background: $checkout-bg !important;
}

:deep(.checkout-page-navbar .wd-navbar__title) {
  font-size: 34rpx !important;
  font-weight: 700 !important;
  color: $checkout-text !important;
}

:deep(.checkout-order-collapse .wd-collapse-item__header) {
  padding: 0 !important;
  background: transparent !important;
}

:deep(.wd-collapse-item) {
  &::after {
    display: none;
    background-color: transparent !important;
  }
}

:deep(.wd-collapse-item__header.is-expanded) {
  &::after {
    background-color: transparent !important;
  }
}

:deep(.wd-collapse-item__body) {
  padding: 0 !important;
}
</style>
