import {useEffect, useMemo, useState} from "react";
import {
  Image,
  Button,
  Cell,
  CellGroup,
  Input,
  Space,
  ActionSheet,
  Popup,
  InputNumber,
  ConfigProvider
} from '@nutui/nutui-react-taro'
import {Location, ArrowRight, Shop} from '@nutui/icons-react-taro'
import Taro, {useDidShow} from '@tarojs/taro'
import {ShopGoods} from "@/api/shop/shopGoods/model";
import {getShopGoods} from "@/api/shop/shopGoods";
import {View, Text} from '@tarojs/components';
import {listShopUserAddress} from "@/api/shop/shopUserAddress";
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model";
import './index.scss'
import Gap from "@/components/Gap";
import {selectPayment} from "@/api/system/payment";
import {Payment} from "@/api/system/payment/model";
import {PaymentHandler, PaymentType, buildSingleGoodsOrder} from "@/utils/payment";
import OrderConfirmSkeleton from "@/components/OrderConfirmSkeleton";
import CouponList from "@/components/CouponList";
import {CouponCardProps} from "@/components/CouponCard";
import {getMyAvailableCoupons} from "@/api/shop/shopUserCoupon";
import {getGltTicketTemplateByGoodsId} from "@/api/glt/gltTicketTemplate";
import type {GltTicketTemplate} from "@/api/glt/gltTicketTemplate/model";
import {
  transformCouponData,
  calculateCouponDiscount,
  isCouponUsable,
  getCouponUnusableReason,
  sortCoupons,
  filterUsableCoupons,
  filterUnusableCoupons
} from "@/utils/couponUtils";
import type {ShopStore} from "@/api/shop/shopStore/model";
import {getShopStore, listShopStore} from "@/api/shop/shopStore";
import {getSelectedStoreFromStorage, saveSelectedStoreToStorage} from "@/utils/storeSelection";
import { ensureLoggedIn, isLoggedIn } from '@/utils/auth'


