package com.ssj.service.sys.award.service.impl;

import com.ssj.bean.sys.award.domain.AwardActivity;
import com.ssj.bean.sys.award.domain.AwardConsume;
import com.ssj.bean.sys.award.domain.AwardSncode;
import com.ssj.bean.sys.award.domain.AwardStock;
import com.ssj.bean.sys.fx.domain.Merchant;
import com.ssj.dao.sys.award.dao.AwardQueryDao;
import com.ssj.dao.sys.award.dao.AwardSncodeDao;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.util.RedisUtil;
import com.ssj.service.conch.conch.service.HomeworkRankingService;
import com.ssj.service.sys.award.service.AwardActivityService;
import com.ssj.service.sys.award.service.AwardConsumeService;
import com.ssj.service.sys.award.service.AwardSncodeService;
import com.ssj.service.sys.award.service.AwardStockService;
import com.ssj.service.sys.fx.service.MerchantService;
import com.ssj.service.task.SyncCreateQrSnCodeTask;
import com.ssj.taskthread.ThreadPool;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class AwardSncodeServiceImpl extends BaseServiceImpl<AwardSncode, String> implements AwardSncodeService {
	
    private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private AwardSncodeDao  awardSncodeDao;

	@Autowired
	private AwardQueryDao  queryDao;
	
	@Autowired
	private AwardStockService  awardStockService;
	
	@Autowired
	private AwardConsumeService  awardConsumeService;

	@Autowired
	private AwardActivityService  awardActivityService;
	
	@Autowired
	private HomeworkRankingService  homeworkRankingService;
	
	@Autowired
	private MerchantService  merchantService;
	
	@Autowired
    private RedisUtil redisUtil;
	
    public static String FALSE_SNCODE="FALSE_SNCODE_";
	
	@Override
	public Page<Map<String, Object>> findAwardSncodeBylist(Map<String, Object> searchParams, Pageable pageable) {
		return queryDao.findAwardSncodeBylist(searchParams, pageable);
	}

	
	@Override
	public PagingAndSortingRepository<AwardSncode, String> getDao() {
		return awardSncodeDao;
	}

	@Override
	public List<AwardSncode> findAwardSncodeByAwardActivityId(String awardActivityId, Integer status) {
		return awardSncodeDao.findAwardSncodeByAwardActivityId(awardActivityId, status);
	}


	@Override
	public List<AwardSncode> findAwardSncodeByAwardMaterialId(String awardActivityId, String awardMaterialId,Integer status) {
		return awardSncodeDao.findAwardSncodeByAwardMaterialId(awardActivityId, awardMaterialId, status);
	}
	
	
	@Override
	public synchronized void createAwardSncodeByCode(AwardActivity awardActivity) {
		//已经生成过code的活动，不能再生成。
		List<AwardSncode> aAwardSncodes=awardSncodeDao.findAwardSncodeByAwardActivityId(awardActivity.getId());
		if(aAwardSncodes!=null && aAwardSncodes.size()>0) {
			return ;
		}
		
		Merchant merchant= merchantService.getById(awardActivity.getMerchantId());
		List<AwardSncode> awardSncodes=new ArrayList<AwardSncode>();
		AwardSncode awardSncode=null;
		
		if(StringUtils.isNotEmpty(awardActivity.getLevel1MaterialId()) && awardActivity.getLevel1Num()>0) {
			for (int i = 1; i <= awardActivity.getLevel1Num(); i++) {
				awardSncode=new AwardSncode();
				awardSncode.setAwardActivityId(awardActivity.getId());
				awardSncode.setAwardMaterialId(awardActivity.getLevel1MaterialId());
				awardSncode.setSnCode(DateHelper.getOrderNo(5)+i);
				awardSncode.setLibId(merchant.getLibId());
				//awardSncode.setSnImg(createQrCode(awardSncode.getSnCode()));
				awardSncode.setStatus(0);
				awardSncode.setCreateTime(new Date());
				awardSncodes.add(awardSncode);
				
			}
		}
		
		if(StringUtils.isNotEmpty(awardActivity.getLevel2MaterialId()) && awardActivity.getLevel2Num()>0) {
			for (int i = 1; i <= awardActivity.getLevel2Num(); i++) {
				awardSncode=new AwardSncode();
				awardSncode.setAwardActivityId(awardActivity.getId());
				awardSncode.setAwardMaterialId(awardActivity.getLevel2MaterialId());
				awardSncode.setSnCode(DateHelper.getOrderNo(5)+i);
				awardSncode.setLibId(merchant.getLibId());
				//awardSncode.setSnImg(createQrCode(awardSncode.getSnCode()));
				awardSncode.setStatus(0);
				awardSncode.setCreateTime(new Date());
				awardSncodes.add(awardSncode);
			}
			
		}
		
		if(StringUtils.isNotEmpty(awardActivity.getLevel3MaterialId()) && awardActivity.getLevel3Num()>0) {
			for (int i = 1; i <= awardActivity.getLevel3Num(); i++) {
				awardSncode=new AwardSncode();
				awardSncode.setAwardActivityId(awardActivity.getId());
				awardSncode.setAwardMaterialId(awardActivity.getLevel3MaterialId());
				awardSncode.setSnCode(DateHelper.getOrderNo(5)+i);
				awardSncode.setLibId(merchant.getLibId());
				//awardSncode.setSnImg(createQrCode(awardSncode.getSnCode()));
				awardSncode.setStatus(0);
				awardSncode.setCreateTime(new Date());
				awardSncodes.add(awardSncode);
			}
		}
		//保存兑换码
		this.save(awardSncodes);
		//加载兑换码到redis
		this.loadAwardSncodeToRedisByActivityId(awardActivity.getId());
		//生成兑换码图片
		ThreadPool.getInstance().addTask(new SyncCreateQrSnCodeTask(awardSncodes));
	}
	
	@Override
	public synchronized void cleanAwardSncodeByCode(AwardActivity awardActivity) {

		List<AwardStock> awardStocks=new ArrayList<AwardStock>();
		List<AwardConsume> awardConsumes=new ArrayList<AwardConsume>();
		List<AwardSncode> statusAwardSncodes=new ArrayList<AwardSncode>();
		
		if(StringUtils.isNotEmpty(awardActivity.getLevel1MaterialId()) && awardActivity.getLevel1Num()>0) {
			List<AwardSncode> awardSncodes=this.findAwardSncodeByAwardMaterialId(awardActivity.getId(), awardActivity.getLevel1MaterialId(), 0);
			if(awardSncodes!=null && awardSncodes.size()>0) {
			
				for (AwardSncode awardSncode : awardSncodes) {
					awardSncode.setStatus(5);
					awardSncode.setUpdateTime(new Date());
					statusAwardSncodes.add(awardSncode);
				}
				
				
				AwardStock awardStock=awardStockService.getAwardStockByMaterialId(awardActivity.getMerchantId(), awardActivity.getLevel1MaterialId());
				awardStock.setStockNumber(awardStock.getStockNumber()+awardSncodes.size());
				awardStocks.add(awardStock);

				AwardConsume awardConsume=new AwardConsume();
				awardConsume.setFromMerchantId(awardActivity.getMerchantId());
				awardConsume.setToMerchantId(null);
				awardConsume.setAwardMaterialId(awardActivity.getLevel1MaterialId());
				awardConsume.setNumber(awardSncodes.size());
				awardConsume.setType(5);
				awardConsume.setRemarks("取消活动返回库存量");
				awardConsumes.add(awardConsume);
			}
		}
		
		if(StringUtils.isNotEmpty(awardActivity.getLevel2MaterialId()) && awardActivity.getLevel2Num()>0) {
			List<AwardSncode> awardSncodes=this.findAwardSncodeByAwardMaterialId(awardActivity.getId(), awardActivity.getLevel2MaterialId(), 0);
			if(awardSncodes!=null && awardSncodes.size()>0) {
				
				for (AwardSncode awardSncode : awardSncodes) {
					awardSncode.setStatus(5);
					awardSncode.setUpdateTime(new Date());
					statusAwardSncodes.add(awardSncode);
				}
				
				AwardStock awardStock=awardStockService.getAwardStockByMaterialId(awardActivity.getMerchantId(), awardActivity.getLevel2MaterialId());
				awardStock.setStockNumber(awardStock.getStockNumber()+awardSncodes.size());
				awardStocks.add(awardStock);
				

				AwardConsume awardConsume=new AwardConsume();
				awardConsume.setFromMerchantId(awardActivity.getMerchantId());
				awardConsume.setToMerchantId(null);
				awardConsume.setAwardMaterialId(awardActivity.getLevel2MaterialId());
				awardConsume.setNumber(awardSncodes.size());
				awardConsume.setType(5);
				awardConsume.setRemarks("取消活动返回库存量");
				awardConsumes.add(awardConsume);
			}
		}
		
		if(StringUtils.isNotEmpty(awardActivity.getLevel3MaterialId()) && awardActivity.getLevel3Num()>0) {
			List<AwardSncode> awardSncodes=this.findAwardSncodeByAwardMaterialId(awardActivity.getId(), awardActivity.getLevel3MaterialId(), 0);
			if(awardSncodes!=null && awardSncodes.size()>0) {
				
				for (AwardSncode awardSncode : awardSncodes) {
					awardSncode.setStatus(5);
					awardSncode.setUpdateTime(new Date());
					statusAwardSncodes.add(awardSncode);
				}
				
				AwardStock awardStock=awardStockService.getAwardStockByMaterialId(awardActivity.getMerchantId(), awardActivity.getLevel3MaterialId());
				awardStock.setStockNumber(awardStock.getStockNumber()+awardSncodes.size());
				awardStocks.add(awardStock);
				
				AwardConsume awardConsume=new AwardConsume();
				awardConsume.setFromMerchantId(awardActivity.getMerchantId());
				awardConsume.setToMerchantId(null);
				awardConsume.setAwardMaterialId(awardActivity.getLevel3MaterialId());
				awardConsume.setNumber(awardSncodes.size());
				awardConsume.setType(5);
				awardConsume.setRemarks("取消活动返回库存量");
				awardConsumes.add(awardConsume);
			}
		}
		this.save(statusAwardSncodes);
		awardStockService.save(awardStocks);
		awardConsumeService.saveAwardConsumeLog(awardConsumes);
	}


	@Override
	public AwardSncode randomAwardSncodeByActivityIdAndMaterialId(String awardActivityId, String materialId) {
		return awardSncodeDao.randomAwardSncodeByActivityIdAndMaterialId(awardActivityId, materialId);
	}
	
	@Override
	public Page<Map<String, Object>> findAwardSncodeByVipList(Map<String, Object> searchParams, Pageable pageable) {
		return queryDao.findAwardSncodeByVipList(searchParams, pageable);
	}


	@Override
	public AwardSncode getAwardSncodeBySnCode(String snCode) {
		return awardSncodeDao.getAwardSncodeBySnCode(snCode);
	}


	@Override
	public boolean loadAwardSncodeToRedisByActivityId(String awardActivityId) {
		logger.info("抽奖活动数据加载Redis，活动ID："+awardActivityId);
		if(redisUtil.exists(awardActivityId)) {
			return true;
		}
		List<String> redisList=new ArrayList<String>();
		AwardActivity awardActivity=awardActivityService.getById(awardActivityId);
		List<AwardSncode> awardSncodes=awardSncodeDao.findAwardSncodeByAwardActivityId(awardActivity.getId());
		for (AwardSncode awardSncode : awardSncodes) {
			redisList.add(awardSncode.getSnCode());
		}
		Integer count=awardActivity.getPartakeNum()-awardSncodes.size();
		if(count>0) {
			for (int i = 1; i <=count; i++) {
				redisList.add(FALSE_SNCODE+i);
			}
		}
		//打乱集合的排序，放到redis中，为了保证数据更乱，三次打乱集合。
		Collections.shuffle(redisList);
		Collections.shuffle(redisList);
		Collections.shuffle(redisList);
		
		String[] sncodeList = redisList.toArray(new String[redisList.size()]); 
		redisUtil.sadd(awardActivityId, redisList.toArray(sncodeList));
		logger.info("抽奖活动数据加载Redis，活动ID："+awardActivityId);
		logger.info("抽奖活动数据加载Redis，奖码列表："+String.join(",",sncodeList));
		awardActivity.setIsRedis(1);
		awardActivityService.save(awardActivity);
		return true;
	}


	@Override
	public synchronized AwardSncode randomAwardSncodeRedisByActivityId(String awardActivityId) {
		logger.info("抽奖中，活动ID："+awardActivityId);
		if(!redisUtil.exists(awardActivityId)) {
			logger.info("抽奖中，Redis中未生成奖品码，开始生成奖品码，活动ID："+awardActivityId);
			loadAwardSncodeToRedisByActivityId(awardActivityId);
			logger.info("抽奖中，Redis中未生成奖品码，生成奖品码成功，活动ID："+awardActivityId);
		}
		String snCode=redisUtil.spop(awardActivityId);
		logger.info("抽奖中，Redis中返回奖品码，奖品码："+(snCode==null ? "": snCode)+"，活动ID："+awardActivityId);
		if(StringUtils.isNotEmpty(snCode) && !snCode.startsWith(FALSE_SNCODE)) {
			AwardSncode awardSncode=this.getAwardSncodeBySnCode(snCode);
			if(awardSncode!=null && awardSncode.getStatus()==0) {
				logger.info("抽奖中，Redis中返回奖品码，奖品码有效返回，活动ID："+awardActivityId);
				return awardSncode;
			}
		}
		return null;
	}


	@Override
	public AwardSncode awardSncodeByActivityId(String userId,String vipId,String awardActivityId) {
		//为了保证数据同步,抽奖前一步再查一次积分,不足的, 返回未中奖
		Integer integral=homeworkRankingService.searchIntegralByVipId(vipId);
		if(integral<200) {
			return null;
		}
		
		//减量积分
        homeworkRankingService.saveRankIntegral(vipId, -200, 9, vipId);
        
		AwardSncode awardSncode=randomAwardSncodeRedisByActivityId(awardActivityId);
		if(awardSncode!=null) {
			logger.info("抽奖中，中奖啦，vipId："+(vipId==null?"":vipId)+"，活动ID："+awardActivityId);
			awardSncode.setUserId(userId);
			awardSncode.setStatus(1);
			awardSncode.setType(1);
			awardSncode.setVipId(vipId);
			awardSncode.setDrawTime(new Date());
			awardSncode.setUpdateTime(new Date());
			this.save(awardSncode);
			return awardSncode;
		}
		logger.info("抽奖中，未中奖...，vipId："+(vipId==null?"":vipId)+"，活动ID："+awardActivityId);
		return null;
	}


	@Override
	public void cleanAwardSncodeResisByCode(String awardActivityId, String snCode) {
		redisUtil.srem(awardActivityId, snCode);
	}


	@Override
	public void updateSnCodeImgBySnCode(String snCode, String snCodeImg) {
		awardSncodeDao.updateSnCodeImgBySnCode(snCode, snCodeImg);
	}


	

	

	

}
