package com.kmall.api.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.kmall.api.dto.UserCouponDto;
import com.kmall.api.entity.CartVo;
import com.kmall.api.entity.CouponVo;
import com.kmall.api.entity.UserVo;
import com.kmall.api.entity.mk.MkStoreTicketDiscountVo;
import com.kmall.api.service.mk.ApiMkStoreTicketDiscountService;
import com.kmall.api.service.mk.ApiMkStoreTopicStatService;
import com.kmall.common.constant.Dict;
import com.kmall.api.dao.ApiUserCouponMapper;
import com.kmall.api.entity.UserCouponVo;
import com.kmall.common.utils.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Service
public class ApiUserCouponService {
    private Log logger = LogFactory.getLog(ApiUserCouponService.class);
    @Autowired
    private ApiUserCouponMapper userCouponDao;
    @Autowired
    private ApiMkStoreTicketDiscountService mkStoreTicketDiscountService;
    @Autowired
    private ApiMkStoreTopicStatService apiMkStoreTopicStatService;


    public UserCouponVo queryObject(Integer id) {
        return userCouponDao.queryObject(id);
    }

    public List<UserCouponVo> queryList(Map<String, Object> map) {
        return userCouponDao.queryList(map);
    }


    public int queryTotal(Map<String, Object> map) {
        return userCouponDao.queryTotal(map);
    }


    public void save(UserCouponVo goods) {
        userCouponDao.save(goods);
    }


    public void update(UserCouponVo goods) {
        userCouponDao.update(goods);
    }


    public void delete(Integer id) {
        userCouponDao.delete(id);
    }


    public void deleteBatch(Integer[] ids) {
        userCouponDao.deleteBatch(ids);
    }

    public List<UserCouponVo> queryUserCoupons(Map<String, Object> map) {
        return userCouponDao.queryUserCoupons(map);
    }
    /**
     * 标记未使用的优惠券是否可用,暂时无用
     *
     * @param userId
     * @param goodsTotalPrice
     * @return
     */
    public List<UserCouponVo> signUserCouponList(Long userId,String merchSn, BigDecimal goodsTotalPrice) {
        Map param = Maps.newHashMap();
        param.put("user_id", userId);
        param.put("unUsed", true);
        param.put("enabled", true);
        Integer[] send_types = new Integer[]{1, 2, 3, 4, 5, 6}; // 去除订单满减0，运费7
        param.put("send_types", send_types);
        param.put("merchSn", merchSn);

        List<UserCouponVo> couponVos = userCouponDao.queryList(param);
        if (null != couponVos && couponVos.size() > 0) {
            // 如果没有用户优惠券直接返回新用户优惠券
            for (UserCouponVo couponVo : couponVos) {
                //// TODO: 2019/5/15 最小金额
//                if (couponVo.getTypeMoney().compareTo(goodsTotalPrice) <= 0) {
//                    couponVo.setEnabled("1");
//                }
            }
        }
        return couponVos;
    }

