package com.czg.service.market.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.czg.constant.MarketConstants;
import com.czg.exception.CzgException;
import com.czg.market.dto.MkCouponGiftDTO;
import com.czg.market.dto.MkShopConsumerCouponDTO;
import com.czg.market.dto.MkShopCouponGiftDTO;
import com.czg.market.entity.MkShopConsumerCoupon;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.service.MkCouponGiftService;
import com.czg.market.service.MkShopConsumerCouponService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.service.market.mapper.MkShopConsumerCouponMapper;
import com.czg.utils.AssertUtil;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 消费赠券表 服务层实现。
 *
 * @author ww
 * @since 2025-09-12
 */
@Slf4j
@Service
public class MkShopConsumerCouponServiceImpl extends ServiceImpl<MkShopConsumerCouponMapper, MkShopConsumerCoupon> implements MkShopConsumerCouponService {

    @Resource
    private MkCouponGiftService couponGiftService;
    @Resource
    private MkShopCouponRecordService recordService;

    @Override
    public Page<MkShopConsumerCouponDTO> getConsumerCouponPage(MkShopConsumerCouponDTO param) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(MkShopConsumerCoupon::getShopId, param.getShopId())
                .eq(MkShopConsumerCoupon::getId, param.getId())
                .orderBy(MkShopConsumerCoupon::getCreateTime).desc();
        Page<MkShopConsumerCouponDTO> pages = pageAs(PageUtil.buildPage(), queryWrapper, MkShopConsumerCouponDTO.class);
        pages.getRecords().forEach(item -> {
            //填充优惠券信息/数量
            item.setCouponGiftList(couponGiftService.getCouponGiftBySourceId(item.getId(), 3));
        });
        return pages;
    }

    @Override
    @Transactional
    public void receiveConsumerCoupon(Long shopId, Long orderId, BigDecimal orderAmount, Long userId, Long shopUserId) {
        MkShopConsumerCoupon consumerCoupon = this.getOne(new QueryWrapper()
                .eq(MkShopConsumerCoupon::getShopId, shopId)
                .eq(MkShopConsumerCoupon::getStatus, 1)
                .le(MkShopConsumerCoupon::getFullAmount, orderAmount)
                .orderBy(MkShopConsumerCoupon::getFullAmount).desc()
                .orderBy(MkShopConsumerCoupon::getCreateTime).desc());
        if (consumerCoupon == null) {
            return;
        }
        //判断是否已被领取
        if (consumerCoupon.getGiveNum() != MarketConstants.Num.NOT_LIMIT && consumerCoupon.getGiveNum() <= consumerCoupon.getGiftNum()) {
            return;
        }
        List<MkCouponGiftDTO> giftCoupons = couponGiftService.getCouponGiftBySourceId(consumerCoupon.getId(), 3);
        if (CollUtil.isEmpty(giftCoupons)) {
            return;
        }
        MkCouponGiftDTO giftCoupon = giftCoupons.getFirst();
        if (consumerCoupon.getLeftNum() == MarketConstants.Num.NOT_LIMIT || consumerCoupon.getLeftNum() >= giftCoupon.getNum()) {
            boolean canReceive = consumerCoupon.getGetLimit() == MarketConstants.Num.NOT_LIMIT;
            // 限量发放，校验用户已经发放数量
            if (consumerCoupon.getGetLimit() != MarketConstants.Num.NOT_LIMIT) {
                long count = recordService.count(new QueryWrapper().eq(MkShopCouponRecord::getShopId, shopId)
                        .eq(MkShopCouponRecord::getShopUserId, shopUserId)
                        .eq(MkShopCouponRecord::getSourceId, consumerCoupon.getId()));
                log.info("用户: {}, 已经发放: {}, 限量: {}", shopUserId, count, consumerCoupon.getGetLimit());
                canReceive = consumerCoupon.getGetLimit() >= count + giftCoupon.getNum();
            }

            if (canReceive) {
                MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO();
                giftDTO.setShopId(shopId);
                giftDTO.setShopUserId(shopUserId);
                giftDTO.setCouponId(giftCoupon.getCouponId());
                giftDTO.setSourceId(consumerCoupon.getId());
                giftDTO.setSourceFlowId(orderId);
                giftDTO.setSource("消费赠券");
                //发放券
                recordService.receiveCoupon(giftDTO, giftCoupon.getNum(), false);
                //更新优惠券信息
                consumerCoupon.setGiftNum(consumerCoupon.getGiftNum() + giftCoupon.getNum());
                if (consumerCoupon.getLeftNum() != MarketConstants.Num.NOT_LIMIT) {
                    consumerCoupon.setLeftNum(consumerCoupon.getLeftNum() - giftCoupon.getNum());
                }
                updateById(new MkShopConsumerCoupon()
                        .setId(consumerCoupon.getId())
                        .setLeftNum(consumerCoupon.getLeftNum())
                        .setGiftNum(consumerCoupon.getGiftNum()));
            }
        }
    }

    @Override
    public void removeConsumerCoupon(Long shopId, Long userId, Long orderId) {
        recordService.remove(query()
                .eq(MkShopCouponRecord::getShopId, shopId)
                .eq(MkShopCouponRecord::getUserId, userId)
                .eq(MkShopCouponRecord::getSourceFlowId, orderId)
                .eq(MkShopCouponRecord::getSource, "消费赠券")
        );
    }


    @Override
    public MkShopConsumerCouponDTO getConsumerCouponById(Long id) {
        AssertUtil.isNull(id, "ID不能为空");
        MkShopConsumerCouponDTO data = getOneAs(new QueryWrapper().eq(MkShopConsumerCoupon::getId, id), MkShopConsumerCouponDTO.class);
        //填充优惠券信息/数量
        data.setCouponGiftList(couponGiftService.getCouponGiftBySourceId(data.getId(), 3));
        return data;
    }

    @Override
    @Transactional
    public void addConsumerCoupon(MkShopConsumerCouponDTO param) {
        if (CollUtil.isEmpty(param.getCouponGiftList())) {
            throw new CzgException("优惠券信息不能为空");
        }
        MkShopConsumerCoupon bean = BeanUtil.toBean(param, MkShopConsumerCoupon.class);
        save(bean);
        //新增优惠券信息/数量
        couponGiftService.addCouponGift(bean.getId(), "消费赠券", 3, param.getCouponGiftList());
    }

    @Override
    @Transactional
    public void updateConsumerCouponById(MkShopConsumerCouponDTO param) {
        MkShopConsumerCoupon consumerCoupon = getById(param.getId());
        if (param.getGiveNum() == MarketConstants.Num.NOT_LIMIT) {
            param.setLeftNum(MarketConstants.Num.NOT_LIMIT);
        } else {
            if (param.getGiveNum() < consumerCoupon.getGiftNum()) {
                throw new CzgException("修改失败 总发放数量必须大于已发放数量");
            } else {
                param.setLeftNum(param.getGiveNum() - consumerCoupon.getGiftNum());
            }
        }
        updateById(BeanUtil.toBean(param, MkShopConsumerCoupon.class), true);
        //更新优惠券信息/数量
        couponGiftService.addCouponGift(param.getId(), "消费赠券", 3, param.getCouponGiftList());
    }

    @Override
    @Transactional
    public void deleteConsumerCoupon(Long id) {
        AssertUtil.isNull(id, "优惠券ID不能为空");
        removeById(id);
        //删除优惠券信息
        couponGiftService.deleteJoinCouponGift(id, 3);
    }
}
