package com.cf.imes.module.system.service.funds.purchase;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.date.LocalDateTimeUtils;
import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelayRespVO;
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.TotalSalesAmountRespVO;
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.OrgEarliestPurchaseProductRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailsPageReqVO;
import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganCreateProductPurchaseReqVO;
import com.cf.imes.module.system.controller.admin.statistics.vo.ManageSalesTotalStatisticRespVO;
import com.cf.imes.module.system.dal.dataobject.funds.productpromotion.ProductPromotionDO;
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO;
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO;
import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.mysql.funds.purchase.PurchaseRecordMapper;
import com.cf.imes.module.system.enums.pay.InvoiceStatusEnum;
import com.cf.imes.module.system.enums.pay.PayChannelCodeEnum;
import com.cf.imes.module.system.enums.pay.ProductDurationUnitEnum;
import com.cf.imes.module.system.enums.pay.PurchaseRecordStatusEnum;
import com.cf.imes.module.system.enums.pay.TradeTypeEnum;
import com.cf.imes.module.system.framework.snowflake.config.MybatisIdProperties;
import com.cf.imes.module.system.service.funds.delay.ProductDelayService;
import com.cf.imes.module.system.service.funds.productpromotion.ProductPromotionService;
import com.cf.imes.module.system.service.funds.products.ProductsDetailService;
import com.cf.imes.module.system.service.organ.OrganService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_DELAY_RECORD_PAID_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_EXIST_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCT_PRICE_NULL_ERROR;
import static com.cf.imes.module.system.enums.pay.PayConstants.PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT;
import static com.cf.imes.module.system.enums.pay.PayConstants.PAY_PRODUCT_DETAIL_AUTO_GENERATE_YEAR_ID_FORMAT;

/**
 * @author 软件购买接口 实现类
 */
@Slf4j
@Service
public class PurchaseServiceImpl implements PurchaseService {

    @Resource
    private PurchaseRecordMapper purchaseRecordMapper;

    @Resource
    private ProductsDetailService productsDetailService;

    @Resource
    private MybatisIdProperties mybatisIdProperties;

    @Resource
    @Lazy
    private OrganService organService;

    @Resource
    @Lazy
    private ProductDelayService productDelayService;

    @Resource
    private ProductPromotionService productPromotionService;

    @Resource
    private I18nUtils i18nUtils;

    @Override
    public PurchaseRecordDO getRecord(Long id) {
        return purchaseRecordMapper.selectById(id);
    }

