package com.liquidnet.service.platform.service.impl.goblin;

import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.goblin.dto.vo.GoblinNftExCodeVo;
import com.liquidnet.service.goblin.entity.GoblinGoodsSku;
import com.liquidnet.service.goblin.entity.GoblinNftExCode;
import com.liquidnet.service.goblin.entity.GoblinNftExSku;
import com.liquidnet.service.goblin.mapper.GoblinGoodsSkuMapper;
import com.liquidnet.service.goblin.mapper.GoblinNftExCodeMapper;
import com.liquidnet.service.goblin.mapper.GoblinNftExSkuMapper;
import com.liquidnet.service.goblin.param.GoblinNftExSkuParam;
import com.liquidnet.service.goblin.service.IGoblinNftExSkuService;
import com.liquidnet.service.platform.utils.GoblinRedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @Author: wll
 * @Description: nft兑换活动和和sku的关联
 * @Date:Create：in 2022/4/19 5:14 下午
 */

@Service
@Slf4j
public class GoblinNftExSkuServiceImpl implements IGoblinNftExSkuService {

    @Autowired
    private GoblinNftExCodeMapper goblinNftExCodeMapper;
    @Autowired
    private GoblinNftExSkuMapper goblinNftExSkuMapper;
    @Autowired
    private GoblinRedisUtils goblinRedisUtils;
    @Autowired
    private GoblinGoodsSkuMapper goblinGoodsSkuMapper;


