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

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.trmplanvalue.model.TRmPlanValue;
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.model.Formula;
import com.steerinfo.ems.formula.service.IFormulaService;
import com.steerinfo.ems.tpmcase.model.TPmCase;
import com.steerinfo.ems.tpmcase.service.TPmCaseService;
import com.steerinfo.ems.tpmcaseact.service.ITPmCaseActService;
import com.steerinfo.ems.trmactitem.model.TRmActItem;
import com.steerinfo.ems.trmactitem.service.ITRmActItemService;
import com.steerinfo.ems.trmactvalue.model.TRmActValue;
import com.steerinfo.ems.trmactvalue.service.ITRmActValueService;
import com.steerinfo.ems.trmbalancevalue.model.TRmBalanceValue;
import com.steerinfo.ems.trmbalancevalue.service.ITRmBalanceValueService;
import com.steerinfo.ems.trmplanvalue.mapper.TRmPlanValueMapper;
import com.steerinfo.ems.trmplanvalue.service.ITRmPlanValueService;
import com.steerinfo.ems.trmworkprocproductvalue.service.ITRmWorkprocProductValueService;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
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.Service;

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

    @Autowired
    private TRmPlanValueMapper tRmPlanValueMapper;
    
    @Autowired
    private IFormulaService formulaService;
    
    @Autowired
    private ITRmWorkprocProductValueService tRmWorkprocProductValueService;
    
    @Autowired
    private ITRmActItemService tRmActItemService;
    
    @Autowired
    private TPmCaseService tPmCaseService;
    
    @Autowired
    ITPmCaseActService tPmCaseActService;
    
    @Autowired
    ITRmActValueService tRmActValueService;
    @Autowired
    ITRmBalanceValueService tRmBalanceValueService;
    @Autowired
    ITRmPlanValueService tRmPlanValueService;
    
    @Override
    protected IBaseMapper<TRmPlanValue, HashMap<String, Object>> getMapper() {
        return tRmPlanValueMapper;
    }

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

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

	@Override
	public List<Map<String, Object>> getDate6231ForPage(HashMap<String, Object> parmas, Integer pageNum,
			Integer pageSize) {
		// PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> rows = tRmPlanValueMapper.getDate6231(parmas);
        // PageList<Map<String, Object>> pageInfo = new PageList<Map<String, Object>>(rows);
        return rows;
	}

	@Override
	public List<Map<String, Object>> getDate6232ForPage(HashMap<String, Object> parmas, Integer pageNum,
			Integer pageSize) {
		// PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> rows = tRmPlanValueMapper.getDate6232(parmas);
        // PageList<Map<String, Object>> pageInfo = new PageList<Map<String, Object>>(rows);
        return rows;
	}
	
    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 = tRmPlanValueMapper.getSumvalue(maps);
    	if(null == sumvalue) {
    		return 0.0;
    	}
    	return sumvalue;
    }

    @Override
    public void state() {
    	List<TRmActItem> items = tRmActItemService.getitems("P");
    	for (TRmActItem tRmActItem : items) {
    		String mintimegranid = tRmActItem.getMintimegranid();
    		if (mintimegranid.equalsIgnoreCase("DAY")) {
    			this.restatData(tRmActItem.getItemid(), new SimpleDateFormat("yyyy-MM-dd").format(new Date()), "DAY");
    			// 每月最后一天生成本月月计划数据
    			Calendar cal = Calendar.getInstance();
    			if(cal.get(Calendar.DAY_OF_MONTH) == cal.getActualMaximum(Calendar.DAY_OF_MONTH)){
    				this.restatData(tRmActItem.getItemid(), new SimpleDateFormat("yyyy-MM").format(new Date()), "MONTH");
    			}
    			// 12月31日生成年计划数据
    			if(new SimpleDateFormat("MM-dd").format(new Date()).equals("12-31")){
    				this.restatData(tRmActItem.getItemid(), new SimpleDateFormat("yyyy").format(new Date()), "YEAR");
    			}
    		}
    		if(mintimegranid.equalsIgnoreCase("MONTH")){
    			if(DateTypeEnum.getMethod("dm").getDate().equals("1")){
    				this.restatData(tRmActItem.getItemid(), new SimpleDateFormat("yyyy-MM").format(new Date()), "MONTH");
    			}
    			// 12月1日生成年计划数据
    			if(new SimpleDateFormat("MM-dd").format(new Date()).equals("12-01")){
    				this.restatData(tRmActItem.getItemid(), new SimpleDateFormat("yyyy").format(new Date()), "YEAR");
    			}
    		}
    		// 年粒度，最小粒度为年的第1天计算，其他12月1日统计
    		if(mintimegranid.equalsIgnoreCase("YEAR") && DateTypeEnum.getMethod("dy").getDate().equals("1")){
    			this.restatData(tRmActItem.getItemid(), new SimpleDateFormat("yyyy").format(new Date()), "YEAR");
    		}
		}
    }

    @Override
    public TRmPlanValue updateForUKey(TRmPlanValue tRmPlanValue) {
        this.getMapper().updateByPrimaryKeySelective(tRmPlanValue);
        return tRmPlanValueMapper.selectByUPrimaryKey(tRmPlanValue);
    }

	@Override
	public String restatData(String itemid, String clock, String timegranid) {
		if(!itemid.endsWith("P")){
			return "项目编号错误";
		}
		TRmActItem t = tRmActItemService.getById(itemid);
		if(t!=null){
			Short digits = t.getDigits() == null ? 2 : t.getDigits();
			HashMap<String, Object> id = new HashMap<String, Object>();
    		id.put("clock", clock);
    		id.put("timegranid", timegranid);
    		id.put("itemid", itemid);
    		// 需要统计的时间粒度
    		if(!TimegranidUtils.getTimegranidList(t.getMintimegranid()).contains(timegranid.toUpperCase())){
            	return "时间粒度错误";
            }else{
            	try {
	            	// 折标系数
	                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,"P");
	                // 计划产量
	                BigDecimal cl = dh.get("SJCL");
	                // 如果没有计划产量，取上一阶段实绩产量
	                if(cl.doubleValue() == 0){
	                	Calendar cal = Calendar.getInstance();
	                	String clockr = "";
	                	if(timegranid.equalsIgnoreCase("DAY")){
	                		cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(clock));
	                		cal.add(Calendar.DAY_OF_YEAR, -1);
	                		clockr = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
	                	}else if(timegranid.equalsIgnoreCase("MONTH")){
	                		cal.setTime(new SimpleDateFormat("yyyy-MM").parse(clock));
	                		cal.add(Calendar.MONTH, -1);
	                		clockr = new SimpleDateFormat("yyyy-MM").format(cal.getTime());
	                	}else if(timegranid.equalsIgnoreCase("YEAR")){
	                		cal.setTime(new SimpleDateFormat("yyyy").parse(clock));
	                		cal.add(Calendar.YEAR, -1);
	                		clockr = new SimpleDateFormat("yyyy").format(cal.getTime());
	                	}
	                	cl = tRmWorkprocProductValueService.getOutPut(t.getWorkprocid(),clockr, timegranid,"R").get("SJCL");
	                }
	                // 单耗
                	BigDecimal ucvalue = null;
	                // 计算值(能介使用量)
	                Double actualvalue = 0d;
	            	// 此时计算值为小粒度累加
	                if(!t.getMintimegranid().equalsIgnoreCase(timegranid)){
	                	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 = tRmPlanValueMapper.getSumvalue(maps);
	                	ucvalue = BigDecimalUtil.divide(actualvalue, cl.doubleValue(), digits.intValue());
	                }else{
	                	// 如果有公式，用公式计算，否则用计划方案计算
	                	HashMap<String, Object> parmas = new HashMap<>();
	                	parmas.put("code", itemid);
	                	parmas.put("clock", clock);
	                	// 获取公式
	                	Formula formula = formulaService.getFormulaCodeClock(parmas);
	                	if(formula!=null && !formula.getSourcecode().startsWith("R")){
	                		actualvalue = formulaService.getValByItemid(itemid, timegranid, clock, 0);
	                	}else{
	                		// 根据计划方案计算
		                	String caseConfig = "";
		                	// 获取计划项目的计划方案
		                	// TODO 这里的计划方案，时间类型只有一种（上一周期），如果添加其他方案，此方法要做相应改动。
		                	TPmCase tpm = tPmCaseService.getTPmCaseByItemId(itemid, timegranid);
		                	if(tpm!=null){
		                		caseConfig = tpm.getCaseConfig();
		                	}else{
		                		// 获取默认计划方案
		                		tpm = tPmCaseService.getTPmCaseDef();
		                		if(tpm!=null && tpm.getIsAp().equalsIgnoreCase(timegranid)){
		                			caseConfig = tpm.getCaseConfig();
		                		}else{
		                			logger.error("计划项目-itemid:" + itemid + ",clock:" + clock + "没有计划方案");
		                			return "";
		                		}
		                	}
		                	String[] cc = caseConfig.split("\\|");
		                	if(cc.length<6 || !cc[3].equalsIgnoreCase("0")){
		                		logger.error("计划项目-itemid:" + itemid + ",clock:" + clock + "方案信息错误");
		            			return "";
		                	}
		                	String res = cc[0].trim(); // 数据来源
		                	String timegranid2 = cc[1].trim(); // 时间粒度
		                	String clock2 = ""; // 时间
		                	int off = -Integer.valueOf(cc[cc.length - 1]); // 上（）月
		                	if(timegranid2.equalsIgnoreCase(timegranid)){
		                		Calendar cal = Calendar.getInstance();
			                	if(timegranid2.equalsIgnoreCase("DAY")){
			                		cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(clock));
			                		cal.add(Calendar.DAY_OF_YEAR, off);
			                		clock2 = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
			                	}else if(timegranid2.equalsIgnoreCase("MONTH")){
			                		cal.setTime(new SimpleDateFormat("yyyy-MM").parse(clock));
			                		cal.add(Calendar.MONTH, off);
			                		clock2 = new SimpleDateFormat("yyyy-MM").format(cal.getTime());
			                	}else if(timegranid2.equalsIgnoreCase("YEAR")){
			                		cal.setTime(new SimpleDateFormat("yyyy").parse(clock));
			                		cal.add(Calendar.YEAR, off);
			                		clock2 = new SimpleDateFormat("yyyy").format(cal.getTime());
			                	}
		                	}
		                	// 项目ID
		                	Map<String,Object> params =  new HashMap<>();
		                    params.put("energyid", t.getEnergyid());
		                    params.put("workprocid", t.getWorkprocid());
		                    params.put("propertyid", t.getPropertyid());
		                    params.put("useflag", "1" );
		                    // 数据ID
		    				HashMap<String, Object> vid = new HashMap<String, Object>();
		    				vid.put("clock", clock2);
		    				vid.put("timegranid", timegranid2);
		                	if(res.equalsIgnoreCase("T_RM_ACT_VALUE")){
		                		params.put("itemtype", "R" );
		                		TRmActItem ta = tRmActItemService.getByParams(params);
		                		if(ta!=null){
		                			vid.put("itemid", ta.getItemid());
		                			TRmActValue tRmActValue = tRmActValueService.getById(vid);
		                			if(tRmActValue!=null && tRmActValue.getUcvalue()!=null){
		                				ucvalue = tRmActValue.getUcvalue();
		                			}
		                		}
		                	}else if(res.equalsIgnoreCase("T_RM_BALANCE_VALUE")){
		                		params.put("itemtype", "B" );
		                		TRmActItem ta = tRmActItemService.getByParams(params);
		                		if(ta!=null){
		                			vid.put("itemid", ta.getItemid());
		                			TRmBalanceValue tRmBalanceValue = tRmBalanceValueService.getById(vid);
		                			if(tRmBalanceValue!=null && tRmBalanceValue.getUcvalue()!=null){
		                				ucvalue = tRmBalanceValue.getUcvalue();
		                			}
		                		}
		                	}else if(res.equalsIgnoreCase("T_RM_PLAN_VALUE")){
		                		vid.put("itemid", itemid);
		                		TRmPlanValue tRmPlanValue = tRmPlanValueService.getById(vid);
		                		if(tRmPlanValue!=null && tRmPlanValue.getUcvalue()!=null){
		            				ucvalue = tRmPlanValue.getUcvalue();
		            			}
		                	}
		                	if(ucvalue!=null){
		                		actualvalue = ucvalue.multiply(cl).setScale(digits, BigDecimal.ROUND_HALF_UP).doubleValue();
		                	}else{
		                		logger.error("计划项目-itemid:" + itemid + ",clock:" + clock + "方案单耗计算错误");
		            			return "";
		                	}
	                	}
	                }
	                TRmPlanValue tv = tRmPlanValueMapper.selectByPrimaryKey(id);
	                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(), cl.doubleValue(), digits.intValue()));
	    	            tv.setUserid(JwtUtil.getUseridByToken());
	    	            tv.setUptime(DateUtils.dateStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
	    	            tRmPlanValueMapper.updateByPrimaryKeySelective(tv);
	                }else{
	                	tv = new TRmPlanValue();
	                	tv.setId(id);
	    	            //计算值
	                	tv.setActualvalue(new BigDecimal(actualvalue));
	    	            //修正值
	                	tv.setCorrectvalue(new BigDecimal(0));
	    	            //最终值
	                	tv.setApportvalue(new BigDecimal(actualvalue));
	    	            //折标值
	                	tv.setStdvalue(BigDecimalUtil.mul(zbxs, tv.getApportvalue().doubleValue()).setScale(digits, BigDecimal.ROUND_HALF_UP));
	    	            //单耗值
	                	tv.setUcvalue(BigDecimalUtil.divide(tv.getApportvalue().doubleValue(), cl.doubleValue(), digits.intValue()));
	                	tv.setRecTime(DateUtils.dateStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
	                	tv.setCrman(JwtUtil.getUseridByToken());
	                	tRmPlanValueMapper.insert(tv);
	                }
            	}catch (Exception e) {
    				logger.error("计划数据计算错误：itemid-" + itemid + ",clock-" + clock);
    				e.printStackTrace();
    			}
            }
		}
		return null;
	}
	
	@Override
	public int getCount(Map<String, Object> params) {
		return tRmPlanValueMapper.getCount(params);
	}
}
