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

import com.steerinfo.auth.utils.JwtUtil;
import com.steerinfo.ems.Utils.BigDecimalUtil;
import com.steerinfo.ems.Utils.DateUtils;
import com.steerinfo.ems.Utils.TimegranidUtils;
import com.steerinfo.ems.common.DateTypeEnum;
import com.steerinfo.ems.formula.service.IFormulaService;
import com.steerinfo.ems.trmactitem.model.TRmActItem;
import com.steerinfo.ems.trmactitem.service.ITRmActItemService;
import com.steerinfo.ems.trmplanvalue.service.ITRmPlanValueService;
import com.steerinfo.ems.trmworkprocproductvalue.service.ITRmWorkprocProductValueService;
import com.steerinfo.framework.mapper.IBaseMapper;
import com.steerinfo.framework.service.impl.BaseServiceImpl;
import com.steerinfo.framework.service.pagehelper.PageHelper;
import com.steerinfo.framework.service.pagehelper.PageList;
import com.steerinfo.ems.trmactvalue.model.TRmActValue;
import com.steerinfo.ems.trmactvalue.mapper.TRmActValueMapper;
import com.steerinfo.ems.trmactvalue.service.ITRmActValueService;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

    @Autowired
    private IFormulaService formulaService;

    @Autowired
    private ITRmActItemService tRmActItemService;
    @Autowired
    private ITRmWorkprocProductValueService tRmWorkprocProductValueService;
    @Autowired
    ITRmPlanValueService tRmPlanValueService;

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

    @Override
    public PageList<Map<String, Object>> getDate611ForPage(Map<String, Object> parameters, Integer pageNum,
                                                           Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> rows = tRmActValueMapper.getDate611(parameters);
        PageList<Map<String, Object>> pageInfo = new PageList<Map<String, Object>>(rows);
        return pageInfo;
    }

    @Override
    public List<Map<String, Object>> getDate6121ForPage(HashMap<String, Object> parmas, Integer pageNum,
                                                            Integer pageSize) {
        List<Map<String, Object>> rows = tRmActValueMapper.getDate6121(parmas);
        return rows;
    }

    @Override
    public List<Map<String, Object>> getDate6122ForPage(HashMap<String, Object> parmas, Integer pageNum,
                                                            Integer pageSize) {
        List<Map<String, Object>> rows = tRmActValueMapper.getDate6122(parmas);
        return rows;
    }

    @Override
    public Double getSumvalue(HashMap<String, Object> params) {
        return tRmActValueMapper.getSumvalue(params);
    }

    @Override
    public int insert(TRmActValue tRmActValue) {
        return tRmActValueMapper.insert(tRmActValue);
    }

    @Override
    public Double getTRmActValue(HashMap<String, Object> params) {
        return tRmActValueMapper.getTRmActValue(params);
    }

    /**
     *  最小粒度为天的定时任务
     */
    @Override
    public void StateTimegranidforDay() {
        List<TRmActItem> tRmActItemsDay = tRmActItemService.getforsj("DAY");
		this.getTRmActValueByFormula(tRmActItemsDay, DateTypeEnum.getMethod("yesterday").getDate(), "DAY");
		this.getMonthRmActValue(tRmActItemsDay);
		this.getYearRmActValue(tRmActItemsDay);
        logger.info("供需实绩粒度为天定时任务结束......");
    }

    /**
     * 最小粒度为月的定时任务
     */
    @Override
    public void StateTimegranidforMonth() {
        List<TRmActItem> tRmActItemsMonth = tRmActItemService.getforsj("MONTH");
        this.getTRmActValueByFormula(tRmActItemsMonth,DateTypeEnum.getMethod("thisMonth").getDate(),"MONTH");
        this.getYearRmActValue(tRmActItemsMonth);
        logger.info("供需实绩粒度为月定时任务结束......");
    }

    @Override
    public Map<String, Object> getMonthOutPut(HashMap<String, Object> params) {
        return tRmActValueMapper.getMonthOutPut(params);
    }

    /**
     * 获取数据到能耗实绩确认表
     * @param
     * @return
     */
    @Override
    public List<Map<String,Object>> getUploadData(){
        return tRmActValueMapper.getUploadData();
    }

    @Override
    public void updateFid(TRmActValue model){
        tRmActValueMapper.updateFid(model);
    }

    /**
     * 通过Fid获取实绩项目数据
     * @param
     */
    @Override
    public List<Map<String,Object>> getByFid(Long fid){
        return tRmActValueMapper.getByFid(fid);
    }

    /**
     * 计算累计值(月时间粒度的计算值为当月日累计值)
     * 
     * @param itemid 项目ID
     * @param clock 累计值来源时间
     * @param timegranid 累计值来源时间粒度
     * @return
     */
    public Double getSumvalue(String itemid,String clock,String timegranid) {
        HashMap<String, Object> maps = new HashMap<>();
        maps.put("itemid", itemid);
        maps.put("clock", clock);
        maps.put("timegranid", timegranid);
        Double sumvalue = tRmActValueMapper.getSumvalue(maps);
        if(null == sumvalue) {
            return 0.0;
        }
        return sumvalue;
    }

    /**
     * 通过公式，实绩项目数据录入（Timegranid为最小时间粒度时候用该方法）
     * 
     * @param tRmActItems 实绩项目
     * @param clock 时间
     * @param Timegranid 时间粒度
     */
    public void getTRmActValueByFormula(List<TRmActItem> tRmActItems,String clock,String Timegranid) {
        for (TRmActItem tRmActItem : tRmActItems) {
        	HashMap<String, Object> id = new HashMap<String, Object>();
    		id.put("clock", clock);
    		id.put("timegranid", Timegranid);
    		id.put("itemid", tRmActItem.getItemid());
    		// 数据是否已存在
    		TRmActValue t = tRmActValueMapper.selectByPrimaryKey(id);
			if(t!=null){
				logger.error("原数据已存在：" + clock + ",itemid:"+ tRmActItem.getItemid());
				continue;
			}
			Short digits = tRmActItem.getDigits() == null ? 2 : tRmActItem.getDigits();
            // 折标系数
            Double zbxs = formulaService.getValByItemid(tRmActItem.getEnergyid(),Timegranid, clock, 0);
            if (zbxs==null){
                zbxs=0.0;
            }
            Double actualvalue = formulaService.getValByItemid(tRmActItem.getItemid(), Timegranid, clock, 0);
			// if(actualvalue<0){
			// actualvalue=0.0;
			// logger.info("id为"+tRmActItem.getItemid()+"计算错误");
			// }
            TRmActValue tRmActValue = new TRmActValue();
            tRmActValue.setItemid(tRmActItem.getItemid());
            tRmActValue.setClock(clock);
            tRmActValue.setTimegranid(Timegranid);
            //计算值
            tRmActValue.setActualvalue(new BigDecimal(actualvalue));
            //修正值
            tRmActValue.setCorrectvalue(new BigDecimal(0));
            //最终值
            tRmActValue.setApportvalue(new BigDecimal(actualvalue));
            //折标值
            tRmActValue.setStdvalue(BigDecimalUtil.mul(zbxs, actualvalue));
            Map<String, BigDecimal> dh = tRmWorkprocProductValueService.getOutPut(tRmActItem.getWorkprocid(),clock, Timegranid,"R");
            //实绩产量
            Double  sjcl  = dh.get("SJCL").doubleValue();
            //单耗值
            tRmActValue.setUcvalue(BigDecimalUtil.divide(actualvalue, sjcl, digits.intValue()));
            ////累计产量
            // Double  ljcl = dh.get("LJCL").doubleValue();
            //BigDecimal  sumvalue = BigDecimalUtil.add(sumvalueActualvalue, actualvalue);
            //Double doubleValue = sumvalue.doubleValue();
            //累计值
            //tRmActValue.setSumvalue(sumvalue);
            //折标累计值
            //tRmActValue.setSumstdvalue(BigDecimalUtil.mul(doubleValue, zbxs));
            //累计单耗值
            //tRmActValue.setSumucvalue(BigDecimalUtil.divide(doubleValue, ljcl, digits.intValue()));
            //logger.info("id为:"+tRmActItem.getItemid()+"的累计产量为"+ljcl +"   "+clock);
            tRmActValue.setRecTime(DateUtils.dateStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
            //修改次数
            tRmActValue.setModifyflag(new Short("0"));
            tRmActValueMapper.insert(tRmActValue);
        }
        //tRmActValueMapper.batchInsert(tRmActValues);
    }

    /**
     * 月粒度数据录入（日数据累加）
     * @param tRmActItems 项目
     */
    public void getMonthRmActValue(List<TRmActItem> tRmActItems) {
        if(DateTypeEnum.getMethod("dm").getDate().equals("1")){
            for (TRmActItem tRmActItem : tRmActItems) {
            	HashMap<String, Object> id = new HashMap<String, Object>();
        		id.put("clock", DateTypeEnum.getMethod("lastMonth").getDate());
        		id.put("timegranid", "MONTH");
        		id.put("itemid", tRmActItem.getItemid());
        		// 数据是否已存在
        		TRmActValue t = tRmActValueMapper.selectByPrimaryKey(id);
    			if(t!=null){
    				logger.error("原数据已存在：" + DateTypeEnum.getMethod("lastMonth").getDate() + ",itemid:"+ tRmActItem.getItemid());
    				continue;
    			}
    			Short digits = tRmActItem.getDigits() == null ? 2 : tRmActItem.getDigits();
            	TRmActValue MonthtRmActValue = new TRmActValue();
                MonthtRmActValue.setItemid(tRmActItem.getItemid());
                MonthtRmActValue.setClock(DateTypeEnum.getMethod("lastMonth").getDate());
                MonthtRmActValue.setTimegranid("MONTH");
                //获取计算值(上月数据累加)
                Double MonthActualvalue = this.getSumvalue(tRmActItem.getItemid(),DateTypeEnum.getMethod("lastMonth").getDate(),"DAY");
//                if(MonthActualvalue<0){
//                    MonthActualvalue=0.0;
//                    logger.info("id为"+tRmActItem.getItemid()+"计算错误");
//                }
                MonthtRmActValue.setActualvalue(new BigDecimal(MonthActualvalue));
                //获取月实绩产量和月累计产量
                Map<String, BigDecimal> monthOutPut = tRmWorkprocProductValueService.getOutPut(tRmActItem.getWorkprocid(), DateTypeEnum.getMethod("lastMonth").getDate(), "MONTH", "R");
                //获取月实绩产量
                Double Monthsjcl = monthOutPut.get("SJCL").doubleValue();
                //获取月实绩累计量
                //Double  Monljcl = monthOutPut.get("LJCL").doubleValue();
                MonthtRmActValue.setApportvalue(new BigDecimal(MonthActualvalue));
                // 折标系数
                Double zbxs = formulaService.getValByItemid(tRmActItem.getEnergyid(),"MONTH", DateTypeEnum.getMethod("yesterday").getDate(), 0);
                if (zbxs==null){
                    zbxs=0.0;
                }
                //折标值
                MonthtRmActValue.setStdvalue(BigDecimalUtil.mul(MonthActualvalue, zbxs));
                //单耗值
                MonthtRmActValue.setSumucvalue(BigDecimalUtil.divide(MonthActualvalue, Monthsjcl, digits.intValue()));
                //修正值
                MonthtRmActValue.setCorrectvalue(new BigDecimal(0));
                //累计值
                //Double sumvalue2 = this.getSumvalue(tRmActItem.getItemid(), DateTypeEnum.getMethod("thisYear").getDate(), "MONTH");
                //if(DateTypeEnum.getMethod("dy").getDate().equals("1")){
                //    sumvalue2 = this.getSumvalue(tRmActItem.getItemid(), DateTypeEnum.getMethod("lastYear").getDate(), "MONTH");
                //}
                //BigDecimal add = BigDecimalUtil.add(MonthActualvalue, sumvalue2);
                //Double  Monthsumvalue = add.doubleValue();
                //累计值
                //MonthtRmActValue.setSumvalue(add);
                //累计折标值
                //MonthtRmActValue.setSumstdvalue(BigDecimalUtil.mul(Monthsumvalue, zbxs));
                //累计单耗值
                //MonthtRmActValue.setSumucvalue(BigDecimalUtil.divide(Monthsumvalue, Monljcl, 3));
                //记录创建时间
                MonthtRmActValue.setRecTime(DateUtils.dateStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
                //修改次数
                MonthtRmActValue.setModifyflag(new Short("0"));
                tRmActValueMapper.insert(MonthtRmActValue);
            }
        }
    }

    /**
     * 年粒度数据录入（月数据累加）
     * 
     * @param tRmActItems
     */
    public void getYearRmActValue(List<TRmActItem> tRmActItems) {
        if(DateTypeEnum.getMethod("dy").getDate().equals("1")){
            for (TRmActItem tRmActItem : tRmActItems) {
            	HashMap<String, Object> id = new HashMap<String, Object>();
        		id.put("clock", DateTypeEnum.getMethod("lastYear").getDate());
        		id.put("timegranid", "YEAR");
        		id.put("itemid", tRmActItem.getItemid());
        		// 数据是否已存在
        		TRmActValue t = tRmActValueMapper.selectByPrimaryKey(id);
    			if(t!=null){
    				logger.error("原数据已存在：" + DateTypeEnum.getMethod("lastYear").getDate() + ",itemid:"+ tRmActItem.getItemid());
    				continue;
    			}
            	TRmActValue YeartRmActValue = new TRmActValue();
                //年累计
                YeartRmActValue.setItemid(tRmActItem.getItemid());
                YeartRmActValue.setClock(DateTypeEnum.getMethod("lastYear").getDate());
                YeartRmActValue.setTimegranid("YEAR");
                //获取计算值
                Double YearActualvalue = this.getSumvalue(tRmActItem.getItemid(), DateTypeEnum.getMethod("lastYear").getDate(), "MONTH");
                YeartRmActValue.setActualvalue(new BigDecimal(YearActualvalue));
                //修正值
                YeartRmActValue.setCorrectvalue(new BigDecimal(0));
                //最终值
                YeartRmActValue.setApportvalue(new BigDecimal(YearActualvalue));
                Map<String, BigDecimal> monthOutPut = tRmWorkprocProductValueService.getOutPut(tRmActItem.getWorkprocid(), DateTypeEnum.getMethod("lastYear").getDate(), "YEAR","R");
                Double bigDecimal = monthOutPut.get("SJCL").doubleValue();
                // 折标系数
                Double zbxs = formulaService.getValByItemid(tRmActItem.getEnergyid(),"MONTH", DateTypeEnum.getMethod("yesterday").getDate(), 0);
                if (zbxs==null){
                    zbxs=0.0;
                }
                //折标值
                YeartRmActValue.setStdvalue(BigDecimalUtil.mul(YearActualvalue, zbxs));
                //记录创建时间
                YeartRmActValue.setRecTime(DateTypeEnum.getMethod("thisYear").getDate());
                //年单耗值
                YeartRmActValue.setUcvalue(BigDecimalUtil.divide(YearActualvalue, bigDecimal, 3));
                //修改次数
                YeartRmActValue.setModifyflag(new Short("0"));
                tRmActValueMapper.insert(YeartRmActValue);
            }
        }
    }

	@Override
	/**
	 *  每日数据统计（实绩定时任务、计划定时任务，根据项目生成日、月、年粒度数据）
	 */
	public void statDataforDay() {
		//获取实绩项目
        List<TRmActItem> rs = tRmActItemService.getitems("R");
        
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_YEAR, -1); // 减1天昨天
        String clockd = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        c.add(Calendar.DAY_OF_YEAR, 1); // 回到今天
        c.add(Calendar.MONTH, -1); // 减1月获得上月
        String clockm = new SimpleDateFormat("yyyy-MM").format(c.getTime());
        c.add(Calendar.MONTH, 1); // 回到当前月
        c.add(Calendar.YEAR, -1); // 去年
        String clocky = new SimpleDateFormat("yyyy").format(c.getTime());
        c.add(Calendar.YEAR, 1); // 回到现在
        // 生成昨日数据
		for (TRmActItem tRmActItem : rs) {
			if(tRmActItem.getMintimegranid().equalsIgnoreCase("DAY")) {
				this.restatData(tRmActItem.getItemid(), clockd, "DAY", "系统");
			}
		}
		// 每月前5天生成上月数据
		if(c.get(Calendar.DAY_OF_MONTH) <= 5){
			for (TRmActItem tRmActItem : rs) {
				this.restatData(tRmActItem.getItemid(), clockm, "MONTH", "系统");
			}
		}
		// 每年前5天生成去年数据
		if(c.get(Calendar.DAY_OF_YEAR) <= 5){
			for (TRmActItem tRmActItem : rs) {
				this.restatData(tRmActItem.getItemid(), clocky, "YEAR", "系统");
			}
		}
		tRmPlanValueService.state();
	}

	@Override
	public String restatData(String itemid, String clock, String timegranid, String opuser) {
		if(!itemid.endsWith("R")){
			return "项目编号错误";
		}
		TRmActItem t = tRmActItemService.getById(itemid);
		if(t!=null){
			Short digits = t.getDigits() == null ? 2 : t.getDigits();
			Short digits2 = digits < 2 ? 2 : digits; // 单耗精度最少为2
			HashMap<String, Object> id = new HashMap<String, Object>();
    		id.put("clock", clock);
    		id.put("timegranid", timegranid);
    		id.put("itemid", itemid);
            // 计算值
            Double actualvalue = 0d;
            if(!TimegranidUtils.getTimegranidList(t.getMintimegranid()).contains(timegranid.toUpperCase())){
            	return "时间粒度错误";
            }else if(t.getMintimegranid().equalsIgnoreCase(timegranid)){
				actualvalue = formulaService.getValByItemid(itemid, timegranid, clock, 0);
			}else{
				// 此时计算值为小粒度累加
				HashMap<String, Object> maps = new HashMap<>();
            	if(timegranid.equalsIgnoreCase("MONTH")){
    	            maps.put("itemid", itemid);
    	            maps.put("clock", clock);
    	            maps.put("timegranid", "DAY");
            	}else if(timegranid.equalsIgnoreCase("YEAR")){
            		maps.put("itemid", itemid);
    	            maps.put("clock", clock);
    	            maps.put("timegranid", "MONTH");
            	}
            	actualvalue = tRmActValueMapper.getSumvalue(maps);
			}
            // 折标系数
            Double zbxs = formulaService.getValByItemid(t.getEnergyid(),timegranid, clock, 0);
            if (zbxs==null){
                zbxs=0.0;
            }
            Map<String, BigDecimal> dh = tRmWorkprocProductValueService.getOutPut(t.getWorkprocid(),clock, timegranid,"R");
            //实绩产量
            Double  sjcl  = dh.get("SJCL").doubleValue();
            //累计产量
            // Double  ljcl = dh.get("LJCL").doubleValue();
    		// 数据是否已存在
    		TRmActValue tv = tRmActValueMapper.selectByPrimaryKey(id);
    		try {
    			if(tv!=null){
    	            tv.setActualvalue(new BigDecimal(actualvalue));
    	            tv.setApportvalue(BigDecimalUtil.add(tv.getCorrectvalue()!=null?tv.getCorrectvalue().doubleValue():0d, actualvalue).setScale(digits, BigDecimal.ROUND_HALF_UP));
    	            // 折标值
    	            tv.setStdvalue(BigDecimalUtil.mul(zbxs, tv.getApportvalue().doubleValue()).setScale(digits, BigDecimal.ROUND_HALF_UP));
    	            //单耗值
    	            tv.setUcvalue(BigDecimalUtil.divide(tv.getApportvalue().doubleValue(), sjcl, digits2.intValue()));
    	            tv.setUptime(DateUtils.dateStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
    	            tv.setUserid(opuser);
    	            tRmActValueMapper.updateByPrimaryKeySelective(tv);
    			}else{
    	            TRmActValue tRmActValue = new TRmActValue();
    	            tRmActValue.setItemid(itemid);
    	            tRmActValue.setClock(clock);
    	            tRmActValue.setTimegranid(timegranid);
    	            //计算值
    	            tRmActValue.setActualvalue(new BigDecimal(actualvalue));
    	            //修正值
    	            tRmActValue.setCorrectvalue(new BigDecimal(0));
    	            //最终值
    	            tRmActValue.setApportvalue(new BigDecimal(actualvalue));
    	            //折标值
    	            tRmActValue.setStdvalue(BigDecimalUtil.mul(zbxs, actualvalue).setScale(digits, BigDecimal.ROUND_HALF_UP));
    	            //单耗值
    	            tRmActValue.setUcvalue(BigDecimalUtil.divide(actualvalue, sjcl, digits2.intValue()));
    	            tRmActValue.setCrman(opuser);
    	            tRmActValue.setRecTime(DateUtils.dateStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
    	            //修改次数
    	            // tRmActValue.setModifyflag(new Short("0"));
    	            tRmActValueMapper.insert(tRmActValue);
    			}
    		} catch (Exception e) {
				logger.error("实绩数据计算错误：itemid-" + itemid + ",clock-" + clock);
				logger.error("--:" + e.getMessage());
				e.printStackTrace();
			}
		}
		return null;
	}

	@Override
	public int getCount(Map<String, Object> params) {
		return tRmActValueMapper.getCount(params);
	}
}