    @Transactional
    @Override
    public Boolean add(List<GoblinNftExSkuParam> goblinNftExSkuParams) {

        LocalDateTime now = LocalDateTime.now();

/*        ArrayList<GoblinNftExSkuVo> goblinNftExSkuArrayList = ObjectUtil.getGoblinNftExSkuArrayList();
        ArrayList<GoblinNftExCodeVo> goblinNftExCodeArrayList = ObjectUtil.getGoblinNftExCodeArrayList();*/


        Boolean bol = false;
        String spuId = "";
        for (GoblinNftExSkuParam goblinNftExSkuParam : goblinNftExSkuParams) {
            if (goblinNftExSkuParam.getUnbox().equals("1")) {
                bol = true;
                spuId = goblinNftExSkuParam.getSpuId();
                break;
            }
        }


        Map<String, BigDecimal> map = new HashMap<>();
        if (bol) {
            // 获取spu下所有sku
            List<GoblinGoodsSku> goblinGoodsSkus = goblinGoodsSkuMapper.selectBySpuIds(spuId);
            for (GoblinGoodsSku goblinGoodsSku : goblinGoodsSkus) {
                if (goblinGoodsSku.getUnbox().equals("1")) {
                    continue;
                }
                map.put(goblinGoodsSku.getSkuId(), goblinGoodsSku.getHitRatio());
            }
        }

        List<GoblinNftExSku> goblinNftExSkus = new ArrayList<>();
        List<GoblinNftExCode> goblinNftExCodes = new ArrayList<>();


        // 构建对象
        for (GoblinNftExSkuParam goblinNftExSkuParam : goblinNftExSkuParams) {
            
            GoblinNftExSku goblinNftExSku = new GoblinNftExSku();
            BeanUtils.copyProperties(goblinNftExSkuParam, goblinNftExSku);
            goblinNftExSku.setCreatedAt(now);


            // 盲盒  概率
            switch (goblinNftExSkuParam.getUnbox()) {
                case "1":
                    // sku ---> 库存
                    Map<String, Integer> skuMap = getSkuHitRatio(goblinNftExSkuParam.getExStock(), map);
                    for (String key : skuMap.keySet()) {
                        Integer stockNum = skuMap.get(key);
                        for (int i = 0; i < stockNum; i++) {
                            GoblinNftExCode goblinNftExCode = GoblinNftExCode.getNew();
                            goblinNftExCode.setCodeId(IDGenerator.nextSnowId());
                            goblinNftExCode.setActivityId(goblinNftExSkuParam.getActivityId());

                            // 获取兑换码ZA
                            // 样例 2978-6496-9269-0694-XX
                            String code = IDGenerator.createCode(3, 4, true);
                            goblinNftExCode.setCode(code);
                            goblinNftExCode.setBoxSkuId(key);
                            goblinNftExCode.setState(1);
                            goblinNftExCode.setCreatedAt(now);
                            goblinNftExCodes.add(goblinNftExCode);

                            GoblinNftExCodeVo goblinNftExCodeVo = GoblinNftExCodeVo.getNew().copy(goblinNftExCode);

                            // 赋值额外属性
                            goblinNftExCodeVo.setExLimit(goblinNftExSkuParam.getExLimit());
                            goblinNftExCodeVo.setExStartTime(goblinNftExSkuParam.getExStartTime());
                            goblinNftExCodeVo.setExStopTime(goblinNftExSkuParam.getExStopTime());

                            LocalDateTime exStartTime = goblinNftExSkuParam.getExStartTime();
                            LocalDateTime exStopTime = goblinNftExSkuParam.getExStopTime();

                            // 时间差  以秒表示
                            long millisNum = Duration.between(exStartTime, exStopTime).toMillis();

                            // redis 存储
                            goblinRedisUtils.addCode(code, goblinNftExCodeVo, millisNum);
                        }
                    }


                    break;
                default:


                    // 构建兑换码数量
                    for (int i = 0; i < goblinNftExSkuParam.getExStock(); i++) {
                        GoblinNftExCode goblinNftExCode = GoblinNftExCode.getNew();
                        goblinNftExCode.setCodeId(IDGenerator.nextSnowId());
                        goblinNftExCode.setActivityId(goblinNftExSkuParam.getActivityId());

                        // 获取兑换码ZA
                        // 样例 2978-6496-9269-0694-XX
                        String code = IDGenerator.createCode(3, 4, true);
                        goblinNftExCode.setCode(code);
                        goblinNftExCode.setSkuId(goblinNftExSkuParam.getSkuId());
                        goblinNftExCode.setState(1);
                        goblinNftExCode.setCreatedAt(now);
                        goblinNftExCodes.add(goblinNftExCode);

                        GoblinNftExCodeVo goblinNftExCodeVo = GoblinNftExCodeVo.getNew().copy(goblinNftExCode);

                        // 赋值额外属性
                        goblinNftExCodeVo.setExLimit(goblinNftExSkuParam.getExLimit());
                        goblinNftExCodeVo.setExStartTime(goblinNftExSkuParam.getExStartTime());
                        goblinNftExCodeVo.setExStopTime(goblinNftExSkuParam.getExStopTime());

                        LocalDateTime exStartTime = goblinNftExSkuParam.getExStartTime();
                        LocalDateTime exStopTime = goblinNftExSkuParam.getExStopTime();

                        // 时间差  以秒表示
                        long millisNum = Duration.between(exStartTime, exStopTime).toMillis();

                        // redis 存储
                        goblinRedisUtils.addCode(code, goblinNftExCodeVo, millisNum);
                        // goblinNftExCodeArrayList.add(GoblinNftExCodeVo.getNew().copy(goblinNftExCode));
                    }
                    goblinNftExSkus.add(goblinNftExSku);
                    // goblinNftExSkuArrayList.add(GoblinNftExSkuVo.getNew().copy(goblinNftExSku));
            }

        }

        // 数据库操作
        goblinNftExSkuMapper.addGoblinNftExSkus(goblinNftExSkus);
        goblinNftExCodeMapper.addGoblinNftExCodes(goblinNftExCodes);

        return true;
    }

    /**
     * 获取每个sku的
     *
     * @param exStock
     * @param map
     * @return
     */
    private Map<String, Integer> getSkuHitRatio(Integer exStock, Map<String, BigDecimal> map) {

        // sku ---> 次数
        Map<String, Integer> skuNumMap = new HashMap<>();

        for (String key : map.keySet()) {
            // 概率
            BigDecimal hitNum = map.get(key).divide(BigDecimal.valueOf(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
            Integer stock = hitNum.multiply(BigDecimal.valueOf(exStock)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
            skuNumMap.put(key, stock);
        }
        return skuNumMap;
    }

}