    /**
     * 匹配未使用的优惠券是否可用
     *
     * @param userCouponDto
     * @return
     */
    public List<UserCouponVo> matchUserCouponList(UserCouponDto userCouponDto) {
        List<UserCouponVo> result = new ArrayList();
        List<MkStoreTicketDiscountVo> switchList = new ArrayList();
        if(userCouponDto.getCartGoodsList() == null || userCouponDto.getCartGoodsList().size() == 0){
            return result;
        }
        //获取订单中商品可支持的优惠券，自动选择减免最大的金额
        String isUsed = "0";
        //查询未使用已领取的优惠券
        Map map = mkStoreTicketDiscountService.queryStoreDiscountByCartGoodsId(userCouponDto, isUsed);
        List<MkStoreTicketDiscountVo> discountVoList = (List<MkStoreTicketDiscountVo>)map.get("discountVoList");
        if(discountVoList != null && discountVoList.size() > 0){
            for (MkStoreTicketDiscountVo discountVo : discountVoList) {
                BigDecimal cond = Constant.ZERO;
                BigDecimal money = Constant.ZERO;
                if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_00.getItem())){//代金券
                    cond = discountVo.getVoucherCond();
                    money = discountVo.getVoucherMoney();
                }
                if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_01.getItem())){//折扣券
                    cond = discountVo.getDiscCond();
                    money = discountVo.getDiscRatio();//满多少打几折
                }
                //// TODO: 2019/5/21 代金券暂时无用
                /*if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_02.getItem())){
                     cond = discountVo.getExchCond();
                     money = discountVo.getExchCond();
                  }*/
                if(discountVo.getApplyType().equalsIgnoreCase(Dict.applyType.item_00.getItem())){ //全部商品参与
                    //计算购物车中满足部分商品的销售价
                    BigDecimal totalByGoodsId = getTotalByGoodsId(userCouponDto.getCartGoodsList(),discountVoList,discountVo.getTickDiscId());
                    //销售价>满减价，去重
                    if (totalByGoodsId.compareTo(cond) >= 0 && containsList(switchList,discountVo)) {
                        UserCouponVo userCouponVo = setUserCouponVo(discountVo, money);
                        result.add(userCouponVo);
                        switchList.add(discountVo);
                    }
                }
                if(!discountVo.getApplyType().equalsIgnoreCase(Dict.applyType.item_00.getItem())) { //部分商品参与
                    //计算购物车中满足部分商品的销售价
                    BigDecimal totalByGoodsId = getTotalByGoodsId(userCouponDto.getCartGoodsList(),discountVoList,discountVo.getTickDiscId());
                    //销售价>满减价，去重
                    if(totalByGoodsId.compareTo(cond) >= 0 && containsList(switchList,discountVo)){
                        UserCouponVo userCouponVo = setUserCouponVo(discountVo, money);
                        result.add(userCouponVo);
                        switchList.add(discountVo);

                    }
                }
            }
            if(result != null && result.size() > 0) {
                UserCouponVo userCouponVo = new UserCouponVo();
                userCouponVo.setId(0L);
                userCouponVo.setCouponName("不参与优惠券");
                userCouponVo.setTypeMoney(Constant.ZERO);
                userCouponVo.setGoodsBizType(userCouponDto.getBizType());
                result.add(userCouponVo);
            }
        }
        return result;
    }

    /**
     * 获取优惠券可支持的商品总销售价
     * @param cartGoodsList
     * @param discountVoList
     * @param tickDistId
     * @return
     */
    private BigDecimal getTotalByGoodsId(List<CartVo> cartGoodsList, List<MkStoreTicketDiscountVo> discountVoList, Integer tickDistId){
        BigDecimal total = new BigDecimal(0);
        for (CartVo vo: cartGoodsList) {
            for(MkStoreTicketDiscountVo discountVo: discountVoList){
                if(discountVo.getTickDiscId() == tickDistId && discountVo.getGoodsId().compareTo(vo.getGoods_id().intValue()) == 0){
                    total = total.add(vo.getRetail_price().multiply(BigDecimal.valueOf(vo.getNumber())));
                }
            }
        }
        return total;
    }

    /**
     * 去重
     * @param switchList
     * @param discountVo
     * @return
     */
    private Boolean containsList(List<MkStoreTicketDiscountVo> switchList,MkStoreTicketDiscountVo discountVo){
        for (MkStoreTicketDiscountVo vo: switchList) {
            if(vo.getTickDiscId().equals(discountVo.getTickDiscId())){
                return false;
            }
        }
        return true;
    }

    private UserCouponVo setUserCouponVo(MkStoreTicketDiscountVo discountVo,BigDecimal money){
        UserCouponVo userCouponVo = new UserCouponVo();
        userCouponVo.setTickDiscType(discountVo.getTickDiscType());
        userCouponVo.setCouponName(discountVo.getName());
        userCouponVo.setTypeMoney(money);
        userCouponVo.setId(Long.valueOf(discountVo.getTickDiscId()));
        userCouponVo.setSelectTicket(false);
        userCouponVo.setGoodsBizType(discountVo.getGoodsBizType());
        userCouponVo.setGoodsList(discountVo.getGoodsList());
        return userCouponVo;
    }

    public UserCouponVo queryObjectByStoreTopicIdAndUserId(Integer storeTopicId,Long userId){
        return userCouponDao.queryObjectByStoreTopicIdAndUserId(storeTopicId,userId);
    }

    /**
     * 领取优惠券
     * @param jsonParam
     * @param loginUser
     */
    @Transactional
    public void getUserCoupon(JSONObject jsonParam, UserVo loginUser){
        Integer tickDiscId = jsonParam.getInteger("tickDiscId");
        Integer storeTopicId = jsonParam.getInteger("storeTopicId");
        Integer storeId = jsonParam.getInteger("storeId");
        Long userId = loginUser.getId();

        MkStoreTicketDiscountVo discountVo = mkStoreTicketDiscountService.queryObject(tickDiscId);
        if(discountVo == null){
            logger.error("该优惠券无效" );
            throw new RRException("该优惠券无效");
        }
        Map map = new HashMap();
        map.put("userId" , userId);
        map.put("storeId", storeId);
        map.put("storeTopicId", storeTopicId);
        map.put("tickDiscId", tickDiscId);
        List<MkStoreTicketDiscountVo> list = mkStoreTicketDiscountService.queryStoreDiscountByUserId(map);

        if (list.size() > 0 && list.size() == discountVo.getLimitNum()) {
            logger.error("您已经领取过该优惠券，不能重复领取" );
            throw new RRException("您已经领取过该优惠券，不能重复领取");
        }
        UserCouponVo userCouponVo = new UserCouponVo();
        userCouponVo.setCouponUrl(discountVo.getAdvImgUrl());
        userCouponVo.setCouponName(discountVo.getName());
        userCouponVo.setUserId(Long.valueOf(userId));
        userCouponVo.setAddTime(new Date());
        userCouponVo.setSourceKey("小程序");
        userCouponVo.setShowState(1);
        userCouponVo.setIsUsed(Dict.isUsed.item_0.getItem());
        userCouponVo.setEnabled("1");
        userCouponVo.setCreateTime(new Date());
        userCouponVo.setModTime(new Date());
        if(discountVo.getEffectTimeType().equalsIgnoreCase(Dict.effectTimeType.item_00.getItem())){
            userCouponVo.setEndTime(discountVo.getFixEndTime());
            userCouponVo.setValidTime(discountVo.getFixBegTime());
        }
        if(discountVo.getEffectTimeType().equalsIgnoreCase(Dict.effectTimeType.item_01.getItem())){
            Integer postponeNum = Integer.parseInt(discountVo.getPostponeNum());//领取后多少天后生效
            Integer day = postponeNum + Integer.parseInt(discountVo.getValidDayNum());
            Date validDate = DateUtils.addDay(new Date(), postponeNum);//生效时间
            Date endDate = DateUtils.addDay(new Date(), day);//过期时间
            userCouponVo.setEndTime(endDate);
            userCouponVo.setValidTime(validDate);
        }
        userCouponVo.setStoreTopicId(Long.valueOf(storeTopicId));
        //// TODO: 2019/5/21 代金券暂时无用
        /*if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_02.getItem())){
            userCouponVo.setTypeMoney(discountVo.getExchCond());
        }*/
        if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_00.getItem())){
            userCouponVo.setTypeMoney(discountVo.getVoucherMoney());
        }
        if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_01.getItem())){
            userCouponVo.setTypeMoney(discountVo.getDiscRatio());//折扣金额
        }
        userCouponDao.save(userCouponVo);
        //优惠券库存扣减
        if(discountVo.getTicketNum()-1 >= 0){
            MkStoreTicketDiscountVo mkStoreTicketDiscountVo = new MkStoreTicketDiscountVo();
            mkStoreTicketDiscountVo.setTickDiscId(discountVo.getTickDiscId());
            mkStoreTicketDiscountVo.setTicketNum(discountVo.getTicketNum()-1);
            mkStoreTicketDiscountService.updateDiscount(mkStoreTicketDiscountVo);
            //记录活动营销统计领取量数据
            apiMkStoreTopicStatService.saveStoreTopicStatByReceiveData(Integer.parseInt(String.valueOf(userCouponVo.getId())));
        }
    }
}
