package com.steerinfo.ems.trmindexvalue.service.impl;

import com.steerinfo.framework.mapper.IBaseMapper;
import com.steerinfo.framework.service.impl.BaseServiceImpl;
import com.steerinfo.ems.trmindexvalue.model.TRmIndexValue;
import com.steerinfo.auth.utils.JwtUtil;
import com.steerinfo.ems.Utils.BigDecimalUtil;
import com.steerinfo.ems.formula.service.IFormulaService;
import com.steerinfo.ems.trmindexitem.mapper.TRmIndexItemMapper;
import com.steerinfo.ems.trmindexitem.model.TRmIndexItem;
import com.steerinfo.ems.trmindexvalue.mapper.TRmIndexValueMapper;
import com.steerinfo.ems.trmindexvalue.service.ITRmIndexValueService;
import com.steerinfo.framework.service.pagehelper.PageHelper;
import com.steerinfo.framework.service.pagehelper.PageList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * TRmIndexValue服务实现：
 * @author generator
 * @version 1.0-SNAPSHORT 2019-11-15 11:24
 * 类描述
 * 修订历史：
 * 日期：2019-11-15
 * 作者：generator
 * 参考：
 * 描述：TRmIndexValue服务实现
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@Service(value = "tRmIndexValueService")
public class TRmIndexValueServiceImpl extends BaseServiceImpl<TRmIndexValue, HashMap<String, Object>> implements ITRmIndexValueService {
	
	private static final Logger logger = LoggerFactory.getLogger(TRmIndexValueServiceImpl.class);

    @Autowired
    private TRmIndexValueMapper tRmIndexValueMapper;
    
    @Autowired
    private TRmIndexItemMapper tRmIndexItemMapper;
    
    @Autowired
    private IFormulaService formulaService;

    @Override
    protected IBaseMapper<TRmIndexValue, HashMap<String, Object>> getMapper() {
        return tRmIndexValueMapper;
    }

    @Override
    public PageList<Map<String, Object>> getTRmIndexValues(HashMap<String, Object> parmas, Integer pageNum, Integer pageSize) {
    	PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> tRmIndexValues = tRmIndexValueMapper.getTRmIndexValues(parmas);
        PageList<Map<String, Object>> pageInfo = new PageList<Map<String, Object>>(tRmIndexValues);
        return pageInfo;
    }

	@Override
	public void statData() {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("useflag", "1");
		m.put("itemflag", "3");
		List<TRmIndexItem> l = tRmIndexItemMapper.selectByParasForFla(m);
		if(l!=null && l.size()>0){
			for(TRmIndexItem tRmIndexItem : l){
				String itemid = tRmIndexItem.getItemid();
				// 从最小粒度到年粒度计算
				Map<String, String> mp = new LinkedHashMap<String, String>();
				String mintimegranid = tRmIndexItem.getMintimegranid();
				if(mintimegranid.equalsIgnoreCase("DAY")){
					Calendar cal = Calendar.getInstance();
					cal.add(Calendar.DAY_OF_YEAR, -1); // 减1日获得昨天日期
					mp.put("DAY", new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime()));
					mp.put("MONTH", new SimpleDateFormat("yyyy-MM").format(cal.getTime()));
					mp.put("YEAR", new SimpleDateFormat("yyyy").format(cal.getTime()));
				}else if(mintimegranid.equalsIgnoreCase("MONTH")){
					mp.put("MONTH", new SimpleDateFormat("yyyy-MM").format(new Date()));
					mp.put("YEAR", new SimpleDateFormat("yyyy").format(new Date()));
				}
				HashMap<String, Object> id = new HashMap<String, Object>();
				id.put("itemid", itemid);
				Iterator<Entry<String, String>> it = mp.entrySet().iterator();
				while (it.hasNext()) {
		            Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
		            String timegranid = entry.getKey();
		            String clock = entry.getValue();
		            id.put("timegranid", timegranid);
		            id.put("clock", clock);
		            this.restatData(itemid, clock, timegranid, "系统");
		        }
			}
		}
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public TRmIndexValue modifyAndCompute(TRmIndexValue tRmIndexValue) {
		tRmIndexValueMapper.updateByPrimaryKeySelective(tRmIndexValue);
		String itemid = tRmIndexValue.getItemid();
		String clock = tRmIndexValue.getClock();
		String timegranid = tRmIndexValue.getTimegranid();
		// 重新计算
		formulaService.reCalculateIndexVal(itemid, clock, timegranid);
		return tRmIndexValueMapper.selectByPrimaryKey(tRmIndexValue.getId());
	}
	
