package com.chinacreator.video.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.chinacreator.video.bean.OrderInfo;
import com.chinacreator.video.exception.BussinessException;
import com.chinacreator.video.mapper.CommConfDao;
import com.chinacreator.video.util.RedisService;
import com.chinacreator.video.validate.BusiValidate;

@Component
public class QryBusiService {
	
	private static final  Logger logger = LoggerFactory.getLogger(QryBusiService.class);
	
	private static final  Logger log = LoggerFactory.getLogger("qrybusi");
	
	@Autowired
	private BusiValidate busiVali;
	
	@Autowired
	private CommConfDao commConfDao;
	
	@Autowired
	RedisService redisService;
	
	public void checkBusi(OrderInfo orderInfo) throws Exception {
		busiVali.valiTime(orderInfo);
		busiVali.valiChannel(orderInfo);
		busiVali.valiSign(orderInfo);
		//CPID如果没限制，则SPID强制设置为0，也是不限制
		if("0".equals(orderInfo.getCpid())){
			orderInfo.setSpid("0");
		}
		busiVali.valiCpSp(orderInfo);
		busiVali.valiMob(orderInfo);
		busiVali.valiIp(orderInfo);
	}
	
	/**
	 * 获取订购数据
	 * @param orderInfo
	 * @return
	 */
	public List<Map> getOrderInfo(OrderInfo orderInfo)throws Exception {
		List<Map> orderList = commConfDao.getAllOrder(orderInfo.getUserid());
		setVisitcount(orderInfo);
		return filterData(orderList,orderInfo);
	}
	
	/**
	 * 过滤数据
	 * @param orderList
	 * @param orderInfo
	 */
	private List<Map> filterData(List<Map> orderList,OrderInfo orderInfo){
		//替换或添加次月生效的数据
		replaceData(orderList, orderInfo);
		List<Map> resList = new ArrayList<Map>();
		if(orderList != null && orderList.size()>0){
			for(Map map : orderList){
				map.put("USERID", orderInfo.getEnuserid());
				if("NULL".equals(map.get("CANCELCHANNEL"))){
					map.put("CANCELCHANNEL", "");
				}
				if("NULL".equals(map.get("CANCELTIME"))){
					map.put("CANCELTIME", "");
				}
				if("NULL".equals(map.get("SPNAME"))){
					map.put("SPNAME", "");
				}
				if("NULL".equals(map.get("ENDTIME"))){
					map.put("ENDTIME", "");
				}
			}
			if("0".equals(orderInfo.getCpid())){ //不限CPID
				for(Map map : orderList){
					if(!"2".equals(map.get("STATUS"))){ //剔除失效的数据
						resList.add(map);
					}
				}
			}else if("0".equals(orderInfo.getSpid())){//限CPID，但不限SPID
				for(Map map : orderList){
					if(map.get("CPID").equals(orderInfo.getCpid()) 
							&& !"2".equals(map.get("STATUS"))){
						resList.add(map);
					}
				}
			}else{ //只限CPID
				for(Map map : orderList){
					if(map.get("CPID").equals(orderInfo.getCpid()) 
							&& map.get("SPID").equals(orderInfo.getSpid()) 
							&& !"2".equals(map.get("STATUS"))){
						resList.add(map);
					}
				}
			}
		}
		return resList;
	}
	
