package com.liquidnet.service.candy.service.impl;

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.candy.dto.CandyCouponCodeDto;
import com.liquidnet.service.candy.dto.CandyCouponInfoDto;
import com.liquidnet.service.candy.dto.CandyUserCouponBasicDto;
import com.liquidnet.service.candy.entity.CandyCoupon;
import com.liquidnet.service.candy.mapper.CandyCouponMapper;
import com.liquidnet.service.candy.service.ICandyCouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.service.candy.util.CouponBaseUtil;
import com.liquidnet.service.candy.util.ObjectUtil;
import com.liquidnet.service.candy.util.QueueUtils;
import com.liquidnet.service.candy.util.RedisDataUtils;
import com.liquidnet.service.candy.vo.CandyCouponVo;
import com.liquidnet.service.candy.vo.CandyMyCouponListVo;
import com.liquidnet.service.candy.vo.CandyUseResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 券基础信息 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-08-18
 */
@Service
public class CandyCouponServiceImpl extends ServiceImpl<CandyCouponMapper, CandyCoupon> implements ICandyCouponService {

    @Autowired
    private RedisDataUtils redisDataUtils;
    @Autowired
    private QueueUtils queueUtils;

    @Override
    public CandyMyCouponListVo myCoupon() {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = redisDataUtils.getCouponByUid(uid);
        CandyMyCouponListVo vo = CandyMyCouponListVo.getNew();
        List<CandyCouponVo> memberCoupon = ObjectUtil.getCandyCouponVoArrayList();
        List<CandyCouponVo> myCoupon = ObjectUtil.getCandyCouponVoArrayList();

        for (CandyUserCouponBasicDto dtoItem : dtoList) {
            CandyCouponVo baseVo = CouponBaseUtil.getBaseCouponUserVo(dtoItem);
            if (dtoItem.getExclusive().equals(1)) { //会员券
                memberCoupon.add(baseVo);
            } else {//非会员券
                myCoupon.add(baseVo);
            }
        }
        //排序
        memberCoupon.sort(Comparator.comparing(CandyCouponVo::getState));
        myCoupon.sort(Comparator.comparing(CandyCouponVo::getState));
        vo.setMemberCoupon(memberCoupon);
        vo.setMyCoupon(myCoupon);
        return vo;
    }

    @Override
    public CandyMyCouponListVo preUsePerformanceCoupon(BigDecimal priceTotal, String performanceId, String timeId, String ticketId) {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = redisDataUtils.getCouponByUid(uid);
        CandyMyCouponListVo vo = CandyMyCouponListVo.getNew();
        List<CandyCouponVo> memberCoupon = ObjectUtil.getCandyCouponVoArrayList();
        List<CandyCouponVo> myCoupon = ObjectUtil.getCandyCouponVoArrayList();

        for (CandyUserCouponBasicDto dtoItem : dtoList) {
            CandyCouponVo baseVo = CouponBaseUtil.getPerformanceCouponUserVo(dtoItem, priceTotal, performanceId, timeId, ticketId);
            if (dtoItem.getExclusive().equals(1)) { //会员券
                memberCoupon.add(baseVo);
            } else {//非会员券
                myCoupon.add(baseVo);
            }
        }

        //排序
        memberCoupon.sort(Comparator.comparing(CandyCouponVo::getState));
        myCoupon.sort(Comparator.comparing(CandyCouponVo::getState));
        vo.setMemberCoupon(memberCoupon);
        vo.setMyCoupon(myCoupon);
        return vo;
    }

    @Override
    public Integer preCanUsePerformanceCoupon(BigDecimal priceTotal, String performanceId, String timeId, String ticketId) {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = redisDataUtils.getCouponByUid(uid);
        int canUse = 0;
        for (CandyUserCouponBasicDto dtoItem : dtoList) {
            CandyCouponVo baseVo = CouponBaseUtil.getPerformanceCouponUserVo(dtoItem, priceTotal, performanceId, timeId, ticketId);
            if (baseVo.getState().equals(1)) { //可用
                canUse = 1;
                break;
            } else {//不可用
                continue;
            }
        }
        return canUse;
    }

    @Override
    public CandyMyCouponListVo preUseGoodCoupon(BigDecimal priceTotal, String goodId, String produceId) {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = redisDataUtils.getCouponByUid(uid);
        CandyMyCouponListVo vo = CandyMyCouponListVo.getNew();
        List<CandyCouponVo> memberCoupon = ObjectUtil.getCandyCouponVoArrayList();
        List<CandyCouponVo> myCoupon = ObjectUtil.getCandyCouponVoArrayList();

        for (CandyUserCouponBasicDto dtoItem : dtoList) {
            CandyCouponVo baseVo = CouponBaseUtil.getGoodCouponUserVo(dtoItem, priceTotal, goodId, produceId);
            if (dtoItem.getExclusive().equals(1)) { //会员券
                memberCoupon.add(baseVo);
            } else {//非会员券
                myCoupon.add(baseVo);
            }
        }

        //排序
        memberCoupon.sort(Comparator.comparing(CandyCouponVo::getState));
        myCoupon.sort(Comparator.comparing(CandyCouponVo::getState));
        vo.setMemberCoupon(memberCoupon);
        vo.setMyCoupon(myCoupon);
        return vo;
    }

