package shop.alien.dining.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.*;
import shop.alien.entity.store.dto.CartDTO;
import shop.alien.entity.store.dto.CartItemDTO;
import shop.alien.entity.store.vo.*;
import shop.alien.mapper.*;
import shop.alien.dining.config.BaseRedisService;
import shop.alien.dining.service.CartService;
import shop.alien.dining.service.DiningService;
import shop.alien.util.coupon.DiscountCouponExpirationUtil;
import shop.alien.util.coupon.LifeDiscountCouponStock;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 点餐服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DiningServiceImpl implements DiningService {

    private final StoreTableMapper storeTableMapper;
    private final StoreInfoMapper storeInfoMapper;
    private final StoreCuisineMapper storeCuisineMapper;
    private final StoreCuisineCategoryMapper storeCuisineCategoryMapper;
    private final StoreCuisineComboMapper storeCuisineComboMapper;
    private final StoreOrderDetailMapper storeOrderDetailMapper;
    private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
    private final CartService cartService;
    private final BaseRedisService baseRedisService;
    private final shop.alien.dining.service.StoreOrderService storeOrderService;
    private final shop.alien.mapper.StoreOrderMapper storeOrderMapper;
    private final shop.alien.dining.service.OrderLockService orderLockService;

    @Override
    public TableDiningStatusVO getTableDiningStatus(Integer tableId) {
        if (tableId == null) {
            return new TableDiningStatusVO(null, false, null);
        }
        StoreTable table = storeTableMapper.selectById(tableId);
        if (table == null) {
            return new TableDiningStatusVO(tableId, false, null);
        }
        // 就餐中(1)、加餐(3) 均视为就餐状态；且需已有就餐人数
        Integer status = table.getStatus();
        boolean inDining = (Integer.valueOf(1).equals(status) || Integer.valueOf(3).equals(status))
                && table.getDinerCount() != null && table.getDinerCount() > 0;
        Integer dinerCount = inDining ? table.getDinerCount() : null;
        return new TableDiningStatusVO(tableId, inDining, dinerCount);
    }

    @Override
    public DiningPageInfoVO getDiningPageInfo(Integer tableId, Integer dinerCount) {
        log.info("获取点餐页面信息, tableId={}, dinerCount={}", tableId, dinerCount);
        StoreTable table = storeTableMapper.selectById(tableId);
        if (table == null) {
            throw new RuntimeException("桌号不存在");
        }

        StoreInfo storeInfo = storeInfoMapper.selectById(table.getStoreId());
        if (storeInfo == null) {
            throw new RuntimeException("门店不存在");
        }

        // 第一个用户：传入用餐人数时，将餐桌置为就餐中并保存就餐人数
        if (dinerCount != null && dinerCount > 0) {
            table.setStatus(1); // 就餐中
            table.setDinerCount(dinerCount);
            storeTableMapper.updateById(table);
            log.info("首客选桌并填写用餐人数, tableId={}, dinerCount={}, 餐桌状态已置为就餐中", tableId, dinerCount);
        } else {
            // 第二个及后续用户：若餐桌已就餐中且表内已有就餐人数，直接使用
            if (Integer.valueOf(1).equals(table.getStatus()) && table.getDinerCount() != null && table.getDinerCount() > 0) {
                dinerCount = table.getDinerCount();
                log.info("餐桌已就餐中，使用已保存的就餐人数, tableId={}, dinerCount={}", tableId, dinerCount);
            } else {
                // 餐桌空闲且未传就餐人数时要求必填
                throw new RuntimeException("请选择用餐人数");
            }
        }

        DiningPageInfoVO vo = new DiningPageInfoVO();
        vo.setStoreName(storeInfo.getStoreName());
        vo.setTableNumber(table.getTableNumber());
        vo.setDinerCount(dinerCount);
        vo.setStoreId(table.getStoreId());
        vo.setTableId(tableId);

        return vo;
    }

    @Override
    public List<CuisineListVO> searchCuisines(Integer storeId, String keyword, Integer tableId) {
        log.info("搜索菜品, storeId={}, keyword={}, tableId={}", storeId, keyword, tableId);

        // 限制搜索关键词长度
        if (StringUtils.hasText(keyword) && keyword.length() > 10) {
            keyword = keyword.substring(0, 10);
        }

        LambdaQueryWrapper<StoreCuisine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreCuisine::getStoreId, storeId);
        wrapper.eq(StoreCuisine::getDeleteFlag, 0);
        wrapper.eq(StoreCuisine::getShelfStatus, 1); // 只查询上架的
        if (StringUtils.hasText(keyword)) {
            wrapper.like(StoreCuisine::getName, keyword);
        }
        wrapper.orderByDesc(StoreCuisine::getCreatedTime);

        List<StoreCuisine> cuisines = storeCuisineMapper.selectList(wrapper);
        return convertToCuisineListVO(cuisines, tableId);
    }

    @Override
    public List<CuisineListVO> getCuisinesByCategory(Integer storeId, Integer categoryId, Integer tableId, Integer page, Integer size) {
        log.info("根据分类获取菜品列表, storeId={}, categoryId={}, tableId={}, page={}, size={}", storeId, categoryId, tableId, page, size);

        if (page == null || page < 1) {
            page = 1;
        }
        if (size == null || size < 1) {
            size = 12;
        }

        LambdaQueryWrapper<StoreCuisine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreCuisine::getStoreId, storeId);
        wrapper.eq(StoreCuisine::getDeleteFlag, 0);
        wrapper.eq(StoreCuisine::getShelfStatus, 1); // 只查询上架的
        if (categoryId != null) {
            // 这里假设菜品表有category_id字段，如果没有需要关联查询
            // wrapper.eq(StoreCuisine::getCategoryId, categoryId);
        }
        wrapper.orderByDesc(StoreCuisine::getCreatedTime);

        // 分页查询
        int offset = (page - 1) * size;
        wrapper.last("LIMIT " + offset + ", " + size);

        List<StoreCuisine> cuisines = storeCuisineMapper.selectList(wrapper);
        return convertToCuisineListVO(cuisines, tableId);
    }

    @Override
    public CuisineDetailVO getCuisineDetail(Integer cuisineId, Integer tableId) {
        log.info("获取菜品详情, cuisineId={}, tableId={}", cuisineId, tableId);

        StoreCuisine cuisine = storeCuisineMapper.selectById(cuisineId);
        if (cuisine == null) {
            throw new RuntimeException("菜品不存在");
        }

        CuisineDetailVO vo = new CuisineDetailVO();
        // 手动映射所有字段，确保所有属性都被正确复制
        vo.setId(cuisine.getId());
        vo.setStoreId(cuisine.getStoreId());
        vo.setName(cuisine.getName());
        vo.setTotalPrice(cuisine.getTotalPrice());
        vo.setCuisineType(cuisine.getCuisineType());
        vo.setCategoryIds(cuisine.getCategoryIds());
        vo.setTags(cuisine.getTags());
        vo.setDishReview(cuisine.getDishReview());
        vo.setDescription(cuisine.getDescription());
        vo.setDetailContent(cuisine.getDetailContent());
        vo.setImageContent(cuisine.getImageContent());
        vo.setExtraNote(cuisine.getExtraNote());
        vo.setNeedReserve(cuisine.getNeedReserve());
        vo.setReserveRule(cuisine.getReserveRule());
        vo.setPeopleLimit(cuisine.getPeopleLimit());
        vo.setUsageRule(cuisine.getUsageRule());

        // 处理图片列表
        if (StringUtils.hasText(cuisine.getImages())) {
            List<String> images = Arrays.asList(cuisine.getImages().split(","));
            vo.setImages(images);
        } else {
            vo.setImages(new ArrayList<>());
        }

        // 计算月售数量
        vo.setMonthlySales(getMonthlySales(cuisineId));

        // 获取购物车数量
        CartDTO cart = cartService.getCart(tableId);
        if (cart.getItems() != null) {
            Optional<CartItemDTO> cartItem = cart.getItems().stream()
                    .filter(item -> item.getCuisineId().equals(cuisineId))
                    .findFirst();
            vo.setCartQuantity(cartItem.map(CartItemDTO::getQuantity).orElse(0));
        } else {
            vo.setCartQuantity(0);
        }

        // 如果是套餐，获取套餐包含的菜品
        if (cuisine.getCuisineType() != null && cuisine.getCuisineType() == 2) {
            LambdaQueryWrapper<StoreCuisineCombo> comboWrapper = new LambdaQueryWrapper<>();
            comboWrapper.eq(StoreCuisineCombo::getCid, cuisineId);
            comboWrapper.eq(StoreCuisineCombo::getDeleteFlag, 0);
            List<StoreCuisineCombo> combos = storeCuisineComboMapper.selectList(comboWrapper);

            List<CuisineComboItemVO> comboItems = combos.stream().map(combo -> {
                CuisineComboItemVO item = new CuisineComboItemVO();
                item.setCuisineId(combo.getSid());
                item.setQuantity(combo.getSnum());
                item.setCategory(combo.getCategory());
                // 查询菜品名称
                StoreCuisine comboCuisine = storeCuisineMapper.selectById(combo.getSid());
                if (comboCuisine != null) {
                    item.setCuisineName(comboCuisine.getName());
                }
                return item;
            }).collect(Collectors.toList());
            vo.setComboItems(comboItems);
        }

        return vo;
    }

    @Override
    public List<AvailableCouponVO> getAvailableCoupons(Integer storeId, Integer userId) {
        log.info("获取可领取优惠券列表, storeId={}, userId={}", storeId, userId);

        // 查询门店的优惠券
        LambdaQueryWrapper<LifeDiscountCoupon> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LifeDiscountCoupon::getStoreId, String.valueOf(storeId));
        wrapper.eq(LifeDiscountCoupon::getDeleteFlag, 0);
        wrapper.eq(LifeDiscountCoupon::getGetStatus, 1); // 开启领取
        wrapper.and(w -> w.eq(LifeDiscountCoupon::getUnlimitedQty, 1)
                .or()
                .gt(LifeDiscountCoupon::getSingleQty, 0));
        LocalDate now = LocalDate.now();
        wrapper.le(LifeDiscountCoupon::getStartDate, now);
        wrapper.ge(LifeDiscountCoupon::getEndDate, now);
        wrapper.orderByDesc(LifeDiscountCoupon::getCreatedTime);

        List<LifeDiscountCoupon> coupons = lifeDiscountCouponMapper.selectList(wrapper);

        // 查询用户已领取的优惠券
        Set<Integer> receivedCouponIds = new HashSet<>();
        if (userId != null) {
            LambdaQueryWrapper<LifeDiscountCouponUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(LifeDiscountCouponUser::getUserId, userId);
            List<LifeDiscountCouponUser> userCoupons = lifeDiscountCouponUserMapper.selectList(userWrapper);
            receivedCouponIds = userCoupons.stream()
                    .map(LifeDiscountCouponUser::getCouponId)
                    .collect(Collectors.toSet());
        }

        final Set<Integer> finalReceivedCouponIds = receivedCouponIds;
        return coupons.stream().map(coupon -> {
            AvailableCouponVO vo = new AvailableCouponVO();
            vo.setId(coupon.getId());
            vo.setName(coupon.getName());
            vo.setNominalValue(coupon.getNominalValue());
            vo.setMinimumSpendingAmount(coupon.getMinimumSpendingAmount());
            vo.setEndDate(coupon.getEndDate());
            vo.setIsReceived(finalReceivedCouponIds.contains(coupon.getId()));
            boolean hasStock = LifeDiscountCouponStock.hasTemplateStockRemaining(coupon.getUnlimitedQty(), coupon.getSingleQty());
            boolean inEnd = coupon.getEndDate() != null
                    && (coupon.getEndDate().isAfter(now) || coupon.getEndDate().isEqual(now));
            vo.setIsAvailable(hasStock && inEnd);
            vo.setLongTermValid(coupon.getLongTermValid());
            vo.setUnlimitedQty(coupon.getUnlimitedQty());
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public boolean receiveCoupon(Integer couponId, Integer userId) {
        log.info("领取优惠券, couponId={}, userId={}", couponId, userId);

        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(couponId);
        if (coupon == null) {
            throw new RuntimeException("优惠券不存在");
        }

        // 检查是否已领取
        LambdaQueryWrapper<LifeDiscountCouponUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LifeDiscountCouponUser::getUserId, userId);
        wrapper.eq(LifeDiscountCouponUser::getCouponId, couponId);
        LifeDiscountCouponUser existing = lifeDiscountCouponUserMapper.selectOne(wrapper);
        if (existing != null) {
            throw new RuntimeException("您已领取过该优惠券");
        }

        // 检查库存（发行量不限则跳过）
        if (!LifeDiscountCouponStock.hasTemplateStockRemaining(coupon.getUnlimitedQty(), coupon.getSingleQty())) {
            throw new RuntimeException("优惠券已领完");
        }

        // 创建用户优惠券记录
        LifeDiscountCouponUser userCoupon = new LifeDiscountCouponUser();
        userCoupon.setUserId(userId);
        userCoupon.setCouponId(couponId);
        userCoupon.setReceiveTime(new Date());
        userCoupon.setExpirationTime(DiscountCouponExpirationUtil.resolveLifeDiscountCouponExpiration(
                userCoupon.getReceiveTime(),
                coupon.getLongTermValid(),
                coupon.getSpecifiedDay(),
                coupon.getExpirationDate(),
                coupon.getValidDate(),
                coupon.getEndDate(),
                ZoneId.systemDefault()));
        userCoupon.setStatus(0); // 待使用
        lifeDiscountCouponUserMapper.insert(userCoupon);

        // 更新库存
        if (!LifeDiscountCouponStock.isUnlimitedQty(coupon.getUnlimitedQty()) && coupon.getSingleQty() != null) {
            coupon.setSingleQty(coupon.getSingleQty() - 1);
            lifeDiscountCouponMapper.updateById(coupon);
        }

        return true;
    }

    @Override
    public OrderConfirmVO getOrderConfirmInfo(Integer tableId, Integer dinerCount, Integer userId) {
        log.info("获取订单确认页面信息, tableId={}, dinerCount={}, userId={}", tableId, dinerCount, userId);

        // 获取点餐页面信息（就餐中且未传人数时，内部会使用桌台已保存的就餐人数）
        DiningPageInfoVO pageInfo = getDiningPageInfo(tableId, dinerCount);
        int effectiveDinerCount = pageInfo.getDinerCount() != null && pageInfo.getDinerCount() > 0
                ? pageInfo.getDinerCount() : (dinerCount != null ? dinerCount : 0);

        // 获取购物车
        CartDTO cart = cartService.getCart(tableId);

        // 为购物车项补全菜品标签（购物车从 DB 加载时可能无 tags）
        List<CartItemDTO> items = cart.getItems();
        if (items != null && !items.isEmpty()) {
            Set<Integer> cuisineIds = items.stream()
                    .map(CartItemDTO::getCuisineId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            if (!cuisineIds.isEmpty()) {
                List<StoreCuisine> cuisines = storeCuisineMapper.selectBatchIds(new ArrayList<>(cuisineIds));
                Map<Integer, String> tagsMap = new HashMap<>();
                if (cuisines != null) {
                    for (StoreCuisine c : cuisines) {
                        if (c.getTags() != null) {
                            tagsMap.put(c.getId(), c.getTags());
                        }
                    }
                }
                for (CartItemDTO item : items) {
                    if (item.getCuisineId() != null && item.getTags() == null) {
                        item.setTags(tagsMap.get(item.getCuisineId()));
                    }
                }
            }
        }

        // 检查订单锁定
        Integer lockUserId = orderLockService.checkOrderLock(tableId);
        boolean isLocked = lockUserId != null && !lockUserId.equals(userId);

        OrderConfirmVO vo = new OrderConfirmVO();
        vo.setStoreName(pageInfo.getStoreName());
        vo.setTableNumber(pageInfo.getTableNumber());
        vo.setDinerCount(pageInfo.getDinerCount() != null ? pageInfo.getDinerCount() : dinerCount);
        // 联系电话和备注由前端传入，这里不设置默认值
        vo.setItems(items != null ? items : cart.getItems());
        vo.setTotalAmount(cart.getTotalAmount());
        vo.setIsLocked(isLocked);
        vo.setLockUserId(lockUserId);

        // 计算餐具费（默认1元/人）
        BigDecimal tablewareUnitPrice = new BigDecimal("1.00");
        BigDecimal tablewareFee = BigDecimal.ZERO;
        if (effectiveDinerCount > 0) {
            tablewareFee = tablewareUnitPrice.multiply(BigDecimal.valueOf(effectiveDinerCount));
        }
        vo.setTablewareFee(tablewareFee);
        vo.setTablewareUnitPrice(tablewareUnitPrice);

        // 自动匹配最优惠的优惠券
        List<AvailableCouponVO> availableCoupons = new ArrayList<>();
        if (userId != null && cart.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
            availableCoupons = getAvailableCoupons(pageInfo.getStoreId(), userId);
            // 过滤出可用的优惠券（已领取且满足最低消费）
            BigDecimal totalWithTableware = cart.getTotalAmount().add(tablewareFee);
            // 需要查询优惠券详情来计算实际优惠金额（用于排序）
            List<Integer> couponIds = availableCoupons.stream()
                    .filter(c -> c.getIsReceived() && c.getIsAvailable())
                    .filter(c -> totalWithTableware.compareTo(c.getMinimumSpendingAmount() != null ? c.getMinimumSpendingAmount() : BigDecimal.ZERO) >= 0)
                    .map(AvailableCouponVO::getId)
                    .collect(Collectors.toList());
            
            // 查询优惠券详情用于计算实际优惠金额
            Map<Integer, LifeDiscountCoupon> couponMap = new HashMap<>();
            if (!couponIds.isEmpty()) {
                List<LifeDiscountCoupon> couponDetails = lifeDiscountCouponMapper.selectBatchIds(couponIds);
                couponMap = couponDetails.stream().collect(Collectors.toMap(LifeDiscountCoupon::getId, c -> c));
            }
            
            final BigDecimal finalTotal = totalWithTableware;
            final Map<Integer, LifeDiscountCoupon> finalCouponMap = couponMap;
            List<AvailableCouponVO> usableCoupons = availableCoupons.stream()
                    .filter(c -> c.getIsReceived() && c.getIsAvailable())
                    .filter(c -> totalWithTableware.compareTo(c.getMinimumSpendingAmount() != null ? c.getMinimumSpendingAmount() : BigDecimal.ZERO) >= 0)
                    .sorted((a, b) -> {
                        // 根据实际优惠金额排序（考虑折扣券）
                        BigDecimal discountA = calculateDiscountAmountForVO(a, finalCouponMap, finalTotal);
                        BigDecimal discountB = calculateDiscountAmountForVO(b, finalCouponMap, finalTotal);
                        return discountB.compareTo(discountA); // 降序排列
                    })
                    .collect(Collectors.toList());

            if (!usableCoupons.isEmpty()) {
                AvailableCouponVO bestCoupon = usableCoupons.get(0);
                vo.setCouponId(bestCoupon.getId());
                vo.setCouponName(bestCoupon.getName());
                // 根据优惠券类型计算优惠金额
                // 需要查询优惠券详情来计算折扣券的优惠金额
                LifeDiscountCoupon couponDetail = lifeDiscountCouponMapper.selectByIdIncludeDeleted(bestCoupon.getId());
                BigDecimal discountAmount = calculateDiscountAmount(couponDetail, cart.getTotalAmount().add(tablewareFee));
                BigDecimal totalAmount = cart.getTotalAmount().add(tablewareFee);
                vo.setDiscountAmount(discountAmount);
                vo.setPayAmount(totalAmount.subtract(discountAmount));
            } else {
                vo.setPayAmount(cart.getTotalAmount().add(tablewareFee));
            }
        } else {
            vo.setPayAmount(cart.getTotalAmount().add(tablewareFee));
        }
        vo.setAvailableCoupons(availableCoupons);

        return vo;
    }

    @Override
    public boolean lockOrder(Integer tableId, Integer userId) {
        return orderLockService.lockOrder(tableId, userId);
    }

    @Override
    public void unlockOrder(Integer tableId, Integer userId) {
        orderLockService.unlockOrder(tableId, userId);
    }

    @Override
    public Integer checkOrderLock(Integer tableId) {
        return orderLockService.checkOrderLock(tableId);
    }

    /**
     * 转换为菜品列表VO
     */
    private List<CuisineListVO> convertToCuisineListVO(List<StoreCuisine> cuisines, Integer tableId) {
        // 获取购物车
        CartDTO cart = cartService.getCart(tableId);
        Map<Integer, Integer> cartQuantityMap = new HashMap<>();
        if (cart.getItems() != null) {
            cartQuantityMap = cart.getItems().stream()
                    .collect(Collectors.toMap(CartItemDTO::getCuisineId, CartItemDTO::getQuantity));
        }

        // 批量查询月售数量
        Map<Integer, Integer> monthlySalesMap = new HashMap<>();
        for (StoreCuisine cuisine : cuisines) {
            monthlySalesMap.put(cuisine.getId(), getMonthlySales(cuisine.getId()));
        }

        final Map<Integer, Integer> finalCartQuantityMap = cartQuantityMap;
        final Map<Integer, Integer> finalMonthlySalesMap = monthlySalesMap;

        return cuisines.stream().map(cuisine -> {
            CuisineListVO vo = new CuisineListVO();
            BeanUtils.copyProperties(cuisine, vo);
            vo.setPrice(cuisine.getTotalPrice());

            // 处理首张图片
            if (StringUtils.hasText(cuisine.getImages())) {
                String[] images = cuisine.getImages().split(",");
                vo.setFirstImage(images.length > 0 ? images[0] : null);
            }

            // 设置购物车数量
            vo.setCartQuantity(finalCartQuantityMap.getOrDefault(cuisine.getId(), 0));

            // 设置月售数量
            vo.setMonthlySales(finalMonthlySalesMap.getOrDefault(cuisine.getId(), 0));

            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 获取菜品月售数量（当月1日至当前日期）
     */
    private Integer getMonthlySales(Integer cuisineId) {
        try {
            // 计算当月1日
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date monthStart = calendar.getTime();

            // 查询订单明细中该菜品的销售数量
            LambdaQueryWrapper<StoreOrderDetail> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreOrderDetail::getCuisineId, cuisineId);
            wrapper.eq(StoreOrderDetail::getDeleteFlag, 0);
            wrapper.ge(StoreOrderDetail::getCreatedTime, monthStart);
            // 只统计已支付的订单
            wrapper.inSql(StoreOrderDetail::getOrderId,
                    "SELECT id FROM store_order WHERE pay_status = 1 AND delete_flag = 0");

            List<StoreOrderDetail> details = storeOrderDetailMapper.selectList(wrapper);
            return details.stream().mapToInt(StoreOrderDetail::getQuantity).sum();
        } catch (Exception e) {
            log.error("获取月售数量失败, cuisineId={}", cuisineId, e);
            return 0;
        }
    }

    @Override
    public shop.alien.entity.store.vo.OrderSettlementVO getOrderSettlementInfo(Integer orderId, Integer userId) {
        log.info("获取订单结算确认页面信息, orderId={}, userId={}", orderId, userId);

        // 查询订单
        shop.alien.entity.store.StoreOrder order = storeOrderService.getOrderById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 查询订单明细
        LambdaQueryWrapper<shop.alien.entity.store.StoreOrderDetail> detailWrapper = new LambdaQueryWrapper<>();
        detailWrapper.eq(shop.alien.entity.store.StoreOrderDetail::getOrderId, orderId);
        detailWrapper.eq(shop.alien.entity.store.StoreOrderDetail::getDeleteFlag, 0);
        detailWrapper.orderByDesc(shop.alien.entity.store.StoreOrderDetail::getCreatedTime);
        List<shop.alien.entity.store.StoreOrderDetail> details = storeOrderDetailMapper.selectList(detailWrapper);

        // 批量查询菜品标签
        Set<Integer> cuisineIds = details.stream()
                .map(shop.alien.entity.store.StoreOrderDetail::getCuisineId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Map<Integer, String> cuisineIdToTags = new HashMap<>();
        if (!cuisineIds.isEmpty()) {
            List<StoreCuisine> cuisines = storeCuisineMapper.selectBatchIds(new ArrayList<>(cuisineIds));
            if (cuisines != null) {
                for (StoreCuisine c : cuisines) {
                    if (c.getTags() != null) {
                        cuisineIdToTags.put(c.getId(), c.getTags());
                    }
                }
            }
        }

        // 转换为CartItemDTO（含菜品标签）
        Map<Integer, String> finalTagsMap = cuisineIdToTags;
        List<shop.alien.entity.store.dto.CartItemDTO> items = details.stream().map(detail -> {
            shop.alien.entity.store.dto.CartItemDTO item = new shop.alien.entity.store.dto.CartItemDTO();
            item.setCuisineId(detail.getCuisineId());
            item.setCuisineName(detail.getCuisineName());
            item.setCuisineType(detail.getCuisineType());
            item.setCuisineImage(detail.getCuisineImage());
            item.setUnitPrice(detail.getUnitPrice());
            item.setQuantity(detail.getQuantity());
            item.setSubtotalAmount(detail.getSubtotalAmount());
            item.setAddUserId(detail.getAddUserId());
            item.setAddUserPhone(detail.getAddUserPhone());
            item.setRemark(detail.getRemark());
            item.setTags(detail.getCuisineId() != null ? finalTagsMap.get(detail.getCuisineId()) : null);
            return item;
        }).collect(Collectors.toList());

        // 查询门店信息
        shop.alien.entity.store.StoreInfo storeInfo = storeInfoMapper.selectById(order.getStoreId());

        // 检查结算锁定
        Integer lockUserId = orderLockService.checkSettlementLock(orderId);
        boolean isLocked = lockUserId != null && !lockUserId.equals(userId);

        shop.alien.entity.store.vo.OrderSettlementVO vo = new shop.alien.entity.store.vo.OrderSettlementVO();
        vo.setOrderId(order.getId());
        vo.setOrderNo(order.getOrderNo());
        vo.setStoreName(storeInfo != null ? storeInfo.getStoreName() : null);
        vo.setTableNumber(order.getTableNumber());
        vo.setDinerCount(order.getDinerCount());
        vo.setContactPhone(order.getContactPhone());
        vo.setRemark(order.getRemark());
        vo.setItems(items);
        vo.setTotalAmount(order.getTotalAmount());
        vo.setTablewareFee(order.getTablewareFee() != null ? order.getTablewareFee() : BigDecimal.ZERO);
        vo.setCouponId(order.getCouponId());
        vo.setDiscountAmount(order.getDiscountAmount() != null ? order.getDiscountAmount() : BigDecimal.ZERO);
        vo.setPayAmount(order.getPayAmount());
        vo.setIsLocked(isLocked);
        vo.setLockUserId(lockUserId);

        // 查询优惠券名称
        if (order.getCouponId() != null) {
            shop.alien.entity.store.LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(order.getCouponId());
            if (coupon != null) {
                vo.setCouponName(coupon.getName());
            }
        }

        return vo;
    }

    @Override
    public boolean lockSettlement(Integer orderId, Integer userId) {
        return orderLockService.lockSettlement(orderId, userId);
    }

    @Override
    public void unlockSettlement(Integer orderId, Integer userId) {
        orderLockService.unlockSettlement(orderId, userId);
    }

    @Override
    public Integer checkSettlementLock(Integer orderId) {
        return orderLockService.checkSettlementLock(orderId);
    }

    /**
     * 计算优惠金额：根据优惠券类型（满减券或折扣券）计算
     *
     * @param coupon           优惠券对象
     * @param totalWithTableware 订单总金额（含餐具费）
     * @return 优惠金额
     */
    private BigDecimal calculateDiscountAmount(LifeDiscountCoupon coupon, BigDecimal totalWithTableware) {
        if (coupon == null || totalWithTableware == null || totalWithTableware.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }

        Integer couponType = coupon.getCouponType();
        BigDecimal discountAmount = BigDecimal.ZERO;

        if (couponType != null && couponType == 2) {
            // 折扣券：根据折扣率计算优惠金额
            // discountRate: 0-100，例如80表示8折，优惠金额 = 订单金额 * (100 - discountRate) / 100
            BigDecimal discountRate = coupon.getDiscountRate();
            if (discountRate != null && discountRate.compareTo(BigDecimal.ZERO) > 0 && discountRate.compareTo(new BigDecimal(100)) <= 0) {
                // 计算折扣后的金额
                BigDecimal discountedAmount = totalWithTableware.multiply(discountRate).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                // 优惠金额 = 原价 - 折扣后价格
                discountAmount = totalWithTableware.subtract(discountedAmount);
            }
        } else {
            // 满减券（默认或couponType=1）：使用nominalValue
            discountAmount = coupon.getNominalValue();
            if (discountAmount == null) {
                discountAmount = BigDecimal.ZERO;
            }
            // 优惠金额不能超过订单总金额
            if (discountAmount.compareTo(totalWithTableware) > 0) {
                discountAmount = totalWithTableware;
            }
        }

        return discountAmount;
    }

    /**
     * 为VO计算优惠金额（用于排序）
     *
     * @param vo          优惠券VO
     * @param couponMap   优惠券详情Map
     * @param totalAmount 订单总金额
     * @return 优惠金额
     */
    private BigDecimal calculateDiscountAmountForVO(AvailableCouponVO vo, Map<Integer, LifeDiscountCoupon> couponMap, BigDecimal totalAmount) {
        if (vo == null || totalAmount == null || totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }

        LifeDiscountCoupon coupon = couponMap.get(vo.getId());
        if (coupon == null) {
            // 如果没有详情，使用nominalValue作为默认值
            return vo.getNominalValue() != null ? vo.getNominalValue() : BigDecimal.ZERO;
        }

        return calculateDiscountAmount(coupon, totalAmount);
    }
}