const OrderConfirm = () => {
  const [goods, setGoods] = useState<ShopGoods | null>(null);
  const [address, setAddress] = useState<ShopUserAddress>()
  const [payments, setPayments] = useState<any[]>([])
  const [payment, setPayment] = useState<Payment>()
  const [isVisible, setIsVisible] = useState<boolean>(false)
  const [quantity, setQuantity] = useState<number>(1)
  const [orderRemark, setOrderRemark] = useState<string>('')
  const [loading, setLoading] = useState<boolean>(true)
  const [error, setError] = useState<string>('')
  const [payLoading, setPayLoading] = useState<boolean>(false)

  // 水票套票活动（若存在则按规则限制最小购买量等）
  const [ticketTemplate, setTicketTemplate] = useState<GltTicketTemplate | null>(null)

  // InputNumber 主题配置
  const customTheme = {
    nutuiInputnumberButtonWidth: '28px',
    nutuiInputnumberButtonHeight: '28px',
    nutuiInputnumberInputWidth: '40px',
    nutuiInputnumberInputHeight: '28px',
    nutuiInputnumberInputBorderRadius: '4px',
    nutuiInputnumberButtonBorderRadius: '4px',
  }

  // 优惠券相关状态
  const [selectedCoupon, setSelectedCoupon] = useState<CouponCardProps | null>(null)
  const [couponVisible, setCouponVisible] = useState<boolean>(false)
  const [availableCoupons, setAvailableCoupons] = useState<CouponCardProps[]>([])
  const [couponLoading, setCouponLoading] = useState<boolean>(false)

  // 门店选择：用于在下单页展示当前"已选门店"，并允许用户切换（写入 SelectedStore Storage）
  const [storePopupVisible, setStorePopupVisible] = useState(false)
  const [stores, setStores] = useState<ShopStore[]>([])
  const [storeLoading, setStoreLoading] = useState(false)
  const [selectedStore, setSelectedStore] = useState<ShopStore | null>(getSelectedStoreFromStorage())

  const router = Taro.getCurrentInstance().router;
  const params = router?.params || ({} as Record<string, any>)
  const goodsIdParam = params?.goodsId
  const orderDataRaw = params?.orderData

  type OrderDataParam = {
    goodsId?: number | string
    skuId?: number | string
    quantity?: number | string
    price?: number | string
    specInfo?: string
  }

  const orderDataParam: OrderDataParam | null = useMemo(() => {
    if (!orderDataRaw) return null
    const rawText = String(orderDataRaw)
    try {
      return JSON.parse(decodeURIComponent(rawText)) as OrderDataParam
    } catch (_e1) {
      try {
        return JSON.parse(rawText) as OrderDataParam
      } catch (_e2) {
        console.error('orderData 参数解析失败:', orderDataRaw)
        return null
      }
    }
  }, [orderDataRaw])

  const resolvedGoodsId = (() => {
    const id1 = Number(goodsIdParam)
    if (Number.isFinite(id1) && id1 > 0) return id1
    const id2 = Number(orderDataParam?.goodsId)
    if (Number.isFinite(id2) && id2 > 0) return id2
    return undefined
  })()

  const resolvedSkuId = (() => {
    const n = Number(orderDataParam?.skuId)
    return Number.isFinite(n) && n > 0 ? n : undefined
  })()

  const quantityFromParam = (() => {
    const n = Number(orderDataParam?.quantity)
    return Number.isFinite(n) && n > 0 ? Math.floor(n) : undefined
  })()

  // 页面级兜底：未登录直接进入下单页时，引导去注册/登录并回跳
  useEffect(() => {
    // 兼容 goodsId / orderData 两种进入方式（goodsDetail 有规格时会走 orderData）
    const backUrl =
      orderDataRaw
        ? `/shop/orderConfirm/index?orderData=${orderDataRaw}`
        : resolvedGoodsId
          ? `/shop/orderConfirm/index?goodsId=${resolvedGoodsId}`
          : '/shop/orderConfirm/index'
    if (!ensureLoggedIn(backUrl)) return
  }, [resolvedGoodsId, orderDataRaw])

  const isTicketTemplateActive =
    !!ticketTemplate &&
    ticketTemplate.enabled !== false &&
    ticketTemplate.status !== 1 &&
    ticketTemplate.deleted !== 1
  const hasTicketTemplate = !!ticketTemplate

  // 套票活动最低购买量：优先取模板配置
  const ticketMinBuyQty = (() => {
    const n = Number(ticketTemplate?.minBuyQty)
    return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1
  })()
  const minBuyQty = isTicketTemplateActive ? ticketMinBuyQty : 1

  const getGiftTicketQty = (buyQty: number) => {
    if (!isTicketTemplateActive) return 0
    const multiplier = Number(ticketTemplate?.giftMultiplier || 0)
    const startSend = Number(ticketTemplate?.startSendQty || 0)
    if (multiplier > 0) return Math.max(0, buyQty) * multiplier
    return Math.max(0, startSend)
  }

  const loadStores = async () => {
    if (storeLoading) return
    try {
      setStoreLoading(true)
      const list = await listShopStore()
      setStores((list || []).filter(s => s?.isDelete !== 1))
    } catch (e) {
      console.error('获取门店列表失败:', e)
      setStores([])
      Taro.showToast({title: '获取门店列表失败', icon: 'none'})
    } finally {
      setStoreLoading(false)
    }
  }

  // @ts-ignore
  const openStorePopup = async () => {
    setStorePopupVisible(true)
    if (!stores.length) {
      await loadStores()
    }
  }

  // 计算商品总价
  const getGoodsTotal = () => {
    if (!goods) return 0
    const rawPrice = String(orderDataParam?.price ?? goods.price ?? '0')
    const priceNum = parseFloat(rawPrice)
    const price = Number.isFinite(priceNum) ? priceNum : 0
    // const total = price * quantity

    // 🔍 详细日志，用于排查数值精度问题
    // console.log('💵 商品总价计算:', {
    //   goodsPrice: goods.price,
    //   goodsPriceType: typeof goods.price,
    //   parsedPrice: price,
    //   quantity: quantity,
    //   total: total,
    //   totalFixed2: total.toFixed(2),
    //   totalString: total.toString()
    // })

    return price * quantity
  }

  // 计算优惠券折扣
  const getCouponDiscount = () => {
    if (!selectedCoupon || !goods) return 0
    const total = getGoodsTotal()
    return calculateCouponDiscount(selectedCoupon, total)
  }

  // 计算实付金额
  const getFinalPrice = () => {
    const total = getGoodsTotal()
    const discount = getCouponDiscount()
    return Math.max(0, total - discount)
  }


  const handleSelect = (item: any) => {
    setPayment(payments.find(payment => payment.name === item.name))
    setIsVisible(false)
  }

  // 处理数量变化
  const handleQuantityChange = (value: string | number) => {
    const fallback = isTicketTemplateActive ? minBuyQty : 1
    const newQuantity = typeof value === 'string' ? parseInt(value, 10) || fallback : value
    const step = goods?.step || 1
    const stockMax = goods?.stock ?? 999
    const maxMultiple = step > 1 ? Math.floor(stockMax / step) * step : stockMax
    const maxAllowed = maxMultiple > 0 ? maxMultiple : stockMax
    const effectiveMin = Math.min(fallback, maxAllowed)
    const clamped = Math.max(effectiveMin, Math.min(Number(newQuantity) || fallback, maxAllowed))
    const snapped = step > 1 ? Math.ceil(clamped / step) * step : clamped
    const finalQuantity = Math.max(effectiveMin, Math.min(snapped, maxAllowed))
    setQuantity(finalQuantity)

    // 数量变化时，重新排序优惠券并检查当前选中的优惠券是否还可用
    if (availableCoupons.length > 0) {
      const priceNum = parseFloat(String(orderDataParam?.price ?? goods?.price ?? '0'))
      const unitPrice = Number.isFinite(priceNum) ? priceNum : 0
      const newTotal = unitPrice * finalQuantity
      const sortedCoupons = sortCoupons(availableCoupons, newTotal)
      const usableCoupons = filterUsableCoupons(sortedCoupons, newTotal)
      setAvailableCoupons(sortedCoupons)

      // 检查当前选中的优惠券是否还可用
      if (selectedCoupon && !isCouponUsable(selectedCoupon, newTotal)) {
        setSelectedCoupon(null)
        Taro.showToast({
          title: '当前优惠券不满足使用条件，已自动取消',
          icon: 'none'
        })

        // 🎯 自动推荐新的最优优惠券
        if (usableCoupons.length > 0) {
          const bestCoupon = usableCoupons[0]
          const discount = calculateCouponDiscount(bestCoupon, newTotal)

          if (discount > 0) {
            setSelectedCoupon(bestCoupon)
            Taro.showToast({
              title: `已为您重新推荐最优优惠券，可省￥${discount.toFixed(2)}`,
              icon: 'success',
              duration: 3000
            })
          }
        }
      } else if (!selectedCoupon && usableCoupons.length > 0) {
        // 🔔 如果没有选中优惠券但有可用的，推荐最优的
        const bestCoupon = usableCoupons[0]
        const discount = calculateCouponDiscount(bestCoupon, newTotal)

        if (discount > 0) {
          setSelectedCoupon(bestCoupon)
          Taro.showToast({
            title: `已为您推荐最优优惠券，可省￥${discount.toFixed(2)}`,
            icon: 'success',
            duration: 3000
          })
        }
      } else if (selectedCoupon && usableCoupons.length > 0) {
        // 🔍 检查是否有更好的优惠券
        const bestCoupon = usableCoupons[0]
        const currentDiscount = calculateCouponDiscount(selectedCoupon, newTotal)
        const bestDiscount = calculateCouponDiscount(bestCoupon, newTotal)

        // 如果有更好的优惠券（优惠超过0.01元）
        if (bestDiscount > currentDiscount + 0.01 && bestCoupon.id !== selectedCoupon.id) {
          Taro.showModal({
            title: '发现更优惠的优惠券',
            content: `有更好的优惠券可用，额外节省￥${(bestDiscount - currentDiscount).toFixed(2)}，是否更换？`,
            success: (res) => {
              if (res.confirm) {
                setSelectedCoupon(bestCoupon)
                Taro.showToast({
                  title: '优惠券已更换',
                  icon: 'success'
                })
              }
            }
          })
        }
      }
    }
  }

  // 处理优惠券选择
  const handleCouponSelect = (coupon: CouponCardProps) => {
    const total = getGoodsTotal()

    // 🔍 详细日志记录，用于排查问题
    console.log('🎫 手动选择优惠券详细信息:', {
      coupon: {
        id: coupon.id,
        title: coupon.title,
        type: coupon.type,
        amount: coupon.amount,
        minAmount: coupon.minAmount,
        status: coupon.status
      },
      orderInfo: {
        goodsPrice: goods?.price,
        quantity: quantity,
        total: total,
        totalFixed: total.toFixed(2)
      },
      validation: {
        isUsable: isCouponUsable(coupon, total),
        discount: calculateCouponDiscount(coupon, total),
        reason: getCouponUnusableReason(coupon, total)
      }
    })

    // 检查是否可用
    if (!isCouponUsable(coupon, total)) {
      const reason = getCouponUnusableReason(coupon, total)

      // 🚨 记录手动选择失败的详细信息
      console.error('🚨 手动选择优惠券失败:', {
        reason,
        coupon,
        total,
        minAmount: coupon.minAmount,
        comparison: {
          totalVsMinAmount: `${total} < ${coupon.minAmount}`,
          result: total < (coupon.minAmount || 0)
        }
      })

      Taro.showToast({
        title: reason || '优惠券不可用',
        icon: 'none'
      })
      return
    }

    setSelectedCoupon(coupon)
    setCouponVisible(false)
    Taro.showToast({
      title: '优惠券选择成功',
      icon: 'success'
    })
  }

  // 取消选择优惠券
  const handleCouponCancel = () => {
    setSelectedCoupon(null)
    Taro.showToast({
      title: '已取消使用优惠券',
      icon: 'success'
    })
  }

  // 加载用户优惠券
  const loadUserCoupons = async (totalOverride?: number) => {
    try {
      setCouponLoading(true)

      // 使用新的API获取可用优惠券
      const res = await getMyAvailableCoupons()

      if (res && res.length > 0) {
        // 转换数据格式
        const transformedCoupons = res.map(transformCouponData)

        // 按优惠金额排序
        const total = totalOverride ?? getGoodsTotal()
        const sortedCoupons = sortCoupons(transformedCoupons, total)
        const usableCoupons = filterUsableCoupons(sortedCoupons, total)

        setAvailableCoupons(sortedCoupons)

        // 🎯 智能推荐：自动应用最优惠的可用优惠券
        if (usableCoupons.length > 0 && !selectedCoupon) {
          const bestCoupon = usableCoupons[0] // 已经按优惠金额排序，第一个就是最优的
          const discount = calculateCouponDiscount(bestCoupon, total)

          // 🔍 详细日志记录自动推荐的信息
          console.log('🤖 自动推荐优惠券详细信息:', {
            coupon: {
              id: bestCoupon.id,
              title: bestCoupon.title,
              type: bestCoupon.type,
              amount: bestCoupon.amount,
              minAmount: bestCoupon.minAmount,
              status: bestCoupon.status
            },
            orderInfo: {
              goodsPrice: goods?.price,
              quantity: quantity,
              total: total,
              totalFixed: total.toFixed(2)
            },
            validation: {
              isUsable: isCouponUsable(bestCoupon, total),
              discount: discount,
              reason: getCouponUnusableReason(bestCoupon, total)
            }
          })

          if (discount > 0) {
            setSelectedCoupon(bestCoupon)

            // 显示智能推荐提示
            Taro.showToast({
              title: `已为您推荐最优优惠券，可省￥${discount.toFixed(2)}`,
              icon: 'success',
              duration: 3000
            })
          }
        }

        // 🔔 优惠券提示：如果有可用优惠券，显示提示
        if (usableCoupons.length > 0) {
          console.log(`发现${usableCoupons.length}张可用优惠券，已为您推荐最优惠券`)
        }

        console.log('加载优惠券成功:', {
          originalData: res,
          transformedData: transformedCoupons,
          sortedData: sortedCoupons,
          usableCoupons: usableCoupons,
          recommendedCoupon: usableCoupons[0] || null
        })
      } else {
        setAvailableCoupons([])
        console.log('暂无可用优惠券')
      }
    } catch (error) {
      console.error('加载优惠券失败:', error)
      setAvailableCoupons([])
      Taro.showToast({
        title: '加载优惠券失败',
        icon: 'none'
      })
    } finally {
      setCouponLoading(false)
    }
  }

  /**
   * 统一支付入口
   */
  const onPay = async (goods: ShopGoods) => {
    let skipFinallyResetPayLoading = false
    try {
      setPayLoading(true)

      // 基础校验
      if (!address) {
        Taro.showToast({
          title: '请选择收货地址',
          icon: 'error'
        })
        return;
      }

      if (!payment) {
        Taro.showToast({
          title: '请选择支付方式',
          icon: 'error'
        })
        return;
      }

      // 购买水票（囤券预付费）与水票核销（下单履约）为两个独立动作：下单页不再选择配送时间。

      // 水票套票活动：最小购买量校验
      if (isTicketTemplateActive && quantity < minBuyQty) {
        Taro.showToast({
          title: `最低购买量：${minBuyQty}桶`,
          icon: 'none'
        })
        return
      }

      // 库存校验
      if (goods.stock !== undefined && quantity > goods.stock) {
        Taro.showToast({
          title: '商品库存不足',
          icon: 'error'
        })
        return;
      }

      // 优惠券校验
      if (selectedCoupon) {
        const total = getGoodsTotal()
        if (!isCouponUsable(selectedCoupon, total)) {
          const reason = getCouponUnusableReason(selectedCoupon, total)
          Taro.showToast({
            title: reason || '优惠券不可用',
            icon: 'error'
          })
          return;
        }
      } else {
        // 🔔 支付前最后一次检查：提醒用户是否有可用优惠券
        const total = getGoodsTotal()
        const usableCoupons = filterUsableCoupons(availableCoupons, total)

        if (usableCoupons.length > 0) {
          const bestCoupon = usableCoupons[0]
          const discount = calculateCouponDiscount(bestCoupon, total)

          if (discount > 0) {
            // 用模态框提醒用户
            const confirmResult = await new Promise<boolean>((resolve) => {
              Taro.showModal({
                title: '发现可用优惠券',
                content: `您有优惠券可使用，可省￥${discount.toFixed(2)}，是否使用？`,
                success: (res) => resolve(res.confirm),
                fail: () => resolve(false)
              })
            })

            if (confirmResult) {
              setSelectedCoupon(bestCoupon)
              // 🔄 使用优惠券后需要重新构建订单数据，这里直接递归调用支付函数
              // 但要确保传递最新的优惠券信息
              const currentPaymentType = payment.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;
              const updatedOrderData = buildSingleGoodsOrder(
                goods.goodsId!,
                quantity,
                address.id,
                {
                  comments: goods.name,
                  deliveryType: goods.deliveryMode === 1 ? 1 : 0,
                  buyerRemarks: orderRemark,
                  couponId: parseInt(String(bestCoupon.id), 10),
                  skuId: resolvedSkuId,
                  specInfo: orderDataParam?.specInfo
                }
              );

              console.log('🎯 使用推荐优惠券的订单数据:', updatedOrderData);

              // 执行支付
              await PaymentHandler.pay(updatedOrderData, currentPaymentType, hasTicketTemplate ? {
                onSuccess: async () => {
                  const id = goods.goodsId
                  const ticketIndexUrl = `/user/ticket/index?fromPayAt=${Date.now()}`
                  try {
                    const res = await Taro.showModal({
                      title: '提示',
                      content: '是否立刻送水？',
                      confirmText: '立刻送水',
                      cancelText: '稍后'
                    })
                    if (res?.confirm) {
                      if (id) {
                        await Taro.redirectTo({ url: `/user/ticket/use?goodsId=${id}` })
                      } else {
                        await Taro.redirectTo({ url: ticketIndexUrl })
                      }
                    } else {
                      await Taro.redirectTo({ url: ticketIndexUrl })
                    }
                  } catch (_e) {
                    await Taro.redirectTo({ url: ticketIndexUrl })
                  }
                  return false
                }
              } : undefined);
              return; // 提前返回，避免重复执行支付
            } else {
              // 用户选择不使用优惠券，继续支付
            }
          }
        }
      }

      // 构建订单数据
      const orderData = buildSingleGoodsOrder(
        goods.goodsId!,
        quantity,
        address.id,
        {
          comments: '桂乐淘',
          deliveryType: goods.deliveryMode === 1 ? 1 : 0,
          buyerRemarks: orderRemark,
          // 🔧 确保 couponId 是正确的数字类型，且不传递 undefined
          couponId: selectedCoupon ? parseInt(String(selectedCoupon.id), 10) : undefined,
          skuId: resolvedSkuId,
          specInfo: orderDataParam?.specInfo
        }
      );

      // 根据支付方式选择支付类型
      const paymentType = payment.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;

      // 🔍 支付前的详细信息记录
      console.log('💰 开始支付 - 详细信息:', {
        orderData,
        paymentType,
        selectedCoupon: selectedCoupon ? {
          id: selectedCoupon.id,
          title: selectedCoupon.title,
          type: selectedCoupon.type,
          amount: selectedCoupon.amount,
          minAmount: selectedCoupon.minAmount,
          discount: getCouponDiscount()
        } : null,
        priceCalculation: {
          goodsPrice: goods?.price,
          quantity: quantity,
          goodsTotal: getGoodsTotal(),
          couponDiscount: getCouponDiscount(),
          finalPrice: getFinalPrice()
        },
        couponValidation: selectedCoupon ? {
          isUsable: isCouponUsable(selectedCoupon, getGoodsTotal()),
          reason: getCouponUnusableReason(selectedCoupon, getGoodsTotal())
        } : null
      });

      // 执行支付 - 移除这里的成功提示，让PaymentHandler统一处理
      await PaymentHandler.pay(orderData, paymentType, hasTicketTemplate ? {
        onSuccess: async () => {
          const id = goods.goodsId
          const ticketIndexUrl = `/user/ticket/index?fromPayAt=${Date.now()}`
          try {
            const res = await Taro.showModal({
              title: '提示',
              content: '是否立刻送水？',
              confirmText: '立刻送水',
              cancelText: '稍后'
            })
            if (res?.confirm) {
              if (id) {
                await Taro.redirectTo({ url: `/user/ticket/use?goodsId=${id}` })
              } else {
                await Taro.redirectTo({ url: ticketIndexUrl })
              }
            } else {
              await Taro.redirectTo({ url: ticketIndexUrl })
            }
          } catch (_e) {
            await Taro.redirectTo({ url: ticketIndexUrl })
          }
          return false
        }
      } : undefined);

      // ✅ 移除双重成功提示 - PaymentHandler会处理成功提示
      // Taro.showToast({
      //   title: '支付成功',
      //   icon: 'success'
      // })
    } catch (error: any) {
      const message = String(error?.message || '')
      const isUserCancelPay =
        message.includes('用户取消支付') ||
        message.includes('取消支付') ||
        message.toLowerCase().includes('requestpayment:fail cancel') ||
        message.toLowerCase().includes('cancel')

      // 用户取消支付：跳转到待付款列表，方便继续支付
      if (isUserCancelPay) {
        skipFinallyResetPayLoading = true
        setPayLoading(false)
        const url = '/user/order/order?statusFilter=0'
        try {
          await Taro.redirectTo({ url })
        } catch (_e) {
          try {
            await Taro.navigateTo({ url })
          } catch (_e2) {
            // ignore
          }
        }
        return
      }

      const isOutOfDeliveryRange =
        message.includes('不在配送范围') ||
        message.includes('配送范围') ||
        message.includes('电子围栏') ||
        message.includes('围栏')

      // "配送范围"类错误给出更友好的解释，并提供快捷入口去更换收货地址
      if (isOutOfDeliveryRange) {
        try {
          const res = await Taro.showModal({
            title: '暂不支持配送',
            content: '当前收货地址超出配送范围。您可以更换收货地址后再下单，或联系门店确认配送范围。',
            confirmText: '更换地址',
            cancelText: '我知道了'
          })
          if (res?.confirm) {
            Taro.navigateTo({ url: '/user/address/index' })
          }
        } catch (_e) {
          // ignore
        }
        return
      }

      // 兜底：仅在 PaymentHandler 未弹过提示时再提示一次
      if (!error?.handled) {
        Taro.showToast({ title: message || '支付失败，请重试', icon: 'none' })
      }
    } finally {
      if (!skipFinallyResetPayLoading) {
        setPayLoading(false)
      }
    }
  };

  // 统一的数据加载函数
  const loadAllData = async () => {
    // 未登录时不发起接口请求；页面会被登录兜底逻辑引导走注册/登录页
    if (!isLoggedIn()) return

    try {
      setLoading(true)
      setError('')

      // 分别加载数据，避免类型推断问题
      let goodsRes: ShopGoods | null = null
      if (resolvedGoodsId) {
        goodsRes = await getShopGoods(resolvedGoodsId)
      }

      const [addressRes, paymentRes] = await Promise.all([
        listShopUserAddress({isDefault: true}),
        selectPayment({})
      ])

      // 设置商品信息
      // 查询当前商品是否存在水票套票活动（失败/无数据时不影响正常下单）
      let tpl: GltTicketTemplate | null = null
      if (resolvedGoodsId) {
        try {
          tpl = await getGltTicketTemplateByGoodsId(resolvedGoodsId)
        } catch (e) {
          tpl = null
        }
      }

      const tplActive =
        !!tpl &&
        tpl.enabled !== false &&
        tpl.status !== 1 &&
        tpl.deleted !== 1

      const tplMinBuyQty = (() => {
        const n = Number(tpl?.minBuyQty)
        return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1
      })()
      const tplStep = (() => {
        const n = Number(tpl?.step)
        return Number.isFinite(n) && n > 0 ? Math.floor(n) : undefined
      })()

      // 设置商品信息（若存在套票模板，则默认 canBuyNumber 使用模板最小购买量）
      if (goodsRes) {
        const patchedGoods: ShopGoods = { ...goodsRes }
        // 兜底：确保 step 为合法正整数；若存在套票模板则优先使用模板 step
        const goodsStepNum = Number((patchedGoods as any)?.step)
        const goodsStep = Number.isFinite(goodsStepNum) && goodsStepNum > 0 ? Math.floor(goodsStepNum) : 1
        patchedGoods.step = tplActive && tplStep ? tplStep : goodsStep

        // 规格商品（orderData 模式）下单时，用 sku 价格覆盖展示与计算金额
        if (orderDataParam?.price !== undefined && orderDataParam?.price !== null && orderDataParam?.price !== '') {
          patchedGoods.price = String(orderDataParam.price)
        }

        if (tplActive && ((patchedGoods.canBuyNumber ?? 0) === 0)) {
          patchedGoods.canBuyNumber = tplMinBuyQty
        }
        setGoods(patchedGoods)

        // 设置默认购买数量：优先使用 canBuyNumber，其次使用路由参数 quantity，否则使用 1
        const fixedQty = (patchedGoods.canBuyNumber ?? 0) > 0 ? Number(patchedGoods.canBuyNumber) : undefined
        const rawQty = fixedQty ?? quantityFromParam ?? 1
        const minQty = tplActive ? tplMinBuyQty : 1
        const step = patchedGoods.step || 1
        const stockMax = patchedGoods.stock ?? 999
        const maxMultiple = step > 1 ? Math.floor(stockMax / step) * step : stockMax
        const maxAllowed = maxMultiple > 0 ? maxMultiple : stockMax
        const effectiveMin = Math.min(minQty, maxAllowed)
        const clamped = Math.max(effectiveMin, Math.min(Math.floor(rawQty), maxAllowed))
        const stepped = step > 1 ? Math.ceil(clamped / step) * step : clamped
        setQuantity(Math.min(maxAllowed, Math.max(effectiveMin, stepped)))
      }

      setTicketTemplate(tpl)

      // 设置默认收货地址
      if (addressRes && addressRes.length > 0) {
        setAddress(addressRes[0])
      }

      // 设置支付方式
      if (paymentRes && paymentRes.length > 0) {
        setPayments(paymentRes.map((d) => ({
          type: d.type,
          name: d.name
        })))
        setPayment(paymentRes[0])
      }

      // 加载优惠券：使用"初始数量"对应的总价做推荐，避免默认数量变化导致推荐不准
      if (goodsRes) {
        const initQty = (() => {
          const n = Number(goodsRes?.canBuyNumber)
          if (Number.isFinite(n) && n > 0) return Math.floor(n)
          if (tplActive) return tplMinBuyQty
          return quantityFromParam || 1
        })()
        const stepForInit = tplActive && tplStep ? tplStep : (() => {
          const n = Number((goodsRes as any)?.step)
          return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1
        })()
        const stockMax = goodsRes.stock ?? 999
        const maxMultiple = stepForInit > 1 ? Math.floor(stockMax / stepForInit) * stepForInit : stockMax
        const maxAllowed = maxMultiple > 0 ? maxMultiple : stockMax
        const initQtySnapped = stepForInit > 1 ? Math.ceil(initQty / stepForInit) * stepForInit : initQty
        const effectiveMin = Math.min(tplActive ? tplMinBuyQty : 1, maxAllowed)
        const safeInitQty = Math.max(effectiveMin, Math.min(initQtySnapped, maxAllowed))
        const unitPrice = parseFloat(String(orderDataParam?.price ?? goodsRes.price ?? '0'))
        const total = unitPrice * safeInitQty
        await loadUserCoupons(total)
      }
    } catch (err) {
      console.error('加载数据失败:', err)
      setError('加载数据失败，请重试')
    } finally {
      setLoading(false)
    }
  }

  useDidShow(() => {
    // 返回/切换到该页面时，刷新一下当前已选门店
    if (!isLoggedIn()) return
    setSelectedStore(getSelectedStoreFromStorage())
    loadAllData()
  })

  useEffect(() => {
    if (!isLoggedIn()) return
    loadAllData()
  }, [resolvedGoodsId, orderDataRaw]);

  // 重新加载数据
  const handleRetry = () => {
    loadAllData()
  }

  // 错误状态
  if (error) {
    return (
      <View className="order-confirm-page">
        <View className="error-state">
          <Text className="error-text">{error}</Text>
          <Button onClick={handleRetry}>重新加载</Button>
        </View>
      </View>
    )
  }

  // 加载状态
  if (loading || !goods) {
    return <OrderConfirmSkeleton/>
  }

  return (
    <div className={'order-confirm-page'}>
      {goods.deliveryMode === 1 ? (
        // 自提模式：显示到店自提提示
        <CellGroup>
          <Cell>
            <Space>
              <Shop className={'text-orange-500'}/>
              <View className={'flex flex-col w-full'}>
                <Text className={'font-medium text-orange-600'}>到店自提</Text>
                <Text className={'text-gray-500 text-sm mt-1'}>请到店取货或出示核销码</Text>
              </View>
            </Space>
          </Cell>
        </CellGroup>
      ) : (
        // 送货上门模式：显示地址选择
        <CellGroup>
          {
            address && (
              <Cell className={'address-bottom-line'} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
                <Space>
                  <Location className={'text-gray-500'}/>
                  <View className={'flex flex-col w-full justify-between items-start'}>
                    <Space className={'flex flex-row w-full'}>
                      <View className={'flex-wrap text-nowrap whitespace-nowrap text-gray-500'}>送至</View>
                      <View className={'font-medium text-sm flex items-center w-full'}>
                        <View
                          style={{width: '64%'}}>{address.province} {address.city} {address.region} {address.address}</View>
                        <ArrowRight className={'text-gray-400'} size={14}/>
                      </View>
                    </Space>
                    <View className={'pt-1 pb-3 text-gray-500'}>{address.name} {address.phone}</View>
                  </View>
                </Space>
              </Cell>
            )
          }
          {!address && (
            <Cell className={''} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
              <Space>
                <Location/>
                添加收货地址
              </Space>
            </Cell>
          )}
        </CellGroup>
      )}

      {/*<CellGroup>*/}
      {/*  <Cell*/}
      {/*    title={(*/}
      {/*      <View className="flex items-center gap-2">*/}
      {/*        <Shop className={'text-gray-500'}/>*/}
      {/*        <Text>门店</Text>*/}
      {/*      </View>*/}
      {/*    )}*/}
      {/*    extra={(*/}
      {/*      <View className={'flex items-center gap-2'}>*/}
      {/*        <View className={'text-gray-900'}>*/}
      {/*          {selectedStore?.name || '请选择门店'}*/}
      {/*        </View>*/}
      {/*        <ArrowRight className={'text-gray-400'} size={14}/>*/}
      {/*      </View>*/}
      {/*    )}*/}
      {/*    onClick={openStorePopup}*/}
      {/*  />*/}
      {/*</CellGroup>*/}

      <CellGroup>
        <Cell key={goods.goodsId}>
          <View className={'flex w-full justify-between gap-3'}>
            <View>
              <Image src={goods.image} mode={'aspectFill'} style={{
                width: '80px',
                height: '80px',
              }} lazyLoad={false}/>
            </View>
            <View className={'flex flex-col w-full ml-2'} style={{width: '100%'}}>
              <Text className={'font-medium w-full'}>{goods.name}</Text>
              {/*<Text className={'number text-gray-400 text-sm py-2'}>80g/袋</Text>*/}
              <View className={'flex justify-between items-center'}>
                <Text className={'text-red-500'}>￥{goods.price}</Text>
                <View className={'flex flex-col items-end gap-1'}>
	                  <ConfigProvider theme={customTheme}>
	                    <InputNumber
	                      value={quantity}
	                      min={isTicketTemplateActive ? minBuyQty : 1}
	                      max={goods.stock || 999}
	                      step={goods.step || 1}
	                      readOnly
                        disabled={((goods.canBuyNumber ?? 0) !== 0) && !isTicketTemplateActive}
	                      onChange={handleQuantityChange}
	                    />
	                  </ConfigProvider>
                  {goods.stock !== undefined && (
                    <Text className={'text-xs text-gray-400'}>
                      库存 {goods.stock} 件
                    </Text>
                  )}
                  {isTicketTemplateActive && (
                    <View className={'text-xs text-gray-500'}>
                      <Text>最低购买量：{minBuyQty}桶</Text>
                      <Text className={'ml-2'}>赠送水票：{getGiftTicketQty(quantity)}张</Text>
                    </View>
                  )}
                </View>
              </View>
            </View>
          </View>
        </Cell>
      </CellGroup>

      <CellGroup>
        <Cell
          title={'支付方式'}
          extra={(
            <View className={'flex items-center gap-2'}>
              <View className={'text-gray-900'}>{payment?.name}</View>
              <ArrowRight className={'text-gray-400'} size={14}/>
            </View>
          )}
          onClick={() => setIsVisible(true)}
        />
      </CellGroup>

      <CellGroup>
        <Cell
          title={`商品总价（共${quantity}件）`}
          extra={<View className={'font-medium'}>￥{getGoodsTotal().toFixed(2)}</View>}
        />
        <Cell
          title={'优惠券'}
          extra={(
            <View className={'flex justify-between items-center'}>
              <View className={'text-red-500 text-sm mr-1'}>
                {selectedCoupon ? `-￥${getCouponDiscount().toFixed(2)}` : '暂未使用'}
              </View>
              {(() => {
                const usableCoupons = filterUsableCoupons(availableCoupons, getGoodsTotal())
                if (usableCoupons.length > 0 && !selectedCoupon) {
                  return (
                    <View className={'flex items-center'}>
                      <View className={'bg-red-500 text-white text-xs px-2 py-1 rounded mr-2'}>
                        {usableCoupons.length}张可用
                      </View>
                      <ArrowRight className={'text-gray-400'} size={14}/>
                    </View>
                  )
                } else if (usableCoupons.length > 0) {
                  return (
                    <View className={'flex items-center'}>
                      <View className={'bg-green-500 text-white text-xs px-2 py-1 rounded mr-2'}>
                        已选择
                      </View>
                      <ArrowRight className={'text-gray-400'} size={14}/>
                    </View>
                  )
                } else {
                  return <ArrowRight className={'text-gray-400'} size={14}/>
                }
              })()
              }
            </View>
          )}
          onClick={() => setCouponVisible(true)}
        />
        <Cell title={'配送费'} extra={'￥0.00'}/>
        <Cell extra={(
          <View className={'flex items-end gap-2'}>
            <Text>已优惠</Text>
            <Text className={'text-red-500 text-sm'}>￥{getCouponDiscount().toFixed(2)}</Text>
            <Text className={'ml-2'}>实付</Text>
            <Text className={'text-gray-700 font-bold'} style={{fontSize: '18px'}}>￥{getFinalPrice().toFixed(2)}</Text>
          </View>
        )}/>
      </CellGroup>

      <CellGroup>
        <Cell title={'订单备注'} extra={(
          <Input
            placeholder={'选填，请先和商家协商一致'}
            style={{padding: '0'}}
            value={orderRemark}
            onChange={(value) => setOrderRemark(value)}
            maxLength={100}
          />
        )}/>
      </CellGroup>

      {ticketTemplate && (
        <CellGroup>
          <Cell extra={(
            <div className={'text-red-500 text-sm'}>
              <Text>注意事项：</Text>
              <Text>最低起送量≥{ticketTemplate.startSendQty}桶；</Text>
              <Text>配送范围要在电子围栏内；</Text>
              <Text>上楼费暂不收取，收费另行通知。</Text>
            </div>
          )}/>
        </CellGroup>
      )}


      {/* 支付方式选择 */}
      <ActionSheet
        visible={isVisible}
        options={payments}
        onSelect={handleSelect}
        onCancel={() => setIsVisible(false)}
      />

      {/* 优惠券选择弹窗 */}
      <Popup
        visible={couponVisible}
        position="bottom"
        onClose={() => setCouponVisible(false)}
        style={{height: '60vh'}}
      >
        <View className="coupon-popup">
          <View className="coupon-popup__header">
            <Text className="text-sm">选择优惠券</Text>
            <Button
              size="small"
              fill="none"
              onClick={() => setCouponVisible(false)}
            >
              关闭
            </Button>
          </View>

          <View className="coupon-popup__content">
            {couponLoading ? (
              <View className="coupon-popup__loading">
                <Text>加载优惠券中...</Text>
              </View>
            ) : (
              <>
                {selectedCoupon && (
                  <View className="coupon-popup__current">
                    <Text className="coupon-popup__current-title font-medium">当前使用</Text>
                    <View className="coupon-popup__current-item">
                      <Text>{selectedCoupon.title} -￥{calculateCouponDiscount(selectedCoupon, getGoodsTotal()).toFixed(2)}</Text>
                      <Button size="small" onClick={handleCouponCancel}>取消使用</Button>
                    </View>
                  </View>
                )}

                {(() => {
                  const total = getGoodsTotal()
                  const usableCoupons = filterUsableCoupons(availableCoupons, total)
                  const unusableCoupons = filterUnusableCoupons(availableCoupons, total)

                  return (
                    <>
                      <CouponList
                        title={`可用优惠券 (${usableCoupons.length})`}
                        coupons={usableCoupons}
                        layout="vertical"
                        onCouponClick={handleCouponSelect}
                        showEmpty={usableCoupons.length === 0}
                        emptyText="暂无可用优惠券"
                      />

                      {unusableCoupons.length > 0 && (
                        <CouponList
                          title={`不可用优惠券 (${unusableCoupons.length})`}
                          coupons={unusableCoupons.map(coupon => ({
                            ...coupon,
                            status: 2 as const
                          }))}
                          layout="vertical"
                          showEmpty={false}
                        />
                      )}
                    </>
                  )
                })()}
              </>
            )}
          </View>
        </View>
      </Popup>

      {/* 门店选择弹窗 */}
      <Popup
        visible={storePopupVisible}
        position="bottom"
        style={{height: '70vh'}}
        onClose={() => setStorePopupVisible(false)}
      >
        <View className="p-4">
          <View className="flex justify-between items-center mb-3">
            <Text className="text-base font-medium">选择门店</Text>
            <Text
              className="text-sm text-gray-500"
              onClick={() => setStorePopupVisible(false)}
            >
              关闭
            </Text>
          </View>

          {storeLoading ? (
            <View className="py-10 text-center text-gray-500">
              <Text>加载中...</Text>
            </View>
          ) : (
            <CellGroup>
              {stores.map((s) => {
                const isActive = !!selectedStore?.id && selectedStore.id === s.id
                return (
                  <Cell
                    key={s.id}
                    title={<Text className={isActive ? 'text-green-600' : ''}>{s.name || `门店${s.id}`}</Text>}
                    description={s.address || ''}
                    onClick={async () => {
                      let storeToSave: ShopStore = s
                      if (s?.id) {
                        try {
                          const full = await getShopStore(s.id)
                          if (full) storeToSave = full
                        } catch (_e) {
                          // keep base item
                        }
                      }
                      setSelectedStore(storeToSave)
                      saveSelectedStoreToStorage(storeToSave)
                      setStorePopupVisible(false)
                      Taro.showToast({title: '门店已切换', icon: 'success'})
                    }}
                  />
                )
              })}
              {!stores.length && (
                <Cell title={<Text className="text-gray-500">暂无门店数据</Text>} />
              )}
            </CellGroup>
          )}
        </View>
      </Popup>

      <Gap height={50}/>

      <div className={'fixed z-50 bg-white w-full bottom-0 left-0 pt-4 pb-10 border-t border-gray-200'}>
        <View className={'btn-bar flex justify-between items-center'}>
          <div className={'flex flex-col justify-center items-start mx-4'}>
            <View className={'flex items-center gap-2'}>
              <span className={'total-price text-sm text-gray-500'}>实付金额：</span>
              <span className={'text-red-500 text-xl font-bold'}>￥{getFinalPrice().toFixed(2)}</span>
            </View>
            {selectedCoupon && (
              <View className={'text-xs text-gray-400'}>
                已优惠 ￥{getCouponDiscount().toFixed(2)}
              </View>
            )}
          </div>
          <div className={'buy-btn mx-4'}>
            <Button
              type="success"
              size="large"
              loading={payLoading}
              disabled={isTicketTemplateActive && quantity < minBuyQty}
              onClick={() => onPay(goods)}
            >
              {payLoading ? '支付中...' : '立即付款'}
            </Button>
          </div>
        </View>
      </div>
    </div>
  );
};

export default OrderConfirm;