	/**
	 * 验证访问数据限制
	 * @param orderInfo
	 * @throws Exception
	 */
	public void valiVisitLimit(OrderInfo orderInfo) throws Exception {
		try {
			String channel = orderInfo.getChannel();
			List<Map> visitConf = commConfDao.getlimitQryConf();
			Map visitMap = null;
			if(visitConf != null && visitConf.size()>0){
				for(Map map : visitConf){
					if(orderInfo.getChannel().equals(map.get("CHANNEL"))){
						visitMap = map;
						break;
					}
				}
			}
			if(visitMap != null){
				//[{MONTHLIMIT=6, CHANNEL=TX_2104, HOURLIMIT=2, DAYLIMIT=4, TOTALLIMIT=10, YEARLIMIT=8}]
				if(visitMap.get("HOURLIMIT") != null && !"".equals(visitMap.get("HOURLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("HOURLIMIT")+"");
					String limitKey = getLimitKey("yyyyMMddHH");
					String itemKey = getLimitKey("yyyyMMdd");
					Object obj = redisService.hmGet("univideo_visit_"+itemKey+"_"+channel,limitKey);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10031", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("DAYLIMIT") != null && !"".equals(visitMap.get("DAYLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("DAYLIMIT")+"");
					String limitKey = getLimitKey("yyyyMMdd");
					String itemKey = getLimitKey("yyyyMM");
					Object obj = redisService.hmGet("univideo_visit_"+itemKey+"_"+channel,limitKey);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10032", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("MONTHLIMIT") != null && !"".equals(visitMap.get("MONTHLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("MONTHLIMIT")+"");
					String limitKey = getLimitKey("yyyyMM");
					String itemKey = getLimitKey("yyyy");
					Object obj = redisService.hmGet("univideo_visit_"+itemKey+"_"+channel,limitKey);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10033", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("YEARLIMIT") != null && !"".equals(visitMap.get("YEARLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("YEARLIMIT")+"");
					String limitKey = getLimitKey("yyyy");
					Object obj = redisService.get("univideo_visit_year_"+limitKey+"_"+channel);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10034", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("TOTALLIMIT") != null && !"".equals(visitMap.get("TOTALLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("TOTALLIMIT")+"");
					Object obj = redisService.get("univideo_visit_total_"+channel);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10035", "访问次数超出最大次数");
					}
				}				
			}
		} catch (Exception e) {
			e.printStackTrace();
			if(e instanceof BussinessException) {
				throw e;
			}else {
				throw new BussinessException("10030", "验证访问数据限制出现错误，"+e.getMessage());
			}
			//log.error("验证访问数据限制出现错误，"+e.getMessage());
		}
	}
	
	/**
	 * 设置访问数据
	 * @param orderInfo
	 * @throws Exception
	 */
	public void setVisitcount(OrderInfo orderInfo) throws Exception {
		try {
			String channel = orderInfo.getChannel();
			List<Map> visitConf = commConfDao.getlimitQryConf();
			Map visitMap = null;
			if(visitConf != null && visitConf.size()>0){
				for(Map map : visitConf){
					if(orderInfo.getChannel().equals(map.get("CHANNEL"))){
						visitMap = map;
						break;
					}
				}
			}
			if(visitMap != null){
				//[{MONTHLIMIT=6, CHANNEL=TX_2104, HOURLIMIT=2, DAYLIMIT=4, TOTALLIMIT=10, YEARLIMIT=8}]
				if(visitMap.get("HOURLIMIT") != null && !"".equals(visitMap.get("HOURLIMIT"))){
					String limitKey = getLimitKey("yyyyMMddHH");
					String itemKey = getLimitKey("yyyyMMdd");
					if(!redisService.exists("univideo_visit_"+itemKey+"_"+channel)){
						redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1);
						redisService.expire("univideo_visit_"+itemKey+"_"+channel, 86400*2); //设置过期 时间为两天
					}else{
						redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1);
					
					}
				}
				if(visitMap.get("DAYLIMIT") != null && !"".equals(visitMap.get("DAYLIMIT"))){
					String limitKey = getLimitKey("yyyyMMdd");
					String itemKey = getLimitKey("yyyyMM");
					if(!redisService.exists("univideo_visit_"+itemKey+"_"+channel)){
						redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1);
						redisService.expire("univideo_visit_"+itemKey+"_"+channel, 86400*62); //设置过期 时间为两个月
					}else{
						redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1);
					}
				}
				if(visitMap.get("MONTHLIMIT") != null && !"".equals(visitMap.get("MONTHLIMIT"))){
					String limitKey = getLimitKey("yyyyMM");
					String itemKey = getLimitKey("yyyy");
					redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1);
				}
				if(visitMap.get("YEARLIMIT") != null && !"".equals(visitMap.get("YEARLIMIT"))){
					String limitKey = getLimitKey("yyyy");
					redisService.incr("univideo_visit_year_"+limitKey+"_"+channel,1);
				}
				if(visitMap.get("TOTALLIMIT") != null && !"".equals(visitMap.get("TOTALLIMIT"))){
					redisService.incr("univideo_visit_total_"+channel,1);
				}				
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("设置访问数据出现错误，"+e.getMessage());
			//throw new BussinessException("10030", "验证访问数据限制出现错误，"+e.getMessage());
		}
	}
	
	private String getLimitKey(String dateFormat){
		 SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); 
		 String limitKey = formatter.format(new Date());
		 return limitKey;
	}
	
	/**
	 * 替换或增加能力平台次月生效的订购数据
	 * @param orderList
	 * @param orderInfo
	 */
	private void replaceData(List<Map> orderList,OrderInfo orderInfo){
		try {
			if(orderList == null){
				orderList = new ArrayList<Map>();
			}
			List<Map> orderNmaList = commConfDao.findNmaOrderRela(orderInfo.getUserid());
			//log.info("替换前orderList=>"+orderList);
			//log.info("orderNmaList=>"+orderNmaList);
			if(orderNmaList != null && orderNmaList.size()>0){
				boolean hasexist = false;
				String nmamapStatus = ""; 
				String nmamapSyncstatus = "";
				//遍历次月生效的订购关系
				for(Map nmamap : orderNmaList){
					hasexist = false;		
					nmamapStatus = (String)nmamap.get("STATUS");
					nmamapSyncstatus = (String)nmamap.get("SYNCSTATUS");
					for(Map ordermap : orderList) {
						//正式表和中间表都有数据
						if(nmamap.get("SPID").equals(ordermap.get("SPID"))){
							//logger.info("SPID相同"+ordermap.get("SPID"));
							hasexist = true;
							//正式表非订购状态，走替换流程
							if(!"0".equals(ordermap.get("STATUS"))){ 
								if(
										//中间表是订购状态，且未同步，则替换为订购
										("0".equals(nmamapStatus) && "1".equals(nmamapSyncstatus)) 
										||
										//中间表是退订状态，且退订时间为当月且大于正式表的退订时间，替换为退订
										("1".equals(nmamapStatus) && Long.parseLong(nmamap.get("CANCELTIME").toString()) > Long.parseLong(ordermap.get("CANCELTIME").toString()))
										){//中间表是订购状态，且未同步，则替换为订购，如果已同步，不替换
									//移除原数据
									orderList.remove(ordermap);
									//添加新数据
									orderList.add(nmamap);													
								}
							}
							
							break;
						}
					}					
					//正式表不存在，则直接添加
					if(!hasexist){
						//log.info("添加数据"+nmamap);
						orderList.add(nmamap);
					}
				}
			}
			//log.info("替换后orderList=>"+orderList);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