	@Override
	public String restatData(String itemid, String clock, String timegranid,String opuser) {
		TRmIndexItem t = tRmIndexItemMapper.selectByPrimaryKey(itemid);
		if(t==null){
			return "项目不存在，itemid：" + itemid;
		}
		Short digits =  t.getDigits()== null ? 2 : t.getDigits();
		if(timegranid.equalsIgnoreCase("DAY") && !t.getMintimegranid().equalsIgnoreCase("DAY")){
			return "最小粒度不匹配";
		} else {
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("timegranid", timegranid);
			params.put("itemid", itemid);
			params.put("clock", clock);
			try {
				// 获取原数据
				TRmIndexValue tv = tRmIndexValueMapper.selectByPrimaryKey(params);
				// 计算值
				Double  actualvalue= formulaService.getValByItemid(itemid, timegranid, clock, 0);
				// 参考值
				BigDecimal refvalue = new BigDecimal(Double.toString(actualvalue));
				// 上报指标-计算值波动算法
				if(t.getParentid().equalsIgnoreCase("NYDW001001") && timegranid.equalsIgnoreCase("MONTH")){
					// 波动关联对象
					String fluitemid = t.getFluitemid();
					Integer fluvalue = t.getFluvalue();
					if(fluvalue!=null){
						// 实绩波动系数,除100
						Double dfluvalue = BigDecimalUtil.divide(fluvalue.doubleValue(), 100d, 2).doubleValue();
						// 波动实绩值= 波动系数*(0~1随机数)*计算值
						Double fva = new BigDecimal(Math.random()).multiply(new BigDecimal(Double.toString(dfluvalue))).multiply(new BigDecimal(Double.toString(actualvalue))).doubleValue();
						if(fluitemid!=null && !fluitemid.isEmpty()){
							String fs = formulaService.getFormula(fluitemid, clock);
							if(fs!=null && fs.startsWith("R")){
								// 根据波动关联对象数据，确认是向上波动、向下波动
								Double dbdt = formulaService.readValByItemid(fluitemid, timegranid, clock, 0);
								Double dbdt2 = formulaService.readValByItemid(fluitemid, timegranid, "2020-02", 0);
								if(dbdt!=null && dbdt2!=null && actualvalue!=null){
									if(dbdt>dbdt2){
										actualvalue = BigDecimalUtil.add(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
									}else if(dbdt<dbdt2){
										actualvalue = BigDecimalUtil.sub(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
									}
								}
							}
						} else {
							// 随机波动
							Double rad = Math.random();
							if(rad>=0.5d){
								actualvalue = BigDecimalUtil.add(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
							}else{
								actualvalue = BigDecimalUtil.sub(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
							}
						}
					}
				}
				if(tv!=null){ // 做更新操作
					tv.setActualvalue(new BigDecimal(Double.toString(actualvalue)).setScale(digits, RoundingMode.HALF_UP));
		            tv.setApportvalue(BigDecimalUtil.add(tv.getCorrectvalue()!=null?tv.getCorrectvalue().doubleValue():0d, actualvalue).setScale(digits, RoundingMode.HALF_UP));
		            tv.setUpman(opuser);
		            tv.setRefvalue(refvalue);
		            tv.setUptime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		            tRmIndexValueMapper.updateByPrimaryKeySelective(tv);
				}else if(tv==null){
					tv = new TRmIndexValue();
					tv.setItemid(itemid);
					tv.setClock(clock);
					tv.setRefvalue(refvalue);
					tv.setTimegranid(timegranid);
					tv.setActualvalue(new BigDecimal(Double.toString(actualvalue)).setScale(digits, RoundingMode.HALF_UP));
					tv.setCorrectvalue(BigDecimal.ZERO);
					tv.setApportvalue(new BigDecimal(Double.toString(actualvalue)).setScale(digits, RoundingMode.HALF_UP));
					tv.setRecUser(opuser);
					tv.setRecTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
					tRmIndexValueMapper.insert(tv);
				}
			} catch (Exception e) {
				logger.error("计算错误：itemid-" + itemid + ",clock-" + clock);
				e.printStackTrace();
			}
		}
		// 上报指标-计算值波动算法
		if(t.getParentid().equalsIgnoreCase("NYDW001001") && timegranid.equalsIgnoreCase("MONTH")){
			formulaService.reCalculate(itemid, clock, timegranid, clock);
		}
		return null;
	}
	
	@Override
	public void statDataF() {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("useflag", "1");
		m.put("itemflag", "3");
		List<TRmIndexItem> l = tRmIndexItemMapper.selectByParasForFla(m);
		if(l!=null && l.size()>0){
			for(TRmIndexItem tRmIndexItem : l){
				String itemid = tRmIndexItem.getItemid();
				// 从最小粒度到年粒度计算
				Map<String, String> mp = new LinkedHashMap<String, String>();
				String mintimegranid = tRmIndexItem.getMintimegranid();
				if(mintimegranid.equalsIgnoreCase("DAY")){
					Calendar cal = Calendar.getInstance();
					cal.add(Calendar.DAY_OF_YEAR, -1); // 减1日获得昨天日期
					mp.put("DAY", new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime()));
					mp.put("MONTH", new SimpleDateFormat("yyyy-MM").format(cal.getTime()));
					mp.put("YEAR", new SimpleDateFormat("yyyy").format(cal.getTime()));
				}else if(mintimegranid.equalsIgnoreCase("MONTH")){
					mp.put("MONTH", new SimpleDateFormat("yyyy-MM").format(new Date()));
					mp.put("YEAR", new SimpleDateFormat("yyyy").format(new Date()));
				}
				HashMap<String, Object> id = new HashMap<String, Object>();
				id.put("itemid", itemid);
				Iterator<Entry<String, String>> it = mp.entrySet().iterator();
				while (it.hasNext()) {
		            Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
		            String timegranid = entry.getKey();
		            String clock = entry.getValue();
		            id.put("timegranid", timegranid);
		            id.put("clock", clock);
		            this.restatDataF(itemid, clock, timegranid, "系统");
		        }
			}
		}
	}
	
	@Override
	public String restatDataF(String itemid, String clock, String timegranid,String opuser) {
		TRmIndexItem t = tRmIndexItemMapper.selectByPrimaryKey(itemid);
		if(t==null){
			return "项目不存在，itemid：" + itemid;
		}
		Short digits =  t.getDigits()== null ? 2 : t.getDigits();
		if(timegranid.equalsIgnoreCase("DAY") && !t.getMintimegranid().equalsIgnoreCase("DAY")){
			return "最小粒度不匹配";
		} else {
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("timegranid", timegranid);
			params.put("itemid", itemid);
			params.put("clock", clock);
			try {
				// 获取原数据
				TRmIndexValue tv = tRmIndexValueMapper.selectByPrimaryKey(params);
				// 计算值
				Double  actualvalue= formulaService.getValByItemid(itemid, timegranid, clock, 0);
				// 参考值
				BigDecimal refvalue = new BigDecimal(Double.toString(actualvalue));
				// 上报指标-计算值波动算法
				if(t.getParentid().equalsIgnoreCase("NYDF001001") && timegranid.equalsIgnoreCase("MONTH")){
					// 波动关联对象
					String fluitemid = t.getFluitemid();
					Integer fluvalue = t.getFluvalue();
					if(fluvalue!=null){
						// 实绩波动系数,除100
						Double dfluvalue = BigDecimalUtil.divide(fluvalue.doubleValue(), 100d, 2).doubleValue();
						// 波动实绩值= 波动系数*(0~1随机数)*计算值
						Double fva = new BigDecimal(Math.random()).multiply(new BigDecimal(Double.toString(dfluvalue))).multiply(new BigDecimal(Double.toString(actualvalue))).doubleValue();
						if(fluitemid!=null && !fluitemid.isEmpty()){
							String fs = formulaService.getFormula(fluitemid, clock);
							if(fs!=null && fs.startsWith("R")){
								// 根据波动关联对象数据，确认是向上波动、向下波动
								Double dbdt = formulaService.readValByItemid(fluitemid, timegranid, clock, 0);
								Double dbdt2 = formulaService.readValByItemid(fluitemid, timegranid, "2020-02", 0);
								if(dbdt!=null && dbdt2!=null && actualvalue!=null){
									if(dbdt>dbdt2){
										actualvalue = BigDecimalUtil.add(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
									}else if(dbdt<dbdt2){
										actualvalue = BigDecimalUtil.sub(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
									}
								}
							}
						} else {
							// 随机波动
							Double rad = Math.random();
							if(rad>=0.5d){
								actualvalue = BigDecimalUtil.add(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
							}else{
								actualvalue = BigDecimalUtil.sub(actualvalue, fva).setScale(digits, RoundingMode.HALF_UP).doubleValue();
							}
						}
					}
				}
				if(tv!=null){ // 做更新操作
					tv.setActualvalue(new BigDecimal(Double.toString(actualvalue)).setScale(digits, RoundingMode.HALF_UP));
		            tv.setApportvalue(BigDecimalUtil.add(tv.getCorrectvalue()!=null?tv.getCorrectvalue().doubleValue():0d, actualvalue).setScale(digits, RoundingMode.HALF_UP));
		            tv.setUpman(opuser);
		            tv.setRefvalue(refvalue);
		            tv.setUptime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		            tRmIndexValueMapper.updateByPrimaryKeySelective(tv);
				}else if(tv==null){
					tv = new TRmIndexValue();
					tv.setItemid(itemid);
					tv.setClock(clock);
					tv.setRefvalue(refvalue);
					tv.setTimegranid(timegranid);
					tv.setActualvalue(new BigDecimal(Double.toString(actualvalue)).setScale(digits, RoundingMode.HALF_UP));
					tv.setCorrectvalue(BigDecimal.ZERO);
					tv.setApportvalue(new BigDecimal(Double.toString(actualvalue)).setScale(digits, RoundingMode.HALF_UP));
					tv.setRecUser(opuser);
					tv.setRecTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
					tRmIndexValueMapper.insert(tv);
				}
			} catch (Exception e) {
				logger.error("计算错误：itemid-" + itemid + ",clock-" + clock);
				e.printStackTrace();
			}
		}
		// 上报指标-计算值波动算法
		if(t.getParentid().equalsIgnoreCase("NYDF001001") && timegranid.equalsIgnoreCase("MONTH")){
			formulaService.reCalculate(itemid, clock, timegranid, clock);
		}
		return null;
	}


	@Override
	public PageList<Map<String, Object>> getIndexData(HashMap<String, Object> parmas, Integer pageNum,
			Integer pageSize) {
		PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> tRmIndexValues = tRmIndexValueMapper.getIndexData(parmas);
        PageList<Map<String, Object>> pageInfo = new PageList<Map<String, Object>>(tRmIndexValues);
		return pageInfo;
	}

	@Override
	public List<Map<String, Object>> chtResult5(HashMap<String, Object> parmas) {
		return tRmIndexValueMapper.chtResult5(parmas);
	}

	@Override
	public List<Map<String, Object>> chtResult6(HashMap<String, Object> parmas) {
		return tRmIndexValueMapper.chtResult6(parmas);
	}

	@Override
	public List<Map<String, Object>> chtResult7(HashMap<String, Object> parmas) {
		return tRmIndexValueMapper.chtResult7(parmas);
	}

	@Override
	public List<Map<String, Object>> chtResult10(HashMap<String, Object> parmas) {
		return tRmIndexValueMapper.chtResult10(parmas);
	}
}
