package shop.alien.store.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.aliyun.tea.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.*;
import shop.alien.entity.store.dto.LifeDiscountCouponDto;
import shop.alien.entity.store.vo.LifeCouponStatusVo;
import shop.alien.entity.store.vo.LifeDiscountCouponStoreFriendVo;
import shop.alien.entity.store.vo.LifeDiscountCouponUserWebVo;
import shop.alien.entity.store.vo.LifeDiscountCouponVo;
import shop.alien.mapper.*;
import shop.alien.store.service.LifeDiscountCouponQuantumRulesService;
import shop.alien.store.service.LifeDiscountCouponService;
import shop.alien.store.service.LifeDiscountCouponUserService;
import shop.alien.util.common.constant.DiscountCouponEnum;
import shop.alien.util.coupon.DiscountCouponExpirationUtil;
import shop.alien.util.coupon.LifeDiscountCouponStock;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券表 服务实现类
 * </p>
 *
 * @author ssk
 * @since 2025-02-07
 */
@Service
@RequiredArgsConstructor
public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCouponMapper, LifeDiscountCoupon> implements LifeDiscountCouponService {

    final static String HOLIDAY_RULE_TITLE = "节假日规则：";
    final static String WEEK_RULE_TITLE = "周中规则：";
    final static String MINIMUM_SPENDING_AMOUNT = "最低限制消费金额：";
    final static String NOT_USE = "不可用;";

    private final LifeDiscountCouponMapper lifeDiscountCouponMapper;

    private final LifeDiscountCouponUnavailableRulesMapper lifeDiscountCouponUnavailableRulesMapper;

    private final LifeDiscountCouponQuantumRulesMapper lifeDiscountCouponQuantumRulesMapper;

    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;

    private final EssentialHolidayComparisonMapper essentialHolidayComparisonMapper;

    private final LifeDiscountCouponStoreFriendMapper lifeDiscountCouponStoreFriendMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final StoreUserMapper storeUserMapper;

    private final LifeDiscountCouponQuantumRulesService lifeDiscountCouponQuantumRulesService;

    private final LifeDiscountCouponUserService lifeDiscountCouponUserService;

    private final LifeCouponMapper lifeCouponMapper;

    @Override
    public boolean addDiscountCoupon(LifeDiscountCouponDto lifeDiscountCouponDto) {
        try {
            boolean isDraft = lifeDiscountCouponDto.getCouponStatus() != null && lifeDiscountCouponDto.getCouponStatus() == 0;
            validateStoreDiscountCouponForCreate(lifeDiscountCouponDto, isDraft);
            LifeDiscountCoupon lifeDiscountCoupon = buildDiscountCouponEntityForInsert(lifeDiscountCouponDto, isDraft);
            lifeDiscountCouponMapper.insert(lifeDiscountCoupon);
            insertDiscountCouponUnavailableAndQuantumRules(lifeDiscountCoupon.getId(), lifeDiscountCouponDto);
            return true;
        } catch (BeansException e) {
            log.error("LifeDiscountCouponServiceImpl.addDiscountCoupon Bean/copy error", e);
            return false;
        }
    }

    /**
     * 门店新增优惠券入参校验（仅满减/折扣 couponType；代金券不在此接口创建）。
     */
    private void validateStoreDiscountCouponForCreate(LifeDiscountCouponDto dto, boolean isDraft) {
        if (!isDraft && dto.getType() != null && !Integer.valueOf(1).equals(dto.getType())) {
            throw new IllegalArgumentException("本接口仅创建门店优惠券（type=1），请勿传入其它业务类型");
        }
        if (!isDraft) {
            Integer couponType = dto.getCouponType();
            if (couponType == null) {
                throw new IllegalArgumentException("优惠券类型不能为空");
            }
            if (couponType == 1) {
                if (dto.getNominalValue() == null || dto.getNominalValue().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new IllegalArgumentException("满减券必须填写面值（减免金额）");
                }
                if (dto.getMinimumSpendingAmount() != null && dto.getMinimumSpendingAmount().compareTo(BigDecimal.ZERO) < 0) {
                    throw new IllegalArgumentException("满减券最低消费金额不能为负数");
                }
            } else if (couponType == 2) {
                if (dto.getDiscountRate() == null
                        || dto.getDiscountRate().compareTo(BigDecimal.ZERO) <= 0
                        || dto.getDiscountRate().compareTo(new BigDecimal(100)) > 0) {
                    throw new IllegalArgumentException("折扣券必须填写折扣率（0-100，例如80表示8折）");
                }
                if (dto.getMinimumSpendingAmount() != null && dto.getMinimumSpendingAmount().compareTo(BigDecimal.ZERO) < 0) {
                    throw new IllegalArgumentException("折扣券最低消费金额不能为负数");
                }
            } else {
                throw new IllegalArgumentException("优惠券类型无效，只能为1（满减券）或2（折扣券）");
            }
        } else {
            if (dto.getMinimumSpendingAmount() != null && dto.getMinimumSpendingAmount().compareTo(BigDecimal.ZERO) < 0) {
                throw new IllegalArgumentException("最低消费金额不能为负数");
            }
            if (dto.getNominalValue() != null && dto.getNominalValue().compareTo(BigDecimal.ZERO) < 0) {
                throw new IllegalArgumentException("面值不能为负数");
            }
            if (dto.getDiscountRate() != null && dto.getDiscountRate().compareTo(BigDecimal.ZERO) < 0) {
                throw new IllegalArgumentException("折扣率不能为负数");
            }
        }
    }

    private LifeDiscountCoupon buildDiscountCouponEntityForInsert(LifeDiscountCouponDto lifeDiscountCouponDto, boolean isDraft) {
        LifeDiscountCoupon lifeDiscountCoupon = new LifeDiscountCoupon();
        BeanUtils.copyProperties(lifeDiscountCouponDto, lifeDiscountCoupon);
        lifeDiscountCoupon.setType(1);

        BigDecimal nominalValue = lifeDiscountCouponDto.getNominalValue();
        if (nominalValue != null) {
            lifeDiscountCoupon.setNominalValue(nominalValue);
        }

        BigDecimal minimumSpendingAmount = lifeDiscountCouponDto.getMinimumSpendingAmount();
        if (minimumSpendingAmount != null) {
            lifeDiscountCoupon.setMinimumSpendingAmount(minimumSpendingAmount);
        } else {
            lifeDiscountCoupon.setMinimumSpendingAmount(BigDecimal.ZERO);
        }

        if (lifeDiscountCoupon.getLongTermValid() == null) {
            lifeDiscountCoupon.setLongTermValid(0);
        }
        if (lifeDiscountCoupon.getUnlimitedQty() == null) {
            lifeDiscountCoupon.setUnlimitedQty(0);
        }

        if (!isDraft) {
            if (!Integer.valueOf(1).equals(lifeDiscountCoupon.getLongTermValid())
                    && !DiscountCouponExpirationUtil.templateHasPositiveDayValidity(
                    lifeDiscountCoupon.getSpecifiedDay(), lifeDiscountCoupon.getExpirationDate())) {
                throw new IllegalArgumentException("请配置有效期天数（expirationDate 或 specifiedDay）或开启长期有效");
            }
        }
        clearTemplateObsoleteAbsoluteUsePeriod(lifeDiscountCoupon);

        Date now = new Date();
        LocalDate localNow = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        if (Integer.valueOf(1).equals(lifeDiscountCouponDto.getCouponStatus())
                && lifeDiscountCoupon.getBeginGetDate() != null
                && lifeDiscountCoupon.getEndGetDate() != null) {
            int startResult = localNow.compareTo(lifeDiscountCoupon.getBeginGetDate());
            int endResult = localNow.compareTo(lifeDiscountCoupon.getEndGetDate());
            if (startResult < 0 || endResult > 0) {
                lifeDiscountCoupon.setGetStatus(0);
            } else {
                lifeDiscountCoupon.setGetStatus(1);
            }
        }
        return lifeDiscountCoupon;
    }

    private void insertDiscountCouponUnavailableAndQuantumRules(Integer discountCouponId, LifeDiscountCouponDto lifeDiscountCouponDto) {
        LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRules = new LifeDiscountCouponUnavailableRules();
        lifeDiscountCouponUnavailableRules.setDiscountCouponId(discountCouponId);
        lifeDiscountCouponUnavailableRules.setUnavailableRuleType(DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue());
        if (CollectionUtils.isNotEmpty(lifeDiscountCouponDto.getWeeklyDisabledList())) {
            lifeDiscountCouponDto.getWeeklyDisabledList().forEach(weeklyDisabled -> {
                lifeDiscountCouponUnavailableRules.setUnavailableRuleValue(weeklyDisabled);
                lifeDiscountCouponUnavailableRulesMapper.insert(lifeDiscountCouponUnavailableRules);
            });
        }

        lifeDiscountCouponUnavailableRules.setUnavailableRuleType(DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue());
        if (CollectionUtils.isNotEmpty(lifeDiscountCouponDto.getHolidayDisabledList())) {
            lifeDiscountCouponDto.getHolidayDisabledList().forEach(holidayDisabled -> {
                lifeDiscountCouponUnavailableRules.setUnavailableRuleValue(holidayDisabled);
                lifeDiscountCouponUnavailableRulesMapper.insert(lifeDiscountCouponUnavailableRules);
            });
        }

        lifeDiscountCouponUnavailableRules.setUnavailableRuleType(DiscountCouponEnum.CLAIM_RULE.getValue());
        String claimRule = lifeDiscountCouponDto.getClaimRule();
        if (claimRule != null && claimRule.equals(DiscountCouponEnum.CUSTOMIZE.getValue())) {
            lifeDiscountCouponUnavailableRules.setCustomizeValue(lifeDiscountCouponDto.getClaimRuleCustomizeValue());
        }
        lifeDiscountCouponUnavailableRules.setUnavailableRuleValue(lifeDiscountCouponDto.getClaimRule());
        lifeDiscountCouponUnavailableRulesMapper.insert(lifeDiscountCouponUnavailableRules);

        List<LifeDiscountCouponQuantumRules> availableTimeQuantumList = lifeDiscountCouponDto.getAvailableTimeQuantum();
        if (CollectionUtils.isNotEmpty(availableTimeQuantumList)) {
            availableTimeQuantumList.forEach(availableTimeQuantum -> availableTimeQuantum.setDiscountCouponId(discountCouponId));
            lifeDiscountCouponQuantumRulesService.saveBatch(availableTimeQuantumList);
        }

        List<LifeDiscountCouponQuantumRules> customizeUnavailableTimeQuantumList = lifeDiscountCouponDto.getCustomizeUnavailableTimeQuantum();
        if (CollectionUtils.isNotEmpty(customizeUnavailableTimeQuantumList)) {
            customizeUnavailableTimeQuantumList.forEach(customizeUnavailableTimeQuantum ->
                    customizeUnavailableTimeQuantum.setDiscountCouponId(discountCouponId));
            lifeDiscountCouponQuantumRulesService.saveBatch(customizeUnavailableTimeQuantumList);
        }
    }

    @Override
    public boolean editDiscountCoupon(LifeDiscountCouponDto lifeDiscountCouponDto) {
        try {
            //发布优惠券表信息
            LifeDiscountCoupon lifeDiscountCoupon = new LifeDiscountCoupon();
            lifeDiscountCoupon.setId(Integer.parseInt(lifeDiscountCouponDto.getCouponId()));
            BeanUtils.copyProperties(lifeDiscountCouponDto, lifeDiscountCoupon);

            LifeDiscountCoupon existingCouponForFlags = lifeDiscountCouponMapper.selectById(lifeDiscountCoupon.getId());
            if (existingCouponForFlags != null) {
                if (lifeDiscountCouponDto.getLongTermValid() == null) {
                    lifeDiscountCoupon.setLongTermValid(existingCouponForFlags.getLongTermValid());
                }
                if (lifeDiscountCouponDto.getUnlimitedQty() == null) {
                    lifeDiscountCoupon.setUnlimitedQty(existingCouponForFlags.getUnlimitedQty());
                }
                if (lifeDiscountCouponDto.getExpirationDate() == null) {
                    lifeDiscountCoupon.setExpirationDate(existingCouponForFlags.getExpirationDate());
                }
                if (lifeDiscountCouponDto.getSpecifiedDay() == null) {
                    lifeDiscountCoupon.setSpecifiedDay(existingCouponForFlags.getSpecifiedDay());
                }
                if (lifeDiscountCouponDto.getCouponStatus() == null) {
                    lifeDiscountCoupon.setCouponStatus(existingCouponForFlags.getCouponStatus());
                }
            }

            boolean editDraft = lifeDiscountCoupon.getCouponStatus() != null && lifeDiscountCoupon.getCouponStatus() == 0;
            if (!editDraft) {
                if (!Integer.valueOf(1).equals(lifeDiscountCoupon.getLongTermValid())
                        && !DiscountCouponExpirationUtil.templateHasPositiveDayValidity(
                        lifeDiscountCoupon.getSpecifiedDay(), lifeDiscountCoupon.getExpirationDate())) {
                    throw new IllegalArgumentException("请配置有效期天数（expirationDate 或 specifiedDay）或开启长期有效");
                }
            }
            
            // 显式设置面值（nominalValue），确保能正确保存
            BigDecimal nominalValue = lifeDiscountCouponDto.getNominalValue();
            if (nominalValue != null) {
                lifeDiscountCoupon.setNominalValue(nominalValue);
            }
            
            // 显式设置最低消费金额（门槛费），确保能正确保存
            // 如果 DTO 中有值（包括0），使用 DTO 的值；如果为 null，设置为 0（表示无门槛）
            BigDecimal minimumSpendingAmount = lifeDiscountCouponDto.getMinimumSpendingAmount();
            if (minimumSpendingAmount != null) {
                lifeDiscountCoupon.setMinimumSpendingAmount(minimumSpendingAmount);
            } else {
                lifeDiscountCoupon.setMinimumSpendingAmount(BigDecimal.ZERO);
            }
            

            // 根据开始领取时间判断可领取状态
            // 判断是否在领取时间内
            Date now = new Date();
            Instant instant = now.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate localNow = instant.atZone(zoneId).toLocalDate();
            if (Integer.valueOf(1).equals(lifeDiscountCouponDto.getCouponStatus())
                    && lifeDiscountCoupon.getBeginGetDate() != null
                    && lifeDiscountCoupon.getEndGetDate() != null) {
                int startResult = localNow.compareTo(lifeDiscountCoupon.getBeginGetDate());
                int endResult = localNow.compareTo(lifeDiscountCoupon.getEndGetDate());
                if (startResult < 0 || endResult > 0) {
                    lifeDiscountCoupon.setGetStatus(0);
                } else {
                    lifeDiscountCoupon.setGetStatus(1);
                }
            } else if (lifeDiscountCouponDto.getCouponStatus() != null && lifeDiscountCouponDto.getCouponStatus() == 0) {
                lifeDiscountCoupon.setGetStatus(0);
            }

            lifeDiscountCouponMapper.updateById(lifeDiscountCoupon);
            //发布优惠券规则信息
            //先删除之前所有规则
            LambdaQueryWrapper<LifeDiscountCouponUnavailableRules> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LifeDiscountCouponUnavailableRules::getDiscountCouponId, lifeDiscountCoupon.getId());
            lifeDiscountCouponUnavailableRulesMapper.delete(queryWrapper);

            //周中规则保存
            LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRules = new LifeDiscountCouponUnavailableRules();
            lifeDiscountCouponUnavailableRules.setDiscountCouponId(lifeDiscountCoupon.getId());
            lifeDiscountCouponUnavailableRules.setUnavailableRuleType(DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue());
            if (CollectionUtils.isNotEmpty(lifeDiscountCouponDto.getWeeklyDisabledList())) {
                lifeDiscountCouponDto.getWeeklyDisabledList().forEach(weeklyDisabled -> {
                    lifeDiscountCouponUnavailableRules.setUnavailableRuleValue(weeklyDisabled);
                    lifeDiscountCouponUnavailableRulesMapper.insert(lifeDiscountCouponUnavailableRules);
                });
            }

            //节假日规则保存
            lifeDiscountCouponUnavailableRules.setUnavailableRuleType(DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue());
            if (CollectionUtils.isNotEmpty(lifeDiscountCouponDto.getHolidayDisabledList())) {
                lifeDiscountCouponDto.getHolidayDisabledList().forEach(holidayDisabled -> {
                    lifeDiscountCouponUnavailableRules.setUnavailableRuleValue(holidayDisabled);
                    lifeDiscountCouponUnavailableRulesMapper.insert(lifeDiscountCouponUnavailableRules);
                });
            }

            //领取规则
            lifeDiscountCouponUnavailableRules.setUnavailableRuleType(DiscountCouponEnum.CLAIM_RULE.getValue());
            lifeDiscountCouponUnavailableRules.setUnavailableRuleValue(lifeDiscountCouponDto.getClaimRule());
            lifeDiscountCouponUnavailableRulesMapper.insert(lifeDiscountCouponUnavailableRules);

            // 删除优惠券时间段规则信息
            LambdaQueryWrapper<LifeDiscountCouponQuantumRules> lifeDiscountCouponQuantumRulesLambdaQueryWrapper = new LambdaQueryWrapper<>();
            lifeDiscountCouponQuantumRulesLambdaQueryWrapper.eq(LifeDiscountCouponQuantumRules::getDiscountCouponId, lifeDiscountCoupon.getId());
            lifeDiscountCouponQuantumRulesMapper.delete(lifeDiscountCouponQuantumRulesLambdaQueryWrapper);

            // 保存指定时间段可用规则
            List<LifeDiscountCouponQuantumRules> availableTimeQuantumList = lifeDiscountCouponDto.getAvailableTimeQuantum();
            if (CollectionUtils.isNotEmpty(availableTimeQuantumList)) {
                availableTimeQuantumList.forEach(availableTimeQuantum -> {
                    availableTimeQuantum.setDiscountCouponId(lifeDiscountCoupon.getId());
                });
                lifeDiscountCouponQuantumRulesService.saveBatch(availableTimeQuantumList);
            }
            // 保存自定义时间段不可用规则
            List<LifeDiscountCouponQuantumRules> customizeUnavailableTimeQuantumList = lifeDiscountCouponDto.getCustomizeUnavailableTimeQuantum();
            if (CollectionUtils.isNotEmpty(customizeUnavailableTimeQuantumList)) {
                customizeUnavailableTimeQuantumList.forEach(customizeUnavailableTimeQuantum -> {
                    customizeUnavailableTimeQuantum.setDiscountCouponId(lifeDiscountCoupon.getId());
                });
                lifeDiscountCouponQuantumRulesService.saveBatch(customizeUnavailableTimeQuantumList);
            }

        } catch (BeansException e) {
            log.error("LifeDiscountCouponServiceImpl.editDiscountCoupon ERROR Msg=" + e.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public boolean deleteDiscountCoupon(Integer id) {
        if (id == null) {
            throw new IllegalArgumentException("优惠券ID不能为空");
        }
        LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectById(id);
        if (coupon == null) {
            throw new IllegalArgumentException("优惠券不存在");
        }
        lifeDiscountCouponMapper.deleteById(id);
        lifeDiscountCouponUnavailableRulesMapper.delete(
                new LambdaQueryWrapper<LifeDiscountCouponUnavailableRules>()
                        .eq(LifeDiscountCouponUnavailableRules::getDiscountCouponId, id));
        lifeDiscountCouponQuantumRulesMapper.delete(
                new LambdaQueryWrapper<LifeDiscountCouponQuantumRules>()
                        .eq(LifeDiscountCouponQuantumRules::getDiscountCouponId, id));
        return true;
    }

    @Override
    public boolean cutDiscountCouponStatus(String counponId) {
        LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectById(counponId);
        if (lifeDiscountCoupon.getGetStatus() == Integer.parseInt(DiscountCouponEnum.NO_GET.getValue())) {
            Date now = new Date();
            Instant instant = now.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate localNow = instant.atZone(zoneId).toLocalDate();
            lifeDiscountCoupon.setBeginGetDate(localNow);
        }
        lifeDiscountCoupon.setGetStatus(lifeDiscountCoupon.getGetStatus() == Integer.parseInt(DiscountCouponEnum.NO_GET.getValue()) ? Integer.parseInt(DiscountCouponEnum.CAN_GET.getValue()) : Integer.parseInt(DiscountCouponEnum.NO_GET.getValue()));
        lifeDiscountCouponMapper.updateById(lifeDiscountCoupon);
        return true;
    }

    @Override
    public LifeDiscountCouponVo getCounponDetailById(String counponId, UserLoginInfo userLoginInfo) {
        int couponIdInt = Integer.parseInt(counponId);
        LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(couponIdInt);
        LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
        lifeDiscountCouponVo.setCouponId(couponIdInt);
        if (lifeDiscountCoupon == null) {
            return lifeDiscountCouponVo;
        }
        BeanUtils.copyProperties(lifeDiscountCoupon, lifeDiscountCouponVo);
        //查规则信息
        List<LifeDiscountCouponUnavailableRules> lifeDiscountCouponUnavailableRules =
                lifeDiscountCouponUnavailableRulesMapper.listByDiscountCouponIdIncludeDeleted(couponIdInt);

        List<String> weeklyDisabledList = new ArrayList<>();
        List<String> holidayDisabledList = new ArrayList<>();
        String claimRule = "";
        for (LifeDiscountCouponUnavailableRules rule : lifeDiscountCouponUnavailableRules) {
            if (rule.getUnavailableRuleType().equals(DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue())) {
                weeklyDisabledList.add(rule.getUnavailableRuleValue());
            }
            if (rule.getUnavailableRuleType().equals(DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue())) {
                holidayDisabledList.add(rule.getUnavailableRuleValue());
            }
            if (rule.getUnavailableRuleType().equals(DiscountCouponEnum.CLAIM_RULE.getValue())) {
                claimRule = rule.getUnavailableRuleValue();
            }
        }
        lifeDiscountCouponVo.setWeeklyDisabledList(weeklyDisabledList);
        lifeDiscountCouponVo.setHolidayDisabledList(holidayDisabledList);
        lifeDiscountCouponVo.setClaimRule(claimRule);

        // 查询时间段规则信息
        List<LifeDiscountCouponQuantumRules> lifeDiscountCouponQuantumRulesList =
                lifeDiscountCouponQuantumRulesMapper.listByDiscountCouponIdIncludeDeleted(couponIdInt);
        List<LifeDiscountCouponQuantumRules> availableTimeQuantumList = new ArrayList<>();
        List<LifeDiscountCouponQuantumRules> customizeUnavailableTimeQuantumList = new ArrayList<>();
        for (LifeDiscountCouponQuantumRules lifeDiscountCouponQuantumRules : lifeDiscountCouponQuantumRulesList) {
            if (lifeDiscountCouponQuantumRules.getTimeQuantumType().equals(DiscountCouponEnum.AVAILABLE_TIME_QUANTUM.getValue())) {
                availableTimeQuantumList.add(lifeDiscountCouponQuantumRules);
            }
            if (lifeDiscountCouponQuantumRules.getTimeQuantumType().equals(DiscountCouponEnum.UNAVAILABLE_TIME_QUANTUM.getValue())) {
                customizeUnavailableTimeQuantumList.add(lifeDiscountCouponQuantumRules);
            }
        }
        lifeDiscountCouponVo.setAvailableTimeQuantum(availableTimeQuantumList);
        lifeDiscountCouponVo.setCustomizeUnavailableTimeQuantum(customizeUnavailableTimeQuantumList);
        
        // 查询店铺名称
        if (lifeDiscountCoupon != null && !StringUtils.isEmpty(lifeDiscountCoupon.getStoreId())) {
            try {
                Integer storeId = Integer.parseInt(lifeDiscountCoupon.getStoreId());
                StoreInfo storeInfo = storeInfoMapper.selectById(storeId);
                if (storeInfo != null && !StringUtils.isEmpty(storeInfo.getStoreName())) {
                    lifeDiscountCouponVo.setStoreName(storeInfo.getStoreName());
                }
            } catch (Exception e) {
                // 查询店铺信息失败，不影响主流程，静默处理
            }
        }
        
        return lifeDiscountCouponVo;
    }

    @Override
    public LifeDiscountCouponVo getCouponDetailWithFriendOwnedQty(String couponId, String storeId) {
        if (StringUtils.isEmpty(couponId) || StringUtils.isEmpty(storeId)) {
            return null;
        }
        int couponIdInt;
        int storeIdInt;
        try {
            couponIdInt = Integer.parseInt(couponId.trim());
            storeIdInt = Integer.parseInt(storeId.trim());
        } catch (NumberFormatException e) {
            return null;
        }
        if (lifeDiscountCouponMapper.selectByIdIncludeDeleted(couponIdInt) == null) {
            return null;
        }

        LifeDiscountCouponVo vo = getCounponDetailById(String.valueOf(couponIdInt), null);

        // ownedQuantity：本店（storeId=store_info.id）下任一商户账号作为赠送方已向好友送出的合计张数（优先 sender_user_id，旧数据兼容 friend_store_user_id）。
        // 接收方店铺：receiver_store_id / store_user_id（store_info.id）。
        int owned = 0;
        List<StoreUser> storeUsers = storeUserMapper.selectList(new LambdaQueryWrapper<StoreUser>()
                .eq(StoreUser::getStoreId, storeIdInt)
                .eq(StoreUser::getDeleteFlag, 0));
        if (CollectionUtils.isNotEmpty(storeUsers)) {
            List<Integer> senderStoreUserIds = storeUsers.stream()
                    .map(StoreUser::getId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(senderStoreUserIds)) {
                List<LifeDiscountCouponStoreFriend> rows = lifeDiscountCouponStoreFriendMapper.selectList(
                        new LambdaQueryWrapper<LifeDiscountCouponStoreFriend>()
                                .eq(LifeDiscountCouponStoreFriend::getCouponId, couponIdInt)
                                .and(w -> w.in(LifeDiscountCouponStoreFriend::getSenderUserId, senderStoreUserIds)
                                        .or(sub -> sub.isNull(LifeDiscountCouponStoreFriend::getSenderUserId)
                                                .in(LifeDiscountCouponStoreFriend::getFriendStoreUserId, senderStoreUserIds)))
                                .eq(LifeDiscountCouponStoreFriend::getReleaseType, 1));
                for (LifeDiscountCouponStoreFriend row : rows) {
                    if (row.getSingleQty() != null) {
                        owned += row.getSingleQty();
                    }
                }
            }
        }

        vo.setOwnedQuantity(owned);
        return vo;
    }

    public static Date addDaysToDateJava8(Date date, int days) {
        // 将Date转换为Instant
        Instant instant = date.toInstant();

        // 转换为LocalDate并加天数
        LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate newLocalDate = localDate.plusDays(days);

        // 转换回Date
        return Date.from(newLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    @Override
    public List<LifeDiscountCouponVo> getStoreUserCouponList(String storeId, UserLoginInfo userLoginInfo, Integer couponType) {
        List<LifeDiscountCouponVo> lifeDiscountCouponVos = new ArrayList<>();
        try {
            LocalDateTime now = LocalDateTime.now();
            LocalDate today = LocalDate.now();
            //根据店铺id查询该店铺的优惠券,状态是开启领取的券（领取起止日为空的模板也查出）
            LambdaQueryWrapper<LifeDiscountCoupon> queryWrapper = new LambdaQueryWrapper<LifeDiscountCoupon>()
                    .eq(LifeDiscountCoupon::getStoreId, storeId).eq(LifeDiscountCoupon::getGetStatus, 1)
                    .and(w -> w.isNull(LifeDiscountCoupon::getBeginGetDate).or().le(LifeDiscountCoupon::getBeginGetDate, today))
                    .and(w -> w.isNull(LifeDiscountCoupon::getEndGetDate).or().ge(LifeDiscountCoupon::getEndGetDate, today))
                    .orderByDesc(LifeDiscountCoupon::getAttentionCanReceived);
            //如果指定了优惠券类型（满减券或折扣券），添加筛选条件
            if (couponType != null) {
                queryWrapper.eq(LifeDiscountCoupon::getCouponType, couponType);
            }
            List<LifeDiscountCoupon> lifeDiscountCoupons = lifeDiscountCouponMapper.selectList(queryWrapper);
            //根据优惠券列表查询该优惠券是否领取过
            for (LifeDiscountCoupon lifeDiscountCoupon : lifeDiscountCoupons) {
                LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
                lifeDiscountCouponVo.setCouponId(lifeDiscountCoupon.getId());
                BeanUtils.copyProperties(lifeDiscountCoupon, lifeDiscountCouponVo);
                //查询该人员该卡券是否达到限领数量
                LambdaQueryWrapper<LifeDiscountCouponUser> userQueryWrapper = new LambdaQueryWrapper<>();
                userQueryWrapper.eq(LifeDiscountCouponUser::getCouponId, lifeDiscountCoupon.getId());
                userQueryWrapper.eq(LifeDiscountCouponUser::getUserId, userLoginInfo.getUserId());
                userQueryWrapper.orderByDesc(LifeDiscountCouponUser::getReceiveTime);
                List<LifeDiscountCouponUser> lifeDiscountCouponUsers = lifeDiscountCouponUserMapper.selectList(userQueryWrapper);
                String specifiedDay = lifeDiscountCoupon.getSpecifiedDay();
                Date receiveDay = null;

                //判断是否已经全部领取
                if (lifeDiscountCoupon.getRestrictedQuantity() != 0 && lifeDiscountCouponUsers.size() >= lifeDiscountCoupon.getRestrictedQuantity()) {
                    receiveDay = lifeDiscountCouponUsers.get(0).getReceiveTime();
                    lifeDiscountCouponVo.setExpirationTime(lifeDiscountCouponUsers.get(0).getExpirationTime());
                    lifeDiscountCouponVo.setCanReceived(false);
                } else {
                    //判断一下领取规则
                    LambdaQueryWrapper<LifeDiscountCouponUnavailableRules> rulesLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    rulesLambdaQueryWrapper.eq(LifeDiscountCouponUnavailableRules::getDiscountCouponId, lifeDiscountCoupon.getId());
                    rulesLambdaQueryWrapper.eq(LifeDiscountCouponUnavailableRules::getUnavailableRuleType, DiscountCouponEnum.CLAIM_RULE.getValue());
                    LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRules = lifeDiscountCouponUnavailableRulesMapper.selectOne(rulesLambdaQueryWrapper);
                    //获取一下当前人员领取的最近一次领取
                    if (lifeDiscountCouponUsers.size() == 0) {
                        lifeDiscountCouponVo.setCanReceived(true);
                    } else {
                        LifeDiscountCouponUser lifeDiscountCouponUser = lifeDiscountCouponUsers.get(0);
                        Date receiveTime = lifeDiscountCouponUser.getReceiveTime();
                        receiveDay = lifeDiscountCouponUser.getReceiveTime();

                        // 将 Date 转换为 Instant
                        Instant instant = receiveTime.toInstant();
                        // 获取系统默认时区
                        ZoneId zoneId = ZoneId.systemDefault();
                        // 将 Instant 转换为 LocalDateTime
                        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
                        if (lifeDiscountCouponUnavailableRules != null) {
                            String unavailableRuleValue = lifeDiscountCouponUnavailableRules.getUnavailableRuleValue();
                            long confineTo = 0L;
                            if (DiscountCouponEnum.DAY.getValue().equals(unavailableRuleValue)) {//如果规则限制一天一张
                                confineTo = ChronoUnit.DAYS.between(localDateTime, now);
                            } else if (DiscountCouponEnum.WEEK.getValue().equals(unavailableRuleValue)) {//如果规则限制一周一张
                                confineTo = ChronoUnit.WEEKS.between(localDateTime, now);
                            } else if (DiscountCouponEnum.MONTH.getValue().equals(unavailableRuleValue)) {//如果规则限制一月一张
                                confineTo = ChronoUnit.MONTHS.between(localDateTime, now);
                            } else if (DiscountCouponEnum.YEAR.getValue().equals(unavailableRuleValue)) {//如果规则限制一年一张
                                confineTo = ChronoUnit.YEARS.between(localDateTime, now);
                            }
                            //如果在规则范围内，则不允许领取,范围外，则可以领取
                            lifeDiscountCouponVo.setCanReceived(confineTo >= 1);
                        } else {
                            lifeDiscountCouponVo.setCanReceived(true);
                        }
                        lifeDiscountCouponVo.setExpirationTime(lifeDiscountCouponUser.getExpirationTime());
                    }
                }
                if (!StringUtils.isEmpty(specifiedDay)) {
                    int sDay = Integer.parseInt(specifiedDay);
                    if (sDay > 0 && receiveDay != null) {
                        Date validDate = addDaysToDateJava8(receiveDay, sDay);
                        LocalDate validDateLocalDate = validDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                        lifeDiscountCouponVo.setValidDate(validDateLocalDate);
                    } else {
                        lifeDiscountCouponVo.setValidDate(null);
                    }
                }
                lifeDiscountCouponVo.setQuantityClaimed(lifeDiscountCouponUsers.size());
                lifeDiscountCouponVos.add(lifeDiscountCouponVo);
            }
        } catch (Exception e) {
            log.error("LifeDiscountCouponServiceImpl.getStoreUserUsableCouponList ERROR Msg={}", e);
        }
        return lifeDiscountCouponVos;
    }

    @Override
    public Map getStoreUserUsableCouponList(String storeId, UserLoginInfo userLoginInfo, BigDecimal amount, Integer couponType) {
        HashMap<String, List> result = new HashMap<>();
        List<LifeDiscountCouponVo> canUseLifeDiscountCouponVos = new ArrayList<>();
        List<LifeDiscountCouponVo> forbidUseLifeDiscountCouponVos = new ArrayList<>();
        LambdaQueryWrapper<LifeDiscountCouponUser> queryWrapper = new LambdaQueryWrapper<>();

        // 获取 Calendar 实例，默认表示当前日期和时间
        Calendar calendar = Calendar.getInstance();
        // 将小时设置为 0
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        // 将分钟设置为 0
        calendar.set(Calendar.MINUTE, 0);
        // 将秒设置为 0
        calendar.set(Calendar.SECOND, 0);
        // 将毫秒设置为 0
        calendar.set(Calendar.MILLISECOND, 0);
        // 获取设置后的 Date 对象
        Date midnight = calendar.getTime();

        //storeId（前台传进来的是团购id）
        //根据团购id获取门店id
//        LifeCoupon lifeCoupon = lifeCouponMapper.selectById(storeId);
//        String makeSureStoreId = lifeCoupon.getStoreId();

        //查询可用的优惠券 1、当前优惠券没过使用期，2、当前优惠券为待使用，3、是该门店的券
        queryWrapper.eq(LifeDiscountCouponUser::getUserId, userLoginInfo.getUserId());
        queryWrapper.eq(LifeDiscountCouponUser::getStatus, DiscountCouponEnum.WAITING_USED.getValue());
        queryWrapper.ge(LifeDiscountCouponUser::getExpirationTime, midnight);
        List<LifeDiscountCouponUser> lifeDiscountCouponUserList = lifeDiscountCouponUserMapper.selectList(queryWrapper);

        List<LifeDiscountCouponUser> lifeDiscountCouponUsers = new ArrayList<>();
        for (LifeDiscountCouponUser lifeDiscountCouponUser : lifeDiscountCouponUserList) {
            //查询该优惠券属于哪个店铺
            LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(lifeDiscountCouponUser.getCouponId());
            if (lifeDiscountCoupon == null) {
                continue;
            }
            //如果指定了优惠券类型，进行筛选
            if (couponType != null && !couponType.equals(lifeDiscountCoupon.getCouponType())) {
                continue;
            }
            String couponStoreId = lifeDiscountCoupon.getStoreId();
            if (null != couponStoreId && couponStoreId.equals(storeId)) {
                lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
            }
            //平台优惠券
            if (3 == lifeDiscountCoupon.getType()) {
                lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
            }
        }

        //判断今日是否为节该券禁用节假日
        //判断当日是否为节假日
        // 获取当前日期
        Date currentDate = new Date();
        // 创建 SimpleDateFormat 对象，指定日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 格式化日期
        String formattedDate = dateFormat.format(currentDate);
        //获取当前年份
        // 获取 Calendar 实例
        // 获取当前年份
        int year = calendar.get(Calendar.YEAR);
        //获取该年份基础节假日数据
        LambdaQueryWrapper<EssentialHolidayComparison> essentialHolidayComparisonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        essentialHolidayComparisonLambdaQueryWrapper.eq(EssentialHolidayComparison::getParticularYear, year);
        List<EssentialHolidayComparison> essentialHolidayComparisons = essentialHolidayComparisonMapper.selectList(essentialHolidayComparisonLambdaQueryWrapper);
        String festivalName = "";
        for (EssentialHolidayComparison essentialHolidayComparison : essentialHolidayComparisons) {
            if (essentialHolidayComparison.getFestivalDate().equals(formattedDate)) {
                festivalName = essentialHolidayComparison.getFestivalName();
            }
        }
        //获取今日周几
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String dayName = "";
        switch (dayOfWeek) {
            case Calendar.SUNDAY:
                dayName = "日";
                break;
            case Calendar.MONDAY:
                dayName = "一";
                break;
            case Calendar.TUESDAY:
                dayName = "二";
                break;
            case Calendar.WEDNESDAY:
                dayName = "三";
                break;
            case Calendar.THURSDAY:
                dayName = "四";
                break;
            case Calendar.FRIDAY:
                dayName = "五";
                break;
            case Calendar.SATURDAY:
                dayName = "六";
                break;
        }

        //去重优惠券id
        for (LifeDiscountCouponUser lifeDiscountCouponUser : lifeDiscountCouponUsers) {
            LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(lifeDiscountCouponUser.getCouponId());
            LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
            lifeDiscountCouponVo.setCouponId(lifeDiscountCoupon.getId());
            lifeDiscountCouponVo.setUserCouponId(lifeDiscountCouponUser.getId());
            BeanUtils.copyProperties(lifeDiscountCoupon, lifeDiscountCouponVo);
            lifeDiscountCouponVo.setQuantityClaimed(lifeDiscountCouponUsers.size());
            //默认该券可用
            lifeDiscountCouponVo.setDisabledStatus(true);
            List<LifeDiscountCouponUnavailableRules> allTemplateRules =
                    lifeDiscountCouponUnavailableRulesMapper.listByDiscountCouponIdIncludeDeleted(lifeDiscountCoupon.getId());
            List<LifeDiscountCouponUnavailableRules> lifeDiscountCouponUnavailableRules = allTemplateRules.stream()
                    .filter(r -> DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue().equals(r.getUnavailableRuleType()))
                    .collect(Collectors.toList());
            String forbiddenRule = "";
            if (lifeDiscountCouponUnavailableRules.size() > 0) {
                forbiddenRule += HOLIDAY_RULE_TITLE;
            }
            List<String> holidCoupnDis = lifeDiscountCouponUnavailableRules.stream().map(rule -> rule.getUnavailableRuleValue()).collect(Collectors.toList());
            forbiddenRule += String.join(", ", holidCoupnDis);
            for (LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRule : lifeDiscountCouponUnavailableRules) {
                //如果当日为节假日，并且该券该节假日也禁用，则该券禁用
                if (StringUtils.isEmpty(festivalName) && festivalName.equals(lifeDiscountCouponUnavailableRule.getUnavailableRuleValue())) {
                    lifeDiscountCouponVo.setDisabledStatus(false);
                }
            }
            if (lifeDiscountCouponUnavailableRules.size() > 0) {
                forbiddenRule += NOT_USE;
            }
            //该券的周中禁用规则
            List<LifeDiscountCouponUnavailableRules> weekLifeDiscountCouponUnavailableRules = allTemplateRules.stream()
                    .filter(r -> DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue().equals(r.getUnavailableRuleType()))
                    .collect(Collectors.toList());
            if (weekLifeDiscountCouponUnavailableRules.size() > 0) {
                forbiddenRule += WEEK_RULE_TITLE;
            }
            List<String> weekCoupnDis = weekLifeDiscountCouponUnavailableRules.stream().map(rule -> rule.getUnavailableRuleValue()).collect(Collectors.toList());
            forbiddenRule += String.join(", ", weekCoupnDis);
            for (LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRule : weekLifeDiscountCouponUnavailableRules) {
                //该券该周中日也禁用，则该券禁用
                if (dayName.equals(lifeDiscountCouponUnavailableRule.getUnavailableRuleValue())) {
                    lifeDiscountCouponVo.setDisabledStatus(false);
                }
            }
            if (weekLifeDiscountCouponUnavailableRules.size() > 0) {
                forbiddenRule += NOT_USE;
            }
            //添加限制金额规则
            BigDecimal minimumSpending = lifeDiscountCoupon.getMinimumSpendingAmount();
            if (minimumSpending != null && amount.compareTo(minimumSpending) < 0) {
                lifeDiscountCouponVo.setDisabledStatus(false);
            }
            // 如果最低消费为0或null，显示"无门槛"
            if (minimumSpending == null || minimumSpending.compareTo(BigDecimal.ZERO) == 0) {
                forbiddenRule += MINIMUM_SPENDING_AMOUNT + "无门槛";
            } else {
                forbiddenRule += MINIMUM_SPENDING_AMOUNT + minimumSpending;
            }
            lifeDiscountCouponVo.setForbiddenRule(forbiddenRule);
            if (lifeDiscountCouponVo.isDisabledStatus()) {
                canUseLifeDiscountCouponVos.add(lifeDiscountCouponVo);
            } else {
                forbidUseLifeDiscountCouponVos.add(lifeDiscountCouponVo);
            }
        }
        result.put("canUseLifeDiscountCouponVos", canUseLifeDiscountCouponVos);
        result.put("forbidUseLifeDiscountCouponVos", forbidUseLifeDiscountCouponVos);
        return result;
    }

    /**
     * 获取用户优惠券列表
     * 
     * @param userLoginInfo 用户登录信息
     * @param page 页码
     * @param size 每页数量
     * @param tabType 分页类型：0-全部（未使用），1-即将过期，2-已使用，3-已过期
     * @param type 券类型：保留兼容，仅 null 或 1（仅用户优惠券）；4 已废弃
     * @param couponType 优惠券类型：1-满减券，2-折扣券，null-全部
     * @param storeId 商铺ID，可为空，传则仅返回该商铺的优惠券
     * @param storeKeyword 店铺名称关键字，非空时仅门店名称匹配的券参与分页（与筛选后再分页一致）
     * @return 优惠券列表
     */
    @Override
    public List<LifeDiscountCouponVo> getUserCouponList(UserLoginInfo userLoginInfo, int page, int size, String tabType, Integer type, Integer couponType, String storeId, String storeKeyword) {
        validateGetUserCouponListParams(userLoginInfo, tabType, type);

        ZoneId zone = ZoneId.systemDefault();
        LocalDate today = LocalDate.now(zone);

        String filterStoreId = null;
        if (storeId != null) {
            String trimmed = storeId.trim();
            if (!trimmed.isEmpty()) {
                filterStoreId = trimmed;
            }
        }
        String keyword = null;
        if (storeKeyword != null) {
            String t = storeKeyword.trim();
            if (!t.isEmpty()) {
                keyword = t;
            }
        }

        // 联表先按模板 + tab + couponType + storeId + 店铺名称关键字筛选再分页（含商家逻辑删除的模板）
        IPage<LifeDiscountCouponUser> pageResult = lifeDiscountCouponUserMapper.selectPageAfterTemplateFilter(
                new Page<>(page, size),
                userLoginInfo.getUserId(),
                tabType,
                today,
                today.plusDays(7),
                today.minusDays(7),
                couponType,
                filterStoreId,
                keyword);

        List<LifeDiscountCouponUser> userRows = pageResult.getRecords();
        if (userRows.isEmpty()) {
            return new ArrayList<>();
        }

        List<LifeDiscountCoupon> templates = loadCouponTemplatesIncludeDeleted(userRows);
        Map<Integer, LifeDiscountCoupon> templateById = templates.stream()
                .collect(Collectors.toMap(LifeDiscountCoupon::getId, c -> c, (a, b) -> a));
        Map<String, StoreInfo> storeByIdStr = storeInfoMapForCouponTemplates(templates);

        List<LifeDiscountCouponVo> result = new ArrayList<>();
        for (LifeDiscountCouponUser row : userRows) {
            LifeDiscountCoupon template = row.getCouponId() == null ? null : templateById.get(row.getCouponId());
            if (template == null) {
                continue;
            }
            result.add(buildCouponVo(template, row, zone, today, storeByIdStr));
        }
        return result;
    }

    private void validateGetUserCouponListParams(UserLoginInfo userLoginInfo, String tabType, Integer legacyTypeParam) {
        if (userLoginInfo == null || StringUtils.isEmpty(userLoginInfo.getUserId())) {
            throw new IllegalArgumentException("用户信息不能为空");
        }
        if (StringUtils.isEmpty(tabType)) {
            throw new IllegalArgumentException("分页类型不能为空");
        }
        if (!DiscountCouponEnum.ALL.getValue().equals(tabType)
                && !DiscountCouponEnum.BE_ABOUT_TO_EXPORE.getValue().equals(tabType)
                && !DiscountCouponEnum.HAVE_ALREADY_APPLIED.getValue().equals(tabType)
                && !DiscountCouponEnum.HAVE_EXPIRED.getValue().equals(tabType)) {
            throw new IllegalArgumentException("分页类型参数错误，必须为0（未使用）、1（即将过期）、2（已使用）、3（已过期/已失效）");
        }
        if (legacyTypeParam != null && legacyTypeParam == 4) {
            throw new IllegalArgumentException("不再支持代金券（type=4）");
        }
    }

    private List<LifeDiscountCoupon> loadCouponTemplatesIncludeDeleted(List<LifeDiscountCouponUser> userRows) {
        List<Integer> couponIds = userRows.stream()
                .map(LifeDiscountCouponUser::getCouponId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (couponIds.isEmpty()) {
            return Collections.emptyList();
        }
        return lifeDiscountCouponMapper.selectByIdsIncludeDeleted(couponIds);
    }

    private Map<String, StoreInfo> storeInfoMapForCouponTemplates(List<LifeDiscountCoupon> templates) {
        List<String> rawStoreIds = templates.stream()
                .map(LifeDiscountCoupon::getStoreId)
                .filter(s -> !StringUtils.isEmpty(s))
                .distinct()
                .collect(Collectors.toList());
        if (rawStoreIds.isEmpty()) {
            return Collections.emptyMap();
        }
        List<StoreInfo> infos = storeInfoMapper.getList(new LambdaQueryWrapper<StoreInfo>().in(StoreInfo::getId, rawStoreIds));
        return infos.stream().collect(Collectors.toMap(s -> s.getId().toString(), s -> s, (a, b) -> a));
    }

    /**
     * 构建优惠券VO
     */
    private LifeDiscountCouponVo buildCouponVo(LifeDiscountCoupon coupon, LifeDiscountCouponUser userCoupon,
                                               ZoneId zoneId, LocalDate localNow, Map<String, StoreInfo> storeInfoMap) {
        LifeDiscountCouponVo vo = new LifeDiscountCouponVo();
        vo.setCouponId(coupon.getId());
        vo.setVoucherId(userCoupon.getVoucherId());
        vo.setUserCouponId(userCoupon.getId());
        vo.setStatus(userCoupon.getStatus());
        BeanUtils.copyProperties(coupon, vo);
        
        // quantityClaimed表示该券的总领取数量，在用户券列表中不设置或设置为0
        vo.setQuantityClaimed(null);
        LocalDate exp = userCoupon.getExpirationTime();
        if (exp == null) {
            exp = DiscountCouponExpirationUtil.resolveLifeDiscountCouponExpiration(
                    userCoupon.getReceiveTime(),
                    coupon.getLongTermValid(),
                    coupon.getSpecifiedDay(),
                    coupon.getExpirationDate(),
                    coupon.getValidDate(),
                    coupon.getEndDate(),
                    zoneId);
        }
        vo.setExpirationTime(exp);
        vo.setValidDate(exp);

        // 判断是否到了优惠券的开始时间
        vo.setReachUseTimeFlag(1);
        if (coupon.getBeginGetDate() != null && localNow.isBefore(coupon.getBeginGetDate())) {
            vo.setReachUseTimeFlag(0);
        }
        
        // 设置店铺信息
        if (!StringUtils.isEmpty(coupon.getStoreId())) {
            StoreInfo storeInfo = storeInfoMap.get(coupon.getStoreId());
            if (storeInfo != null) {
                vo.setStoreName(storeInfo.getStoreName());
                vo.setBusinessSection(storeInfo.getBusinessSection());
                vo.setBusinessSectionName(storeInfo.getBusinessSectionName());
            }
        }
        
        return vo;
    }
    
    /**
     * 在指定日期基础上增加天数
     */
    private Date addDaysToDate(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, days);
        return calendar.getTime();
    }

    //获取纯日期
    public static Date getPureDate(Date date) {
        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDateTime localDateTime = localDate.atStartOfDay(); // 时间为 00:00
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /** 模板不再写入用券绝对日期；用户侧起止以领券时间 + 模板天数在 {@link DiscountCouponExpirationUtil} 中计算 */
    private static void clearTemplateObsoleteAbsoluteUsePeriod(LifeDiscountCoupon c) {
        c.setStartDate(null);
        c.setEndDate(null);
        c.setValidDate(null);
    }

    /** 未配置领取起止日时，列表仍按草稿/库存/领取开关推断展示状态，避免整条记录被丢弃 */
    private Integer resolveListStatusWhenGetWindowMissing(Integer couponStatus, Integer getStatus,
                                                          Integer unlimitedQty, Integer singleQty) {
        if (couponStatus != null && couponStatus == LifeDiscountCoupon.COUPON_STATUS_INVALID) {
            return Integer.parseInt(DiscountCouponEnum.INVALID.getValue());
        }
        if (couponStatus != null && couponStatus == 0) {
            return Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue());
        }
        if (!LifeDiscountCouponStock.hasTemplateStockRemaining(unlimitedQty, singleQty)) {
            return Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue());
        }
        if (getStatus == null || getStatus.toString().equals(DiscountCouponEnum.NO_GET.getValue())) {
            return Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue());
        }
        return Integer.parseInt(DiscountCouponEnum.UNDER_WAY.getValue());
    }

    private Integer resolveInvalidStatusIfNeeded(Integer couponStatus) {
        if (couponStatus != null && couponStatus == LifeDiscountCoupon.COUPON_STATUS_INVALID) {
            return Integer.parseInt(DiscountCouponEnum.INVALID.getValue());
        }
        return null;
    }

    /**
     * 获取店铺所有优惠券列表（分页）
     * 支持查询我的优惠券和好友优惠券
     * 
     * @param storeId 店铺ID
     * @param userLoginInfo 用户登录信息
     * @param page 页码
     * @param size 每页数量
     * @param couponName 优惠券名称（模糊查询）
     * @param tab 分页类型：0-全部，1-进行中，2-已结束
     * @param couponsFromType 查询类型：1-我的优惠券，2-好友的优惠券
     * @param couponStatus 优惠券状态：0-草稿，1-正式
     * @param couponType 优惠券类型：1-满减券，2-折扣券，null-全部
     * @return 分页优惠券列表
     */
    @Override
    public IPage<LifeDiscountCouponVo> getStoreAllCouponList(String storeId, UserLoginInfo userLoginInfo, int page, int size, String couponName, String tab, int couponsFromType, int couponStatus, Integer couponType) {
        // 参数校验
        if (StringUtils.isEmpty(storeId)) {
            throw new IllegalArgumentException("店铺ID不能为空");
        }
        if (StringUtils.isEmpty(tab)) {
            throw new IllegalArgumentException("分页类型不能为空");
        }
        
        if (couponsFromType == 1) {
            IPage<LifeDiscountCoupon> iPage = new Page<>(page, size);
            List<LifeDiscountCouponVo> lifeDiscountCouponVos = new ArrayList<>();
            LambdaQueryWrapper<LifeDiscountCoupon> lifeDiscountCouponLambdaQueryWrapper = new LambdaQueryWrapper<LifeDiscountCoupon>();
            
            // 如果tab=3（草稿），强制设置couponStatus=0；否则使用传入的couponStatus参数
            if ("3".equals(tab)) {
                // 草稿：强制设置为couponStatus = 0
                lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getCouponStatus, 0);
            } else {
                // 非草稿状态：使用传入的couponStatus参数
                lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getCouponStatus, couponStatus);
            }
            
            //如果couponName不为空，则模糊查询
            if (!StringUtils.isEmpty(couponName)) {
                lifeDiscountCouponLambdaQueryWrapper.like(LifeDiscountCoupon::getName, couponName);
            }
            //如果指定了优惠券类型（满减券或折扣券），添加筛选条件
            if (couponType != null) {
                lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getCouponType, couponType);
            }
            //获取当日日期
            Date now = new Date();
            // 根据tab类型添加查询条件
            Date pureDate = getPureDate(now);
            LocalDate pureLocalDate = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            if ("1".equals(tab)) {
                // 进行中：有库存 且 开启领取；领取起止日未配置时在 SQL 中也视为满足时间条件，由内存内状态再筛
                lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getGetStatus, 1)
                        .and(w -> w.eq(LifeDiscountCoupon::getUnlimitedQty, 1)
                                .or()
                                .gt(LifeDiscountCoupon::getSingleQty, 0))
                        .and(w -> w.and(w2 -> w2.isNull(LifeDiscountCoupon::getBeginGetDate)
                                        .or()
                                        .le(LifeDiscountCoupon::getBeginGetDate, pureLocalDate))
                                .and(w2 -> w2.isNull(LifeDiscountCoupon::getEndGetDate)
                                        .or()
                                        .ge(LifeDiscountCoupon::getEndGetDate, pureLocalDate)));
            } else if ("2".equals(tab)) {
                // 已结束：结束时间 < 当前时间 且 开启领取
                lifeDiscountCouponLambdaQueryWrapper.lt(LifeDiscountCoupon::getEndGetDate, pureDate)
                        .eq(LifeDiscountCoupon::getGetStatus, 1);
            } else if ("4".equals(tab)) {
                // 未开始：开始时间 > 当前时间
                lifeDiscountCouponLambdaQueryWrapper.gt(LifeDiscountCoupon::getBeginGetDate, pureDate);
            } else if ("5".equals(tab)) {
                // 已下架：getStatus = 0（暂停领取）
                lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getGetStatus, 0);
            } else if ("6".equals(tab)) {
                // 已清库：发行量有限且库存为0
                lifeDiscountCouponLambdaQueryWrapper.and(w -> w.isNull(LifeDiscountCoupon::getUnlimitedQty).or().eq(LifeDiscountCoupon::getUnlimitedQty, 0))
                        .eq(LifeDiscountCoupon::getSingleQty, 0);
            }
            // tab=0或其他值：查询全部，不添加额外条件
            // tab=3（草稿）已在上面处理，这里不再重复设置
            lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getStoreId, storeId);
            lifeDiscountCouponLambdaQueryWrapper.orderByDesc(LifeDiscountCoupon::getCreatedTime);
            //根据店铺id查询该店铺的优惠券,状态是开启领取的券
            IPage<LifeDiscountCoupon> lifeDiscountCouponIPage = lifeDiscountCouponMapper.selectPage(iPage, lifeDiscountCouponLambdaQueryWrapper);
            for (LifeDiscountCoupon lifeDiscountCoupon : lifeDiscountCouponIPage.getRecords()) {
                LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
                lifeDiscountCouponVo.setCouponId(lifeDiscountCoupon.getId());
                //处理一下该优惠券的状态 状态(0:进行中，1:已结束，2:未开始，3:已暂停)
                // 将 Date 转换为 LocalDate
                Instant instant = now.toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                LocalDate localNow = instant.atZone(zoneId).toLocalDate();
                
                // 计算优惠券状态
                Integer calculatedStatus = resolveInvalidStatusIfNeeded(lifeDiscountCoupon.getCouponStatus());
                if (calculatedStatus == null && !StringUtils.isEmpty(lifeDiscountCoupon.getBeginGetDate()) && !StringUtils.isEmpty(lifeDiscountCoupon.getEndGetDate())) {
                    int startResult = localNow.compareTo(lifeDiscountCoupon.getBeginGetDate());
                    int endResult = localNow.compareTo(lifeDiscountCoupon.getEndGetDate());
                    //如果当前时间小于开始时间
                    if (!LifeDiscountCouponStock.hasTemplateStockRemaining(
                            lifeDiscountCoupon.getUnlimitedQty(), lifeDiscountCoupon.getSingleQty())) {//无库存则已售罄
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue());
                    } else if (startResult < 0) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue());
                    } else if (lifeDiscountCoupon.getGetStatus() == null || lifeDiscountCoupon.getGetStatus().toString().equals(DiscountCouponEnum.NO_GET.getValue())) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue());
                    } else if (endResult > 0) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.FINISHED.getValue());
                    } else if (startResult >= 0 && endResult <= 0) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.UNDER_WAY.getValue());
                    }
                } else {
                    calculatedStatus = resolveListStatusWhenGetWindowMissing(
                            lifeDiscountCoupon.getCouponStatus(),
                            lifeDiscountCoupon.getGetStatus(),
                            lifeDiscountCoupon.getUnlimitedQty(),
                            lifeDiscountCoupon.getSingleQty());
                }
                
                // 如果状态计算失败，跳过该记录
                if (calculatedStatus == null) {
                    continue;
                }
                
                // 根据tab类型过滤状态
                if (!"0".equals(tab)) {
                    if ("3".equals(tab) && lifeDiscountCoupon.getCouponStatus() != 0) {
                        // 草稿：必须是couponStatus=0
                        continue;
                    } else if ("4".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue()))) {
                        // 未开始：必须是未开始状态
                        continue;
                    } else if ("5".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue()))) {
                        // 已下架：必须是暂停领取状态
                        continue;
                    } else if ("6".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue()))) {
                        // 已清库：必须是已售罄状态
                        continue;
                    } else if ("1".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.UNDER_WAY.getValue()))) {
                        // 进行中：必须是进行中状态
                        continue;
                    } else if ("2".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.FINISHED.getValue()))) {
                        // 已结束：必须是已结束状态
                        continue;
                    }
                }
                
                lifeDiscountCouponVo.setStatus(calculatedStatus);
                // 查询优惠券不可用规则（工作日、节假日、领取规则）
                List<LifeDiscountCouponUnavailableRules> unavailableRules = lifeDiscountCouponUnavailableRulesMapper.selectList(
                        new LambdaQueryWrapper<LifeDiscountCouponUnavailableRules>()
                                .eq(LifeDiscountCouponUnavailableRules::getDiscountCouponId, lifeDiscountCoupon.getId()));
                
                // 按规则类型分组
                Map<String, List<LifeDiscountCouponUnavailableRules>> rulesMap = unavailableRules.stream()
                        .collect(Collectors.groupingBy(LifeDiscountCouponUnavailableRules::getUnavailableRuleType));
                
                // 设置工作日不可用列表
                String weekdayKey = DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue();
                if (rulesMap.containsKey(weekdayKey)) {
                    lifeDiscountCouponVo.setWeeklyDisabledList(rulesMap.get(weekdayKey).stream()
                            .map(LifeDiscountCouponUnavailableRules::getUnavailableRuleValue)
                            .collect(Collectors.toList()));
                }
                
                // 设置节假日不可用列表
                String holidayKey = DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue();
                if (rulesMap.containsKey(holidayKey)) {
                    lifeDiscountCouponVo.setHolidayDisabledList(rulesMap.get(holidayKey).stream()
                            .map(LifeDiscountCouponUnavailableRules::getUnavailableRuleValue)
                            .collect(Collectors.toList()));
                }
                
                // 设置领取规则
                String claimRuleKey = DiscountCouponEnum.CLAIM_RULE.getValue();
                if (rulesMap.containsKey(claimRuleKey) && !rulesMap.get(claimRuleKey).isEmpty()) {
                    lifeDiscountCouponVo.setClaimRule(rulesMap.get(claimRuleKey).get(0).getUnavailableRuleValue());
                }
                BeanUtils.copyProperties(lifeDiscountCoupon, lifeDiscountCouponVo);
                lifeDiscountCouponVos.add(lifeDiscountCouponVo);
            }
            IPage<LifeDiscountCouponVo> lifeDiscountCouponVoIPage = new Page<>();
            BeanUtils.copyProperties(lifeDiscountCouponIPage, lifeDiscountCouponVoIPage);
            lifeDiscountCouponVoIPage.setRecords(lifeDiscountCouponVos);
            return lifeDiscountCouponVoIPage;
        } else {
            // 查询好友优惠券
            IPage<LifeDiscountCouponStoreFriendVo> iPage = new Page<>(page, size);
            List<LifeDiscountCouponVo> friendLifeDiscountCouponVos = new ArrayList<>();
            QueryWrapper<LifeDiscountCouponStoreFriendVo> friendLifeDiscountCouponQueryWrapper = new QueryWrapper<>();
            
            // 如果tab=3（草稿），强制设置couponStatus=0；否则使用传入的couponStatus参数
            if ("3".equals(tab)) {
                // 草稿：强制设置为couponStatus = 0
                friendLifeDiscountCouponQueryWrapper.eq("ldc.coupon_status", 0);
            } else {
                // 非草稿状态：使用传入的couponStatus参数（好友优惠券也需要根据couponStatus过滤）
                friendLifeDiscountCouponQueryWrapper.eq("ldc.coupon_status", couponStatus);
            }
            
            //如果couponName不为空，则模糊查询
            if (!StringUtils.isEmpty(couponName)) {
                friendLifeDiscountCouponQueryWrapper.like("ldc.name", couponName);
            }
            //如果指定了优惠券类型（满减券或折扣券），添加筛选条件
            if (couponType != null) {
                friendLifeDiscountCouponQueryWrapper.eq("ldc.coupon_type", couponType);
            }
            //获取当日日期
            Date now = new Date();
            // 根据tab类型添加查询条件（好友优惠券）
            Date pureDate = getPureDate(now);
            if ("1".equals(tab)) {
                // 进行中：开启领取；用券时间范围未配置时视为满足，与「仅填使用时间、不配领取窗口」的场景一致
                friendLifeDiscountCouponQueryWrapper.eq("ldc.get_status", 1)
                        .and(w -> w.and(w2 -> w2.isNull("ldc.start_date").or().le("ldc.start_date", pureDate))
                                .and(w2 -> w2.isNull("ldc.end_date").or().ge("ldc.end_date", pureDate)));
            } else if ("2".equals(tab)) {
                // 已结束：结束时间 < 当前时间 且 开启领取
                friendLifeDiscountCouponQueryWrapper.lt("ldc.end_date", pureDate)
                        .eq("ldc.get_status", 1);
            } else if ("4".equals(tab)) {
                // 未开始：开始时间 > 当前时间
                friendLifeDiscountCouponQueryWrapper.gt("ldc.start_date", pureDate);
            } else if ("5".equals(tab)) {
                // 已下架：getStatus = 0（暂停领取）
                friendLifeDiscountCouponQueryWrapper.eq("ldc.get_status", 0);
            } else if ("6".equals(tab)) {
                // 已清库：发行量有限且库存为0
                friendLifeDiscountCouponQueryWrapper.and(w ->
                        w.isNull("ldc.unlimited_qty").or().eq("ldc.unlimited_qty", 0));
                friendLifeDiscountCouponQueryWrapper.eq("ldc.single_qty", 0);
            }
            // tab=0或其他值：查询全部，不添加额外条件
            // tab=3（草稿）已在上面处理，这里不再重复设置
            friendLifeDiscountCouponQueryWrapper.orderByDesc("ldc.created_time");
            friendLifeDiscountCouponQueryWrapper.and(w -> w.eq("ldcsf.receiver_store_id", storeId)
                    .or(sub -> sub.isNull("ldcsf.receiver_store_id").eq("ldcsf.store_user_id", storeId)));
            friendLifeDiscountCouponQueryWrapper.eq("ldcsf.delete_flag", 0);
            IPage<LifeDiscountCouponVo> lifeDiscountCouponIPage = lifeDiscountCouponStoreFriendMapper.selectPage(iPage, friendLifeDiscountCouponQueryWrapper);
            // 查询三个券规则，设置
            for (LifeDiscountCouponVo record : lifeDiscountCouponIPage.getRecords()) {
                LifeDiscountCouponVo lifeDiscountcouponVo = new LifeDiscountCouponVo();
                // 将 Date 转换为 LocalDate
                Instant instant = now.toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                LocalDate localNow = instant.atZone(zoneId).toLocalDate();
                
                // 计算优惠券状态
                Integer calculatedStatus = resolveInvalidStatusIfNeeded(record.getCouponStatus());
                if (calculatedStatus == null && !StringUtils.isEmpty(record.getBeginGetDate()) && !StringUtils.isEmpty(record.getEndGetDate())) {
                    int startResult = localNow.compareTo(record.getBeginGetDate());
                    int endResult = localNow.compareTo(record.getEndGetDate());
                    //如果当前时间小于开始时间
                    if (!LifeDiscountCouponStock.hasTemplateStockRemaining(record.getUnlimitedQty(), record.getSingleQty())) {//无库存则已售罄
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue());
                    } else if (record.getGetStatus() == null || record.getGetStatus().toString().equals(DiscountCouponEnum.NO_GET.getValue())) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue());
                    } else if (startResult < 0) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue());
                    } else if (endResult > 0) {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.FINISHED.getValue());
                    } else {
                        calculatedStatus = Integer.parseInt(DiscountCouponEnum.UNDER_WAY.getValue());
                    }
                } else {
                    calculatedStatus = resolveListStatusWhenGetWindowMissing(
                            record.getCouponStatus(),
                            record.getGetStatus(),
                            record.getUnlimitedQty(),
                            record.getSingleQty());
                }
                
                // 如果状态计算失败，跳过该记录
                if (calculatedStatus == null) {
                    continue;
                }
                
                // 根据tab类型过滤状态
                if (!"0".equals(tab)) {
                    if ("3".equals(tab) && record.getCouponStatus() != 0) {
                        // 草稿：必须是couponStatus=0
                        continue;
                    } else if ("4".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue()))) {
                        // 未开始：必须是未开始状态
                        continue;
                    } else if ("5".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue()))) {
                        // 已下架：必须是暂停领取状态
                        continue;
                    } else if ("6".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue()))) {
                        // 已清库：必须是已售罄状态
                        continue;
                    } else if ("1".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.UNDER_WAY.getValue()))) {
                        // 进行中：必须是进行中状态
                        continue;
                    } else if ("2".equals(tab) && !calculatedStatus.equals(Integer.parseInt(DiscountCouponEnum.FINISHED.getValue()))) {
                        // 已结束：必须是已结束状态
                        continue;
                    }
                }
                
                record.setStatus(calculatedStatus);
                // 查询优惠券不可用规则（好友优惠券）
                List<LifeDiscountCouponUnavailableRules> unavailableRules = lifeDiscountCouponUnavailableRulesMapper.selectList(
                        new LambdaQueryWrapper<LifeDiscountCouponUnavailableRules>()
                                .eq(LifeDiscountCouponUnavailableRules::getDiscountCouponId, record.getCouponId()));
                
                // 按规则类型分组
                Map<String, List<LifeDiscountCouponUnavailableRules>> rulesMap = unavailableRules.stream()
                        .collect(Collectors.groupingBy(LifeDiscountCouponUnavailableRules::getUnavailableRuleType));
                
                // 设置工作日不可用列表
                String weekdayKey = DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue();
                if (rulesMap.containsKey(weekdayKey)) {
                    record.setWeeklyDisabledList(rulesMap.get(weekdayKey).stream()
                            .map(LifeDiscountCouponUnavailableRules::getUnavailableRuleValue)
                            .collect(Collectors.toList()));
                }
                
                // 设置节假日不可用列表
                String holidayKey = DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue();
                if (rulesMap.containsKey(holidayKey)) {
                    record.setHolidayDisabledList(rulesMap.get(holidayKey).stream()
                            .map(LifeDiscountCouponUnavailableRules::getUnavailableRuleValue)
                            .collect(Collectors.toList()));
                }
                
                // 设置领取规则
                String claimRuleKey = DiscountCouponEnum.CLAIM_RULE.getValue();
                if (rulesMap.containsKey(claimRuleKey) && !rulesMap.get(claimRuleKey).isEmpty()) {
                    record.setClaimRule(rulesMap.get(claimRuleKey).get(0).getUnavailableRuleValue());
                }
                BeanUtils.copyProperties(record, lifeDiscountcouponVo);
                friendLifeDiscountCouponVos.add(lifeDiscountcouponVo);
            }
            IPage<LifeDiscountCouponVo> friendLifeDiscountCouponVoIPage = new Page<>();
            BeanUtils.copyProperties(lifeDiscountCouponIPage, friendLifeDiscountCouponVoIPage);
            friendLifeDiscountCouponVoIPage.setRecords(friendLifeDiscountCouponVos);
            return friendLifeDiscountCouponVoIPage;
        }
    }

    @Override
    public List<LifeDiscountCouponVo> getStoreAllCouponListPaginateNot(String status, String storeId, UserLoginInfo userLoginInfo, int couponStatus, Integer type, Integer couponType) {
        List<LifeDiscountCouponVo> result = new ArrayList<>();
        if (Integer.valueOf(4).equals(type)) {
            // type=4：直接查 life_coupon（代金券），返回代金券数据。life_coupon.type=1 为代金券，data_type 0正式/1草稿 与 couponStatus 1/0 对应
            LambdaQueryWrapper<LifeCoupon> wrapper = new LambdaQueryWrapper<LifeCoupon>()
                    .eq(LifeCoupon::getStoreId, storeId)
                    .eq(LifeCoupon::getType, 1)
                    .ne(LifeCoupon::getSingleQty, 0)
                    .eq(LifeCoupon::getDataType, 1 - couponStatus);
            List<LifeCoupon> lifeCoupons = lifeCouponMapper.selectList(wrapper);
            for (LifeCoupon lc : lifeCoupons) {
                LifeDiscountCouponVo vo = mapLifeCouponToVo(lc);
                if (!StringUtils.isEmpty(status) && !status.equals(vo.getStatus() != null ? vo.getStatus().toString() : "")) {
                    continue;
                }
                result.add(vo);
            }
            return result;
        }

        // type 不为 4：只查 life_discount_coupon 单表（优惠券列表）
        List<LifeDiscountCoupon> lifeDiscountCoupons = lifeDiscountCouponMapper.selectListSingleTable(storeId, couponStatus, type, couponType);
        for (LifeDiscountCoupon lifeDiscountCoupon : lifeDiscountCoupons) {
            LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
            lifeDiscountCouponVo.setCouponId(lifeDiscountCoupon.getId());
            lifeDiscountCouponVo.setType(lifeDiscountCoupon.getType());
            Date now = new Date();
            Instant instant = now.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate localNow = instant.atZone(zoneId).toLocalDate();
            Integer invalidStatus = resolveInvalidStatusIfNeeded(lifeDiscountCoupon.getCouponStatus());
            if (invalidStatus != null) {
                lifeDiscountCouponVo.setStatus(invalidStatus);
            } else if (!StringUtils.isEmpty(lifeDiscountCoupon.getBeginGetDate()) && !StringUtils.isEmpty(lifeDiscountCoupon.getEndGetDate())) {
                int startResult = localNow.compareTo(lifeDiscountCoupon.getBeginGetDate());
                int endResult = localNow.compareTo(lifeDiscountCoupon.getEndGetDate());
                if (!LifeDiscountCouponStock.hasTemplateStockRemaining(
                        lifeDiscountCoupon.getUnlimitedQty(), lifeDiscountCoupon.getSingleQty())) {
                    lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue()));
                } else if (startResult < 0) {
                    lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue()));
                } else if (lifeDiscountCoupon.getGetStatus() == null || lifeDiscountCoupon.getGetStatus().toString().equals(DiscountCouponEnum.NO_GET.getValue())) {
                    lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue()));
                } else if (endResult > 0) {
                    lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.FINISHED.getValue()));
                } else if (startResult >= 0 && endResult <= 0) {
                    lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.UNDER_WAY.getValue()));
                }
            } else {
                lifeDiscountCouponVo.setStatus(resolveListStatusWhenGetWindowMissing(
                        lifeDiscountCoupon.getCouponStatus(),
                        lifeDiscountCoupon.getGetStatus(),
                        lifeDiscountCoupon.getUnlimitedQty(),
                        lifeDiscountCoupon.getSingleQty()));
            }
            BeanUtils.copyProperties(lifeDiscountCoupon, lifeDiscountCouponVo);
            lifeDiscountCouponVo.setCreatedTime(lifeDiscountCoupon.getCreatedTime() != null ? lifeDiscountCoupon.getCreatedTime() : null);
            if (!StringUtils.isEmpty(status) && (lifeDiscountCouponVo.getStatus() == null || !status.equals(lifeDiscountCouponVo.getStatus().toString()))) {
                continue;
            }
            result.add(lifeDiscountCouponVo);
        }
        return result;
    }

    /** 将 life_coupon（代金券）转为 LifeDiscountCouponVo，便于与 life_discount_coupon 统一返回 */
    private LifeDiscountCouponVo mapLifeCouponToVo(LifeCoupon lc) {
        LifeDiscountCouponVo vo = new LifeDiscountCouponVo();
        vo.setVoucherId(lc.getId());
        vo.setStoreId(lc.getStoreId());
        vo.setName(lc.getName());
        vo.setSingleQty(lc.getSingleQty());
        vo.setCreatedTime(lc.getCreatedTime());
        vo.setType(4);
        if (lc.getStartDate() != null) {
            vo.setStartDate(lc.getStartDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        }
        if (lc.getEndDate() != null) {
            vo.setEndDate(lc.getEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        }
        if (lc.getPrice() != null) {
            try {
                vo.setNominalValue(new BigDecimal(lc.getPrice()));
            } catch (Exception ignored) { }
        }
        if (lc.getStatus() != null) {
            if (lc.getStatus() == 5) {
                vo.setStatus(0);
            } else if (lc.getStatus() == 7 || lc.getStatus() == 6) {
                vo.setStatus(1);
            } else if (lc.getStatus() == 2) {
                vo.setStatus(2);
            } else {
                vo.setStatus(3);
            }
        }
        vo.setLongTermValid(0);
        vo.setUnlimitedQty(0);
        return vo;
    }

    @Override
    public String getCouponRule(String couponId, UserLoginInfo userLoginInfo, Integer type, String voucherId) {
        // type=4：仅代金券，根据 life_coupon 构建使用规则文案（代金券 id 优先用 id 参数，未传则用 couponId）
        if (type != null && type == 4) {
            String vid = (voucherId != null && !voucherId.isEmpty()) ? voucherId : couponId;
            if (vid == null || vid.isEmpty()) {
                return "";
            }
            LifeCoupon lc = lifeCouponMapper.selectById(vid);
            return lc != null ? buildLifeCouponRule(lc) : "";
        }
        // type=1：仅优惠券，根据 life_discount_coupon 构建使用规则
        if (type != null && type == 1) {
            try {
                Integer coupon = Integer.parseInt(couponId);
                LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(coupon);
                if (lifeDiscountCoupon == null) {
                    return "";
                }
                return buildDiscountCouponRule(lifeDiscountCoupon);
            } catch (NumberFormatException e) {
                return "";
            }
        }
        // type 不传：根据 life_discount_coupon 与 life_coupon 两张表分别构建使用规则文案并都返回
        StringBuilder sb = new StringBuilder();
        try {
            Integer coup = Integer.parseInt(couponId);
            LifeDiscountCoupon c = lifeDiscountCouponMapper.selectByIdIncludeDeleted(coup);
            if (c != null) {
                sb.append("【优惠券使用规则】\n").append(buildDiscountCouponRule(c));
            }
        } catch (NumberFormatException ignored) {
        }
        String vid = (voucherId != null && !voucherId.isEmpty()) ? voucherId : couponId;
        if (vid != null && !vid.isEmpty()) {
            try {
                LifeCoupon lc = lifeCouponMapper.selectById(vid);
                if (lc != null) {
                    if (sb.length() > 0) {
                        sb.append("\n\n");
                    }
                    sb.append("【代金券使用规则】\n").append(buildLifeCouponRule(lc));
                }
            } catch (Exception ignored) {
            }
        }
        return sb.toString();
    }

    /** 根据 life_coupon（代金券）构建使用规则文案，委托给 buildVoucherCouponRule，与 buildDiscountCouponRule 对应的一套代金券逻辑 */
    private String buildLifeCouponRule(LifeCoupon lc) {
        return buildVoucherCouponRule(lc);
    }

    /** 根据 life_discount_coupon 构建使用规则文案（节假日/周中禁用 + 最低消费） */
    private String buildDiscountCouponRule(LifeDiscountCoupon lifeDiscountCoupon) {
        // 获取 Calendar 实例，默认表示当前日期和时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = dateFormat.format(currentDate);
        int year = calendar.get(Calendar.YEAR);
        LambdaQueryWrapper<EssentialHolidayComparison> essentialHolidayComparisonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        essentialHolidayComparisonLambdaQueryWrapper.eq(EssentialHolidayComparison::getParticularYear, year);
        List<EssentialHolidayComparison> essentialHolidayComparisons = essentialHolidayComparisonMapper.selectList(essentialHolidayComparisonLambdaQueryWrapper);
        String festivalName = "";
        for (EssentialHolidayComparison essentialHolidayComparison : essentialHolidayComparisons) {
            if (essentialHolidayComparison.getFestivalDate().equals(formattedDate)) {
                festivalName = essentialHolidayComparison.getFestivalName();
            }
        }
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String dayName = "";
        switch (dayOfWeek) {
            case Calendar.SUNDAY:
                dayName = "日";
                break;
            case Calendar.MONDAY:
                dayName = "一";
                break;
            case Calendar.TUESDAY:
                dayName = "二";
                break;
            case Calendar.WEDNESDAY:
                dayName = "三";
                break;
            case Calendar.THURSDAY:
                dayName = "四";
                break;
            case Calendar.FRIDAY:
                dayName = "五";
                break;
            case Calendar.SATURDAY:
                dayName = "六";
                break;
            default:
                break;
        }

        LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
        List<LifeDiscountCouponUnavailableRules> allUnavailableRules =
                lifeDiscountCouponUnavailableRulesMapper.listByDiscountCouponIdIncludeDeleted(lifeDiscountCoupon.getId());
        List<LifeDiscountCouponUnavailableRules> lifeDiscountCouponUnavailableRules = allUnavailableRules.stream()
                .filter(r -> DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue().equals(r.getUnavailableRuleType()))
                .collect(Collectors.toList());
        String forbiddenRule = "";
        if (lifeDiscountCouponUnavailableRules.size() > 0) {
            forbiddenRule += HOLIDAY_RULE_TITLE;
        }
        List<String> holidCoupnDis = lifeDiscountCouponUnavailableRules.stream().map(rule -> rule.getUnavailableRuleValue()).collect(Collectors.toList());
        forbiddenRule += String.join(", ", holidCoupnDis);
        for (LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRule : lifeDiscountCouponUnavailableRules) {
            if (StringUtils.isEmpty(festivalName) && festivalName.equals(lifeDiscountCouponUnavailableRule.getUnavailableRuleValue())) {
                lifeDiscountCouponVo.setDisabledStatus(false);
            }
        }
        if (lifeDiscountCouponUnavailableRules.size() > 0) {
            forbiddenRule += NOT_USE;
        }
        List<LifeDiscountCouponUnavailableRules> weekLifeDiscountCouponUnavailableRules = allUnavailableRules.stream()
                .filter(r -> DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue().equals(r.getUnavailableRuleType()))
                .collect(Collectors.toList());
        if (weekLifeDiscountCouponUnavailableRules.size() > 0) {
            forbiddenRule += WEEK_RULE_TITLE;
        }
        List<String> weekCoupnDis = weekLifeDiscountCouponUnavailableRules.stream().map(rule -> rule.getUnavailableRuleValue()).collect(Collectors.toList());
        forbiddenRule += String.join(", ", weekCoupnDis);
        for (LifeDiscountCouponUnavailableRules lifeDiscountCouponUnavailableRule : weekLifeDiscountCouponUnavailableRules) {
            if (dayName.equals(lifeDiscountCouponUnavailableRule.getUnavailableRuleValue())) {
                lifeDiscountCouponVo.setDisabledStatus(false);
            }
        }
        if (weekLifeDiscountCouponUnavailableRules.size() > 0) {
            forbiddenRule += NOT_USE;
        }
        
        // 根据优惠券类型显示不同的信息
        Integer couponType = lifeDiscountCoupon.getCouponType();
        if (couponType != null && couponType == 2) {
            // 折扣券：显示折扣率和最低消费
            if (lifeDiscountCoupon.getDiscountRate() != null) {
                BigDecimal zheShu = lifeDiscountCoupon.getDiscountRate().divide(BigDecimal.TEN, 2, RoundingMode.HALF_UP);
                forbiddenRule += "折扣率：" + zheShu.stripTrailingZeros().toPlainString() + "折；";
            }
        } else {
            // 满减券（默认）：显示面值和最低消费
            if (lifeDiscountCoupon.getNominalValue() != null) {
                forbiddenRule += "面值：" + lifeDiscountCoupon.getNominalValue() + "元；";
            }
        }
        
        // 如果最低消费为0或null，显示"无门槛"
        BigDecimal minimumSpending = lifeDiscountCoupon.getMinimumSpendingAmount();
        if (minimumSpending == null || minimumSpending.compareTo(BigDecimal.ZERO) == 0) {
            forbiddenRule += MINIMUM_SPENDING_AMOUNT + "无门槛";
        } else {
            forbiddenRule += MINIMUM_SPENDING_AMOUNT + minimumSpending;
        }
        lifeDiscountCouponVo.setForbiddenRule(forbiddenRule);
        return forbiddenRule;
    }

    /**
     * 代金券使用规则文案（对应表 life_coupon），逻辑与 buildDiscountCouponRule 平行：查 essentialHolidayComparison、lifeDiscountCouponUnavailableRules（按 voucher_id），再拼接面值/使用规则/有效期等。
     */
    private String buildVoucherCouponRule(LifeCoupon lifeCoupon) {
        // 与 buildDiscountCouponRule 一致：Calendar、当日日期、年份
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = dateFormat.format(currentDate);
        int year = calendar.get(Calendar.YEAR);
        // 查 essentialHolidayComparison 获取当日是否节假日
        LambdaQueryWrapper<EssentialHolidayComparison> essentialHolidayComparisonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        essentialHolidayComparisonLambdaQueryWrapper.eq(EssentialHolidayComparison::getParticularYear, String.valueOf(year));
        List<EssentialHolidayComparison> essentialHolidayComparisons = essentialHolidayComparisonMapper.selectList(essentialHolidayComparisonLambdaQueryWrapper);
        String festivalName = "";
        for (EssentialHolidayComparison essentialHolidayComparison : essentialHolidayComparisons) {
            if (essentialHolidayComparison.getFestivalDate() != null && formattedDate.equals(essentialHolidayComparison.getFestivalDate().toString())) {
                festivalName = essentialHolidayComparison.getFestivalName();
            }
        }
        // 当日周几
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String dayName = "";
        switch (dayOfWeek) {
            case Calendar.SUNDAY:
                dayName = "日";
                break;
            case Calendar.MONDAY:
                dayName = "一";
                break;
            case Calendar.TUESDAY:
                dayName = "二";
                break;
            case Calendar.WEDNESDAY:
                dayName = "三";
                break;
            case Calendar.THURSDAY:
                dayName = "四";
                break;
            case Calendar.FRIDAY:
                dayName = "五";
                break;
            case Calendar.SATURDAY:
                dayName = "六";
                break;
            default:
                break;
        }
        // 代金券按 voucher_id 查 life_discount_coupon_unavailable_rules（节假日 + 周中），与优惠券按 discount_coupon_id 查对应
        String voucherId = lifeCoupon.getId();
        LambdaQueryWrapper<LifeDiscountCouponUnavailableRules> holidayWrapper = new LambdaQueryWrapper<>();
        holidayWrapper.eq(LifeDiscountCouponUnavailableRules::getVoucherId, voucherId);
        holidayWrapper.eq(LifeDiscountCouponUnavailableRules::getUnavailableRuleType, DiscountCouponEnum.HOLIDAY_UNAVAILABLE.getValue());
        List<LifeDiscountCouponUnavailableRules> holidayRules = lifeDiscountCouponUnavailableRulesMapper.selectList(holidayWrapper);
        String forbiddenRule = "";
        if (!holidayRules.isEmpty()) {
            forbiddenRule += HOLIDAY_RULE_TITLE;
            forbiddenRule += holidayRules.stream().map(LifeDiscountCouponUnavailableRules::getUnavailableRuleValue).collect(Collectors.joining(", "));
            forbiddenRule += NOT_USE;
        }
        LambdaQueryWrapper<LifeDiscountCouponUnavailableRules> weekWrapper = new LambdaQueryWrapper<>();
        weekWrapper.eq(LifeDiscountCouponUnavailableRules::getVoucherId, voucherId);
        weekWrapper.eq(LifeDiscountCouponUnavailableRules::getUnavailableRuleType, DiscountCouponEnum.WEEKDAY_UNAVAILABLE.getValue());
        List<LifeDiscountCouponUnavailableRules> weekRules = lifeDiscountCouponUnavailableRulesMapper.selectList(weekWrapper);
        if (!weekRules.isEmpty()) {
            forbiddenRule += WEEK_RULE_TITLE;
            forbiddenRule += weekRules.stream().map(LifeDiscountCouponUnavailableRules::getUnavailableRuleValue).collect(Collectors.joining(", "));
            forbiddenRule += NOT_USE;
        }
        // life_coupon 表字段：面值、使用规则、使用有效期、购买须知使用时间
        forbiddenRule += "面值：" + (lifeCoupon.getPrice() != null ? lifeCoupon.getPrice() : "");
        if (!StringUtils.isEmpty(lifeCoupon.getUseRule())) {
            forbiddenRule += "\n使用规则：" + lifeCoupon.getUseRule();
        }
        if (lifeCoupon.getStartDate() != null || lifeCoupon.getEndDate() != null) {
            forbiddenRule += "\n使用有效期：";
            if (lifeCoupon.getStartDate() != null) {
                forbiddenRule += new SimpleDateFormat("yyyy-MM-dd").format(lifeCoupon.getStartDate());
            }
            forbiddenRule += " 至 ";
            if (lifeCoupon.getEndDate() != null) {
                forbiddenRule += new SimpleDateFormat("yyyy-MM-dd").format(lifeCoupon.getEndDate());
            }
        }
        if (!StringUtils.isEmpty(lifeCoupon.getBuyUseStartTime()) || !StringUtils.isEmpty(lifeCoupon.getBuyUseEndTime())) {
            forbiddenRule += "\n购买须知使用时间：";
            if (!StringUtils.isEmpty(lifeCoupon.getBuyUseStartTime())) {
                forbiddenRule += lifeCoupon.getBuyUseStartTime();
            }
            forbiddenRule += " 至 ";
            if (!StringUtils.isEmpty(lifeCoupon.getBuyUseEndTime())) {
                forbiddenRule += lifeCoupon.getBuyUseEndTime();
            }
        }
        return forbiddenRule;
    }

    
    /**
     * <p>
     * 获取优惠券状态
     * </p>
     *
     * @author zhangchen
     * @since 2025-07-14
     */
    @Override
    public LifeCouponStatusVo getCouponStatus(String couponId) {
        if (couponId == null || couponId.isEmpty()) {
            log.error("获取优惠券状态失败：couponId为空");
            throw new IllegalArgumentException("couponId不能为空");
        }
        try {
            LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectByIdIncludeDeleted(Integer.parseInt(couponId.trim()));
            LifeCouponStatusVo lifeCouponStatusVo = new LifeCouponStatusVo();
            if (lifeDiscountCoupon != null) {
                lifeCouponStatusVo.setCouponId(couponId);
                lifeCouponStatusVo.setSingleQty(lifeDiscountCoupon.getSingleQty());
            } else {
                // 可选：设置默认值或标记状态为无效
                lifeCouponStatusVo.setSingleQty(0); // 或其他默认逻辑
            }
            return lifeCouponStatusVo;
        } catch (Exception e) {
            log.error("获取优惠券状态失败: {}", e);
            throw new RuntimeException("获取优惠券状态失败", e); // 或者根据项目规范处理
        }
    }

    /**
     * 获取平台优惠券列表
     *
     * @param pageNum    分页页码
     * @param pageSize   分页大小
     * @param name       优惠券名称
     * @param createDate 创建时间
     * @param couponType 类型:(1:优惠券, 2:红包, 3:平台优惠券)
     * @return IPage<LifeDiscountCoupon>
     */
    @Override
    public IPage<LifeDiscountCoupon> getPlatformCouponList(Integer pageNum, Integer pageSize, String name, String createDate, Integer couponType) {
        IPage<LifeDiscountCoupon> iPage = new Page<>(pageNum, pageSize);
        return lifeDiscountCouponMapper.selectPage(iPage, new LambdaQueryWrapper<LifeDiscountCoupon>()
                .eq(LifeDiscountCoupon::getType, 3)
                .like(!StringUtils.isEmpty(name), LifeDiscountCoupon::getName, name)
                .orderByDesc(LifeDiscountCoupon::getCreatedTime)
                .between(!StringUtils.isEmpty(createDate), LifeDiscountCoupon::getCreatedTime, createDate + " 00:00:00", createDate + " 23:59:59"));
    }

    /**
     * 新增平台优惠券
     *
     * @param lifeDiscountCoupon 优惠券实体
     * @return boolean
     */
    @Override
    public boolean addPlatformCoupon(LifeDiscountCoupon lifeDiscountCoupon) {
        lifeDiscountCoupon.setStartDate(LocalDate.now());
        if (null == lifeDiscountCoupon.getSpecifiedDay()) {
            return false;
        }
        lifeDiscountCoupon.setEndDate(LocalDate.now().plusDays(Long.parseLong(lifeDiscountCoupon.getSpecifiedDay())));
        lifeDiscountCoupon.setType(3);
        lifeDiscountCoupon.setGetStatus(1);
//        lifeDiscountCoupon.setMinimumSpendingAmount(BigDecimal.ZERO);
        return this.save(lifeDiscountCoupon);
    }

    /**
     * 查询平台优惠券详情
     *
     * @param id 柱间, 妈的就叫这个吧! 哈西辣妈!
     * @return LifeDiscountCoupon
     */
    @Override
    public LifeDiscountCoupon getOnePlatformCoupon(Integer id) {
        return this.getById(id);
    }

    /**
     * 发放平台优惠券
     *
     * @param userIds  用户主键List
     * @param couponId 优惠券id
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean issuePlatformCoupon(List<Integer> userIds, Integer couponId) {
        if (userIds == null || userIds.isEmpty()) {
            return false;
        }
        LifeDiscountCoupon lifeDiscountCoupon = this.getById(couponId);
        if (lifeDiscountCoupon == null) {
            return false;
        }
        int grantCount = userIds.size();

        if (!LifeDiscountCouponStock.isUnlimitedQty(lifeDiscountCoupon.getUnlimitedQty())) {
            Integer q = lifeDiscountCoupon.getSingleQty();
            if (q == null || q < grantCount) {
                return false;
            }
            lifeDiscountCoupon.setSingleQty(q - grantCount);
        }

        List<LifeDiscountCouponUser> lifeDiscountCouponUsers = new ArrayList<>();
        for (Integer userId : userIds) {
            LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
            lifeDiscountCouponUser.setUserId(userId);
            lifeDiscountCouponUser.setCouponId(couponId);
            lifeDiscountCouponUser.setReceiveTime(new Date());
            lifeDiscountCouponUser.setExpirationTime(DiscountCouponExpirationUtil.resolveLifeDiscountCouponExpiration(
                    lifeDiscountCouponUser.getReceiveTime(),
                    lifeDiscountCoupon.getLongTermValid(),
                    lifeDiscountCoupon.getSpecifiedDay(),
                    lifeDiscountCoupon.getExpirationDate(),
                    lifeDiscountCoupon.getValidDate(),
                    lifeDiscountCoupon.getEndDate(),
                    ZoneId.systemDefault()));
            lifeDiscountCouponUser.setStatus(0);
            lifeDiscountCouponUser.setDeleteFlag(0);
            lifeDiscountCouponUser.setCreatedTime(new Date());
            lifeDiscountCouponUser.setIssueSource(5); // 5-平台发放
            lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
        }
        if (!lifeDiscountCouponUserService.saveBatch(lifeDiscountCouponUsers)) {
            return false;
        }
        if (!LifeDiscountCouponStock.isUnlimitedQty(lifeDiscountCoupon.getUnlimitedQty())) {
            lifeDiscountCoupon.setUpdatedTime(new Date());
            if (!this.updateById(lifeDiscountCoupon)) {
                throw new IllegalStateException("平台发券失败：优惠券模板发行量更新失败 couponId=" + couponId);
            }
        }
        return true;
    }

    /**
     * 收回平台优惠券
     *
     * @param couponId 优惠券id
     * @return boolean
     */
    @Override
    public boolean recoverPlatformCoupon(Integer couponId) {
        return lifeDiscountCouponUserService.remove(new LambdaQueryWrapper<LifeDiscountCouponUser>().eq(LifeDiscountCouponUser::getCouponId, couponId));
    }

    /**
     * 删除平台优惠券
     *
     * @param couponId 优惠券id
     * @return boolean
     */
    @Override
    public boolean deletePlatformCoupon(Integer couponId) {
        int count = lifeDiscountCouponUserService.count(new LambdaQueryWrapper<LifeDiscountCouponUser>().eq(LifeDiscountCouponUser::getCouponId, couponId));
        if (count > 0) {
            return false;
        } else {
            return this.removeById(couponId);
        }
    }

    /**
     * 分页查询该券发放记录
     *
     * @param pageNum  分页页码
     * @param pageSize 分页大小
     * @param userName 用户名
     * @param phone    手机号
     * @param couponId 优惠券id
     * @return IPage<LifeDiscountCouponUserWebVo>
     */
    @Override
    public IPage<LifeDiscountCouponUserWebVo> getPlatformCouponLogList(Integer pageNum, Integer pageSize, String userName, String phone, Integer couponId) {
        IPage<LifeDiscountCouponUserWebVo> iPage = new Page<>(pageNum, pageSize);
        return lifeDiscountCouponUserMapper.selectPageList(iPage, new QueryWrapper<LifeDiscountCouponUserWebVo>()
                .eq(!StringUtils.isEmpty(couponId), "a.coupon_id", couponId)
                .like(!StringUtils.isEmpty(userName), "b.real_name", userName)
                .like(!StringUtils.isEmpty(phone), "b.user_phone", phone));
    }

    @Override
    public List<LifeDiscountCoupon> getPlatformCoupon(Integer couponId, Integer couponType) {
        LambdaQueryWrapper<LifeDiscountCoupon> lifeDiscountCouponLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (couponId != null) {
            lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getId, couponId);
        }
        if (couponType != null) {
            lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getType, couponType);
        }
        lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getDeleteFlag, 0);
        lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getGetStatus, 1);
        return lifeDiscountCouponMapper.selectList(lifeDiscountCouponLambdaQueryWrapper);
    }
}