    @Override
    public void deleteRecord(Long id) {
        // 删除且作废
        purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getId, id)
                .set(PurchaseRecordDO::getDeleted, true)
                .set(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.INACTIVE.getStatus()));
    }

    @Override
    public PageResult<PurchaseRecordRespVO> getPurchaseRecord(PurchaseRecordPageReqVO pageReqVO) {
        // 生成起时间0点和止时间12点的区间
        pageReqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getCreateTime()));
        // 生成产品有效时间0点和止时间12点的区间
        LocalDate[] endTime = pageReqVO.getEndTime();
        if (ArrayUtil.isNotEmpty(endTime) && endTime.length == 2) {
            pageReqVO.setEndTimeSection(new LocalDateTime[]{
                    pageReqVO.getEndTime()[0].atStartOfDay(),
                    pageReqVO.getEndTime()[1].plusDays(1).atStartOfDay()
            });
        } else {
            pageReqVO.setEndTimeSection(null);
        }

        PageResult<PurchaseRecordDO> pageResult = purchaseRecordMapper.selectPage(pageReqVO);
        List<PurchaseRecordDO> resultList = pageResult.getList();

        if (CollUtil.isEmpty(resultList)) {
            return new PageResult<>();
        }
        List<PurchaseRecordRespVO> respVOS = new ArrayList<>();
        for (PurchaseRecordDO purchaseRecordDO : resultList) {
            PurchaseRecordRespVO respVO = BeanUtil.copyProperties(purchaseRecordDO, PurchaseRecordRespVO.class, "paymentMethod");
            respVO.setPaymentMethod(i18nUtils.getMessage(PayChannelCodeEnum.describe(purchaseRecordDO.getPaymentMethod())));
            respVO.setPayStatus(purchaseRecordDO.getStatus());
            respVOS.add(respVO);
        }
        respVOS.forEach(respVO -> {
            OrganizationDO organ = organService.getOrganWithDeleted(respVO.getOrganId());
            if (ObjectUtil.isNotNull(organ)) {
                respVO.setOrganName(organ.getName());
            }
        });
        return new PageResult<>(respVOS, pageResult.getTotal());
    }

    @Override
    public void createRecord(PurchaseRecordDO purchaseRecordDO) {
        purchaseRecordMapper.insert(purchaseRecordDO);
    }

    @Override
    public void updateRecordInvoicable(Long purchaseRecordId, Long organId) {
        purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getId, purchaseRecordId)
                .eq(PurchaseRecordDO::getOrganId, organId)
                .set(PurchaseRecordDO::getIsInvocing, InvoiceStatusEnum.INVOICABLE.getCode()));
    }

    @Override
    public OrgEarliestPurchaseProductRespVO getOrgEarliestProductDetail(Long organId) {
        // 查询购买记录中还有效的最晚一条
        PurchaseRecordDO purchaseRecordDO = purchaseRecordMapper.selectOne(new LambdaQueryWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getOrganId, organId)
                .eq(PurchaseRecordDO::getDeleted, false)
                .eq(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.ACTIVE.getStatus())
                .orderByDesc(PurchaseRecordDO::getCreateTime)
                .last("limit 1"));
        if (ObjectUtil.isNotNull(purchaseRecordDO)) {
            // 查询延期记录
            List<ProductDelayRespVO> recordsByPurchaseId = productDelayService.getRecordsByPurchaseId(purchaseRecordDO.getId(), organId);
            if (CollUtil.isNotEmpty(recordsByPurchaseId)) {
                // 延期记录是按自增id逆序的，第一条的延期后时间作为产品到期时间
                purchaseRecordDO.setEndTime(recordsByPurchaseId.get(0).getDelayTime());
            }
            return new OrgEarliestPurchaseProductRespVO(purchaseRecordDO);
        }
        return null;
    }

    @Override
    public BigDecimal getInvoicingAmount(Long organId) {
        return purchaseRecordMapper.getInvoicingAmount(organId);
    }

    @Override
    public void createOrgInitProductPurchaseRecord(Long organId, List<OrganCreateProductPurchaseReqVO> productPurchaseReqVOS) {
        if (CollUtil.isEmpty(productPurchaseReqVOS)) {
            return;
        }
        for (OrganCreateProductPurchaseReqVO purchaseReqVO : productPurchaseReqVOS) {
            // 1、校验产品
            Long productId = purchaseReqVO.getProductId();
            ProductsDO productsDO = productsDetailService.validateProductExist(productId);

            // 2、创建购买记录

            // 输入的价格
            BigDecimal price = purchaseReqVO.getPrice();
            // 首次订购默认是1年的价格，月均单价/10（赠送两个月）
            BigDecimal monthAverageAmount = price.divide(new BigDecimal(10), 2, RoundingMode.DOWN);

            long purchaseId = IdUtil.getSnowflake(mybatisIdProperties.getWorkerId(), mybatisIdProperties.getDatacenterId()).nextId();

            LocalDate now = LocalDate.now();
            PurchaseRecordDO purchaseRecordDO = PurchaseRecordDO.builder()
                    .id(purchaseId)
                    .organId(organId)
                    .productId(productId)
                    .productName(productsDO.getProductName())
                    .productDetailsId(0L)
                    .purchaseDuration(1)
                    .purchaseDurationUnit(ProductDurationUnitEnum.YEAR.getCode())
                    .startTime(now)
                    // 组织创建时的套餐购买默认过期
                    .endTime(now.minusDays(1))
                    .totalAmount(price)
                    .monthAverageAmount(monthAverageAmount)
                    .originalAmount(price)
                    .initial(true)
                    .status(PurchaseRecordStatusEnum.ACTIVE.getStatus())
                    .build();
            createRecord(purchaseRecordDO);
        }
    }

    @Override
    public void updateOrgInitProductPurchaseRecord(Long organId, List<OrganCreateProductPurchaseReqVO> productPurchaseReqVOS) {
        // 1、查询组织下的产品首购记录
        List<PurchaseRecordDO> currOrgProductInitialPurchaseList = purchaseRecordMapper.selectList(new LambdaQueryWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getOrganId, organId)
                .eq(PurchaseRecordDO::getInitial, true)
                .eq(PurchaseRecordDO::getDeleted, false));

        // 2、入参整理为新增列表和修改列表
        List<OrganCreateProductPurchaseReqVO> createList = productPurchaseReqVOS.stream().filter(purchaseReqVO -> ObjectUtil.isNull(purchaseReqVO.getPurchaseId())).toList();
        List<OrganCreateProductPurchaseReqVO> updateList = productPurchaseReqVOS.stream().filter(purchaseReqVO -> ObjectUtil.isNotNull(purchaseReqVO.getPurchaseId())).toList();

        // 3、筛选出修改列表和当前记录中有差集的部分提示首购不存在
        Set<Long> currPurchaseIds = currOrgProductInitialPurchaseList.stream()
                .map(PurchaseRecordDO::getId)
                .collect(Collectors.toSet());

        boolean updateNotExist = updateList.stream()
                .map(OrganCreateProductPurchaseReqVO::getPurchaseId)
                .anyMatch(purchaseId -> !currPurchaseIds.contains(purchaseId));
        if (updateNotExist) {
            throw new ServiceException(ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR);
        }

        // 4、筛选出新增列表和当前记录中有产品id重复的提示订购记录已存在
        Map<Long, String> currProductMap = currOrgProductInitialPurchaseList.stream()
                .collect(Collectors.toMap(PurchaseRecordDO::getProductId, PurchaseRecordDO::getProductName));

        Optional<OrganCreateProductPurchaseReqVO> duplicateOpt = createList.stream()
                .filter(req -> currProductMap.containsKey(req.getProductId()))
                .findFirst();

        if (duplicateOpt.isPresent()) {
            throw new ServiceException(ORG_PRODUCT_PURCHASE_EXIST_ERROR, currProductMap.get(duplicateOpt.get().getProductId()));
        }

        // 5、删选出当前记录和入参列表中purchaseId不重复的，作为删除的部分
        Set<Long> inputPurchaseIds = updateList.stream().map(OrganCreateProductPurchaseReqVO::getPurchaseId).collect(Collectors.toSet());
        List<Long> deleteIdList = currOrgProductInitialPurchaseList.stream()
                .map(PurchaseRecordDO::getId)
                .filter(id -> !inputPurchaseIds.contains(id))
                .toList();

        // 6、修改
        for (OrganCreateProductPurchaseReqVO purchaseReqVO : updateList) {
            // 购买记录id
            Long purchaseId = purchaseReqVO.getPurchaseId();
            // 订购价格
            BigDecimal price = purchaseReqVO.getPrice();

            // 2、更新购买记录的订购价格
            purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
                    .eq(PurchaseRecordDO::getId, purchaseId)
                    .eq(PurchaseRecordDO::getOrganId, organId)
                    .eq(PurchaseRecordDO::getInitial, true)
                    .set(PurchaseRecordDO::getTotalAmount, price)
                    .set(PurchaseRecordDO::getMonthAverageAmount, price.divide(new BigDecimal(10), 2, RoundingMode.DOWN))
                    .set(PurchaseRecordDO::getOriginalAmount, price));
        }

        // 7、删除首购记录关联的延期记录如果有已经支付的不允许删除
        for (Long purchaseId : deleteIdList) {
            List<ProductDelayRespVO> recordsByPurchaseId = productDelayService.getRecordsByPurchaseId(purchaseId, organId);
            if (CollUtil.isNotEmpty(recordsByPurchaseId)) {
                Optional<ProductDelayRespVO> anyPaid = recordsByPurchaseId.stream().filter(ProductDelayRespVO::getPaid).findAny();
                if (anyPaid.isPresent()) {
                    throw new ServiceException(ORG_PRODUCT_PURCHASE_DELAY_RECORD_PAID_ERROR);
                }
                productDelayService.deleteProductDelayRecords(recordsByPurchaseId.stream().map(ProductDelayRespVO::getId).toList(), organId);
            }
        }

        // 8、删除
        if (CollUtil.isNotEmpty(deleteIdList)) {
            purchaseRecordMapper.physicalDeleteByIds(deleteIdList, organId);
        }

        // 9、新增
        createOrgInitProductPurchaseRecord(organId, createList);

    }

    @Override
    public List<PurchaseRecordDO> getOrgPurchaseList(Set<Long> organIds) {
        return purchaseRecordMapper.selectList(new LambdaQueryWrapper<PurchaseRecordDO>()
                .in(PurchaseRecordDO::getOrganId, organIds)
                .eq(PurchaseRecordDO::getDeleted, false)
                .orderByDesc(PurchaseRecordDO::getCreateTime));
    }

    @Override
    public TotalSalesAmountRespVO getTotalSales() {
        return purchaseRecordMapper.getTotalSales();
    }

    @Override
    public PageResult<SalesDetailRespVO> getManageSalesDetailsPage(SalesDetailsPageReqVO reqVO) {
        // 时间类型规范为开始0点，结束12点
        reqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(reqVO.getCreateTime()));

        // 分页查询
        PageResult<PurchaseRecordDO> salesDetailPage = purchaseRecordMapper.getSaleDetailsPage(reqVO);

        // 构建回调数据
        List<SalesDetailRespVO> resultList = new ArrayList<>();
        for (PurchaseRecordDO detailDO : salesDetailPage.getList()) {
            SalesDetailRespVO respVO = BeanUtils.toBean(detailDO, SalesDetailRespVO.class);
            // 销售目前都是产品购买
            respVO.setTradeType(TradeTypeEnum.PRODUCT.getCode());
            // 充值支付=支付宝/微信
            respVO.setRechargeSpent(detailDO.getExternalSpent());
            // 支付方式
            respVO.setPaymentMethod(i18nUtils.getMessage(PayChannelCodeEnum.describe(detailDO.getPaymentMethod())));
            // 查询组织名称
            OrganizationDO organ = organService.getOrganWithDeleted(detailDO.getOrganId());
            if (ObjectUtil.isNotNull(organ)) {
                respVO.setOrganName(organ.getName());
            }
            resultList.add(respVO);
        }
        return new PageResult<>(resultList, salesDetailPage.getTotal());
    }

    @Override
    public PurchaseRecordDO getOrgInitialPurchaseRecord(Long organId, Long productId) {
        return purchaseRecordMapper.selectOne(new LambdaQueryWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getOrganId, organId)
                .eq(PurchaseRecordDO::getProductId, productId)
                .eq(PurchaseRecordDO::getInitial, true));
    }

    @Override
    public List<PurchaseRecordDO> getOrgProductPendingPurchaseList(Long organId, Long productId) {
        return purchaseRecordMapper.selectList(new LambdaQueryWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getOrganId, organId)
                .eq(PurchaseRecordDO::getProductId, productId)
                .eq(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.PENDING.getStatus())
                .eq(PurchaseRecordDO::getDeleted, false));
    }

    @Override
    public List<ProductDetailsRespVO> getOrgProductDetailList(Long organId, Long productId) {
        // 校验产品
        ProductsDO productsDO = productsDetailService.validateProductExist(productId);

        // 查询产品下的所有定价规则
        ProductDetailsPageReqVO pageReqVO = new ProductDetailsPageReqVO();
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setProductId(productId);
        PageResult<ProductsDetailDO> page = productsDetailService.getPage(pageReqVO);

        // 查询可用的产品对应优惠活动
        List<ProductPromotionDO> availableProductPromotionList = productPromotionService.getAvailableProductPromotionList(productId);

        // 查询组织下的首次订购产品记录
        PurchaseRecordDO orgInitialPurchaseRecord = getOrgInitialPurchaseRecord(organId, productId);
        if (ObjectUtil.isNull(orgInitialPurchaseRecord)) {
            return getInitialProductDetailList(productsDO, page.getList(), availableProductPromotionList);
        }

        List<ProductDetailsRespVO> resultList = new ArrayList<>();

        // 月均单价
        BigDecimal monthAverageAmount = orgInitialPurchaseRecord.getMonthAverageAmount();
        // 1年定价
        BigDecimal totalAmount = orgInitialPurchaseRecord.getTotalAmount();
        // 定价中有的，以年数量*组织定价*折扣展示
        List<ProductDetailsRespVO> productDetailRespVOList = new ArrayList<>();
        for (ProductsDetailDO detailDO : page.getList()) {
            ProductDetailsRespVO newDetailRespVO = BeanUtils.toBean(detailDO, ProductDetailsRespVO.class);
            // 折扣
            BigDecimal discount = detailDO.getDiscount();

            Integer durationUnit = detailDO.getDurationUnit();

            // 重新计算购买价格
            switch (ProductDurationUnitEnum.fromStatus(durationUnit)) {
                case YEAR -> {
                    Integer duration = detailDO.getDuration();
                    // 原价
                    BigDecimal originalPrice = totalAmount.multiply(BigDecimal.valueOf(duration));
                    newDetailRespVO.setOriginalPrice(originalPrice);
                    // 折扣价格
                    newDetailRespVO.setCurrentPrice(originalPrice.multiply(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
                    // 补充优惠活动赠送时长
                    fillGiftDurationFromPromotion(duration, durationUnit, newDetailRespVO, availableProductPromotionList);
                    productDetailRespVOList.add(newDetailRespVO);
                }
                default -> {
                }
            }
        }
        // 没有定价年的规则，自动补充一个1年的
        if (CollUtil.isEmpty(productDetailRespVOList)) {
            ProductDetailsRespVO oneYearRespVO = new ProductDetailsRespVO();
            oneYearRespVO.setProductId(productId);
            oneYearRespVO.setDuration(1);
            oneYearRespVO.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
            oneYearRespVO.setCurrentPrice(productsDO.getPrice());
            oneYearRespVO.setOriginalPrice(productsDO.getPrice());
            // 补充优惠活动赠送时长
            fillGiftDurationFromPromotion(1, ProductDurationUnitEnum.YEAR.getCode(), oneYearRespVO, availableProductPromotionList);
            productDetailRespVOList.add(oneYearRespVO);
        }
        // 默认展示1到10月的价格
        for (int i = 1; i <= 10; i++) {
            ProductDetailsRespVO detailRespVO = new ProductDetailsRespVO();
            detailRespVO.setId(Long.parseLong(String.format(PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT, i)));
            detailRespVO.setProductId(productId);
            detailRespVO.setDuration(i);
            detailRespVO.setDurationUnit(ProductDurationUnitEnum.MONTH.getCode());
            // 价格：月均单价*月数量
            BigDecimal price = monthAverageAmount.multiply(BigDecimal.valueOf(i));
            // 有一年的折扣要把月价格做折算
            detailRespVO.setCurrentPrice(price);
            detailRespVO.setOriginalPrice(price);
            resultList.add(detailRespVO);
        }
        resultList.addAll(productDetailRespVOList);

        return resultList;
    }

    /**
     * 拼接没有首次购买记录的定价方式列表
     *
     * @param productsDO
     * @param productsDetailDOS
     * @param availableProductPromotionList
     * @return
     */
    private List<ProductDetailsRespVO> getInitialProductDetailList(ProductsDO productsDO, List<ProductsDetailDO> productsDetailDOS, List<ProductPromotionDO> availableProductPromotionList) {
        List<ProductDetailsRespVO> resultList = new ArrayList<>();
        // 没有首次购买记录的产品，展示的总价是产品建议价格
        // 1年定价
        BigDecimal totalAmount = productsDO.getPrice();
        if (ObjectUtil.isNull(totalAmount)) {
            throw new ServiceException(PRODUCT_PRICE_NULL_ERROR);
        }
        // 月均单价
        BigDecimal monthAverageAmount = totalAmount.divide(new BigDecimal(10), 2, RoundingMode.DOWN);

        List<ProductDetailsRespVO> productDetailRespVOList = new ArrayList<>();
        for (ProductsDetailDO detailDO : productsDetailDOS) {
            ProductDetailsRespVO newDetailRespVO = BeanUtils.toBean(detailDO, ProductDetailsRespVO.class);
            // 折扣
            BigDecimal discount = detailDO.getDiscount();

            Integer durationUnit = detailDO.getDurationUnit();

            // 重新计算购买价格
            switch (ProductDurationUnitEnum.fromStatus(durationUnit)) {
                case YEAR -> {
                    Integer duration = detailDO.getDuration();
                    // 原价
                    BigDecimal originalPrice = totalAmount.multiply(BigDecimal.valueOf(duration));
                    newDetailRespVO.setOriginalPrice(originalPrice);
                    // 折扣价格
                    newDetailRespVO.setCurrentPrice(originalPrice.multiply(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
                    // 补充优惠活动赠送时长
                    fillGiftDurationFromPromotion(duration, durationUnit, newDetailRespVO, availableProductPromotionList);
                    productDetailRespVOList.add(newDetailRespVO);
                }
                default -> {
                }
            }
        }
        // 没有定价年的规则，自动补充一个1年的
        if (CollUtil.isEmpty(productDetailRespVOList)) {
            ProductDetailsRespVO oneYearRespVO = new ProductDetailsRespVO();
            oneYearRespVO.setId(Long.parseLong(String.format(PAY_PRODUCT_DETAIL_AUTO_GENERATE_YEAR_ID_FORMAT, 1)));
            oneYearRespVO.setProductId(productsDO.getId());
            oneYearRespVO.setDuration(1);
            oneYearRespVO.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
            oneYearRespVO.setCurrentPrice(productsDO.getPrice());
            oneYearRespVO.setOriginalPrice(productsDO.getPrice());
            // 补充优惠活动赠送时长
            fillGiftDurationFromPromotion(1, ProductDurationUnitEnum.YEAR.getCode(), oneYearRespVO, availableProductPromotionList);
            productDetailRespVOList.add(oneYearRespVO);
        }

        // 默认展示1到10月的价格
        for (int i = 1; i <= 10; i++) {
            ProductDetailsRespVO detailRespVO = new ProductDetailsRespVO();
            detailRespVO.setId(Long.parseLong(String.format(PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT, i)));
            detailRespVO.setProductId(productsDO.getId());
            detailRespVO.setDuration(i);
            detailRespVO.setDurationUnit(ProductDurationUnitEnum.MONTH.getCode());
            // 价格：月均单价*月数量
            BigDecimal price = monthAverageAmount.multiply(BigDecimal.valueOf(i));
            // 有一年的折扣要把月价格做折算
            detailRespVO.setCurrentPrice(price);
            detailRespVO.setOriginalPrice(price);
            resultList.add(detailRespVO);
        }
        resultList.addAll(productDetailRespVOList);
        return resultList;
    }

    /**
     * 填充优惠活动的赠送时间
     *
     * @param duration
     * @param durationUnit
     * @param productDetailsRespVO
     * @param availableProductPromotionList
     * @return
     */
    private ProductDetailsRespVO fillGiftDurationFromPromotion(Integer duration, Integer durationUnit, ProductDetailsRespVO productDetailsRespVO, List<ProductPromotionDO> availableProductPromotionList) {
        // 补充优惠活动的赠送时间
        Optional<ProductPromotionDO> promotionOpt = availableProductPromotionList.stream().filter(p -> p.getPurchaseDuration().equals(duration) && p.getPurchaseDurationUnit().equals(durationUnit)).findFirst();
        if (promotionOpt.isPresent()) {
            ProductPromotionDO productPromotionDO = promotionOpt.get();
            productDetailsRespVO.setGiftDuration(productPromotionDO.getGiftDuration());
            productDetailsRespVO.setGiftDurationUnit(productPromotionDO.getGiftDurationUnit());
        }
        return productDetailsRespVO;
    }

    @Override
    public void invalidHistoryOrganProductPurchaseRecord(Long organId, Long purchaseRecordId) {
        purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getOrganId, organId)
                .eq(PurchaseRecordDO::getId, purchaseRecordId)
                .in(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.ACTIVE.getStatus(), PurchaseRecordStatusEnum.PENDING.getStatus())
                .eq(PurchaseRecordDO::getDeleted, false)
                .set(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.INACTIVE.getStatus()));
    }

    @Override
    public void activateHistoryOrganProductPurchaseRecord(Long organId, Long purchaseRecordId) {
        purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
                .eq(PurchaseRecordDO::getOrganId, organId)
                .eq(PurchaseRecordDO::getId, purchaseRecordId)
                .eq(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.PENDING.getStatus())
                .eq(PurchaseRecordDO::getDeleted, false)
                .set(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.ACTIVE.getStatus()));
    }

    @Override
    public ManageSalesTotalStatisticRespVO getSalesTotalStatistics() {
        ManageSalesTotalStatisticRespVO respVO = new ManageSalesTotalStatisticRespVO();
        respVO.setSalesTotal(purchaseRecordMapper.getTotalSales().getAmount());
        respVO.setSalesToday(purchaseRecordMapper.getTodaySales(LocalDateTime.now().plusDays(1)));
        return respVO;
    }
}
