package com.qs.mp.admin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.admin.domain.Coupon;
import com.qs.mp.admin.domain.CouponTicket;
import com.qs.mp.admin.domain.Goods;
import com.qs.mp.admin.domain.GoodsSku;
import com.qs.mp.admin.domain.Ticket;
import com.qs.mp.admin.mapper.CouponMapper;
import com.qs.mp.admin.service.ICouponService;
import com.qs.mp.admin.service.ICouponTicketService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.common.enums.CouponUseAreaEnum;
import com.qs.mp.common.enums.UserCouponStatusEnum;
import com.qs.mp.common.exception.ServiceException;
import com.qs.mp.common.utils.DateUtils;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.system.service.id.BizIdGenerator;
import com.qs.mp.user.domain.UserCoupon;
import com.qs.mp.user.domain.UserCouponChannel;
import com.qs.mp.user.domain.UserTicketOrder;
import com.qs.mp.user.domain.UserTicketOrderItem;
import com.qs.mp.user.service.IUserCouponChannelService;
import com.qs.mp.user.service.IUserCouponService;
import com.qs.mp.user.service.IUserTicketOrderItemService;

import com.qs.mp.user.service.IUserTicketOrderService;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 优惠券 服务实现类
 * </p>
 *
 * @author quanshu
 * @since 2022-03-07
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ICouponService couponService;

    @Autowired
    private IUserCouponService userCouponService;

    @Autowired
    private IUserCouponChannelService userCouponChannelService;

    @Autowired
    private ICouponTicketService couponTicketService;

    @Autowired
    private BizIdGenerator bizIdGenerator;

    @Autowired
    private IUserTicketOrderItemService userTicketOrderItemService;

    @Autowired
    private IUserTicketOrderService userTicketOrderService;

    @Autowired
    private IChannelService channelService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void distributeByMarketing(Long userId, String couponId) {
        Coupon coupon = getById(couponId);
        UserCoupon userCoupon = getUserCoupon(userId, coupon);
        userCoupon.setUseAreaDesc(coupon.getUseArea().getDesc());
        userCouponService.save(userCoupon);
        boolean rtn = update(new LambdaUpdateWrapper<Coupon>().set(Coupon::getDistributeQty, coupon.getDistributeQty() + 1)
                .eq(Coupon::getCouponId, coupon.getCouponId()).eq(Coupon::getDistributeQty, coupon.getDistributeQty()));
        Assert.isTrue(rtn, "发放优惠券奖品，更新优惠券发放量失败。couponId:" + coupon.getCouponId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void distribute(Ticket ticket, Long userId, String couponId) {
        Coupon coupon = getById(couponId);
        UserCoupon userCoupon = getUserCoupon(userId, coupon);


        // 确定限定范围
        if (coupon.getUseArea() == CouponUseAreaEnum.POST_SCOPE) {
            UserTicketOrderItem orderItem = userTicketOrderItemService.queryFinishedOrderItem(userId, ticket.getTicketId());
            UserTicketOrder ticketOrder = userTicketOrderService.getById(orderItem.getOrderId());
            if (null == orderItem || null == ticketOrder.getChannelId()) {
                LogUtil.error(logger, "优惠券的限定使用范围类型为发放时生成，但找不到关联的渠道ID。orderItem:{0}", new Object[]{
                        JSONObject.toJSONString(orderItem)});
                throw new ServiceException("优惠券发放失败");
            }
            UserCouponChannel userCouponChannel = new UserCouponChannel();
            userCouponChannel.setUserCouponId(userCoupon.getId());
            userCouponChannel.setChannelId(ticketOrder.getChannelId());
            userCouponChannelService.save(userCouponChannel);
            Channel channel = channelService.getById(ticketOrder.getChannelId());
            userCoupon.setUseAreaDesc(channel.getSiteName());
        } else {
            userCoupon.setUseAreaDesc(coupon.getUseArea().getDesc());
        }
        userCouponService.save(userCoupon);

        boolean rtn = update(new LambdaUpdateWrapper<Coupon>().set(Coupon::getDistributeQty, coupon.getDistributeQty() + 1)
                .eq(Coupon::getCouponId, coupon.getCouponId()).eq(Coupon::getDistributeQty, coupon.getDistributeQty()));
        Assert.isTrue(rtn, "领取优惠券奖品，更新优惠券发放量失败。couponId:" + coupon.getCouponId());
    }

    private UserCoupon getUserCoupon(Long userId, Coupon coupon) {
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.setId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
        userCoupon.setUserId(userId);
        userCoupon.setVerifyCode(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
        userCoupon.setCouponId(coupon.getCouponId());
        if (coupon.getDueDays() > 0) {
            userCoupon.setValidStart(DateUtils.getToday());
            userCoupon.setValidEnd(DateUtils.addDays(userCoupon.getValidStart(), coupon.getDueDays() - 1));
        } else {
            userCoupon.setValidStart(coupon.getValidStart());
            userCoupon.setValidEnd(coupon.getValidEnd());
        }
        userCoupon.setStatus(UserCouponStatusEnum.UNUSED);
        return userCoupon;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCoupon(Coupon coupon, List<CouponTicket> ticketList) {
        boolean res = couponService.save(coupon);
        if (!res) {
            throw new ServiceException("请联系管理员");
        }
        if (res && null != ticketList
                && ticketList.size() > 0) {
            for (CouponTicket couponTicket : ticketList) {
                if (null != couponTicket) {
                    couponTicket.setCouponId(coupon.getCouponId());
                }
            }
            boolean skuRes = couponTicketService.saveBatch(ticketList);
            if (!skuRes) {
                throw new ServiceException("请联系管理员");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCoupon(Coupon coupon, List<CouponTicket> ticketList) {
        boolean res = couponService.updateById(coupon);
        if (!res) {
            throw new ServiceException("请联系管理员");
        }
        // 多SKU
        if (res && null != ticketList
                && ticketList.size() > 0) {
            for (CouponTicket couponTicket : ticketList) {
                if (null != couponTicket) {
                    couponTicket.setCouponId(couponTicket.getCouponId());
                }
            }

            LambdaQueryWrapper<CouponTicket> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(CouponTicket::getCouponId, coupon.getCouponId());
            boolean delRes = couponTicketService.remove(queryWrapper);
            if (delRes) {
                boolean skuRes = couponTicketService.saveBatch(ticketList);
                if (!skuRes) {
                    throw new ServiceException("请联系管理员");
                }
            } else {
                throw new ServiceException("请联系管理员");
            }

        }
    }
}