    @Override
    public Integer preCanUseGoodCoupon(BigDecimal priceTotal, String goodId, String produceId) {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = redisDataUtils.getCouponByUid(uid);
        int canUse = 0;
        for (CandyUserCouponBasicDto dtoItem : dtoList) {
            CandyCouponVo baseVo = CouponBaseUtil.getGoodCouponUserVo(dtoItem, priceTotal, goodId, produceId);
            if (baseVo.getState().equals(1)) { //可用
                canUse = 1;
                break;
            } else {//不可用
                continue;
            }
        }
        return canUse;
    }

    @Override
    public List<CandyCouponVo> myAdvanceCoupon() {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = redisDataUtils.getCouponByUid(uid);
        List<CandyCouponVo> advanceCoupon = ObjectUtil.getCandyCouponVoArrayList();
        for (CandyUserCouponBasicDto dtoItem : dtoList) {
            if (dtoItem.getBusiType().equals(3)) {
                CandyCouponVo baseVo = CouponBaseUtil.getBaseCouponUserVo(dtoItem);
                if (baseVo.getState().equals(1)) {
                    advanceCoupon.add(baseVo);
                } else {
                    continue;
                }
            } else {
                continue;
            }
        }
        return advanceCoupon;
    }

    @Override
    public Integer stateCoupon(String uCouponId) {
        String uid = CurrentUtil.getCurrentUid();
        CandyUserCouponBasicDto dto = CouponBaseUtil.getSingleDtoByUCouponId(redisDataUtils.getCouponByUid(uid), uCouponId);
        if (dto == null) {
            return null;//券不存在
        }
        return CouponBaseUtil.getCouponState(LocalDateTime.now(), dto.getExpireAt(), dto.getState());
    }

    @Override
    public CandyUseResultVo useCoupon(String uCouponId, String content,String totalPrice) {
        String uid = CurrentUtil.getCurrentUid();
        CandyUseResultVo vo = CandyUseResultVo.getNew();
        List<CandyUserCouponBasicDto> dtoList = CouponBaseUtil.useCoupon(redisDataUtils.getCouponByUid(uid), uCouponId, content);
        if (dtoList == null) {
            vo.setCouType(-1);
            vo.setValue(BigDecimal.ZERO);
        } else {
            CandyUserCouponBasicDto dto = CouponBaseUtil.getSingleDtoByUCouponId(redisDataUtils.getCouponByUid(uid), uCouponId);
            vo.setCouType(dto.getCouType());
            switch (dto.getCouType()) {//券类型[1-代金券｜2-满减券｜3-兑换券｜4-折扣券]
                case 1:
                    vo.setValue(dto.getValFace());
                    break;
                case 2:
                    if(dto.getValOver().compareTo(new BigDecimal(totalPrice))>=0) {
                        vo.setValue(dto.getValMinus());
                    }else{
                        vo.setCouType(-1);
                        vo.setValue(BigDecimal.ZERO);
                    }
                    break;
                case 3:
                    vo.setValue(BigDecimal.valueOf(-1));
                    break;
                case 4:
                    vo.setValue(dto.getDiscount());
                    break;
                default:
                    vo.setValue(BigDecimal.valueOf(0));
                    break;
            }
            if(vo.getCouType()!=-1) {
                redisDataUtils.setCouponByUid(uid, dtoList);
                //入库
                queueUtils.sendMsgByRedis(
                        MQConst.CandyQueue.COUPON_USE.getKey(),
                        SqlMapping.get("candy_coupon.use",
                                uid, uCouponId
                        )
                );
            }
        }
        return vo;
    }

    @Override
    public Boolean useBackCoupon(String uCouponId) {
        String uid = CurrentUtil.getCurrentUid();
        List<CandyUserCouponBasicDto> dtoList = CouponBaseUtil.backCoupon(redisDataUtils.getCouponByUid(uid), uCouponId);
        if (dtoList == null) {
            return false;
        } else {
            redisDataUtils.setCouponByUid(uid, dtoList);
            //入库
            queueUtils.sendMsgByRedis(
                    MQConst.CandyQueue.COUPON_BACK.getKey(),
                    SqlMapping.get("candy_coupon.back",
                            uid,uCouponId
                    )
            );
        }
        return true;
    }

    @Override
    public Boolean receiveCoupon(String ccode) {
        String uid = CurrentUtil.getCurrentUid();
        CandyCouponCodeDto dto = redisDataUtils.getCouponByCode(ccode);
        if (dto.getState().equals(0)) {//判断可领
            CandyCouponInfoDto infoDto = redisDataUtils.getCouponInfo(dto.getCouponId());
            String uCouponId = IDGenerator.get32UUID();
            //构建baseDto
            CandyUserCouponBasicDto baseDto = CandyUserCouponBasicDto.getNew().copyToRedisBaseCoupon(uCouponId, uid, ccode, infoDto);
            //删除code redis
            redisDataUtils.delCouponByCode(ccode);
            //添加baseDto -> baseDtoList
            redisDataUtils.addCouponByUid(uid, baseDto);
            //入库
            queueUtils.sendMsgByRedis(
                    MQConst.CandyQueue.COUPON_RECEIVE.getKey(),
                    SqlMapping.get("candy_coupon.receive",
                            uCouponId, uid, 1, infoDto.getCouponId(), ccode, LocalDateTime.now()
                    )
            );
        } else {
            return false;
        }
        return true;
    }
}
