package com.steerinfo.ems.usagedata.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.usagedata.model.UsageData;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import com.steerinfo.ems.Utils.DateUtils;
import com.steerinfo.ems.Utils.UsageDataUtils;
import com.steerinfo.ems.formula.service.IFormulaService;
import com.steerinfo.ems.ifemsmesactitem.service.IIfEmsMesActitemService;
import com.steerinfo.ems.ifmesemsswapfile.service.IIfMesEmsSwapfileService;
import com.steerinfo.ems.usagedata.mapper.UsageDataMapper;
import com.steerinfo.ems.usagedata.service.IUsageDataService;
import com.steerinfo.ems.usagedataconfig.model.UsageDataConfig;
import com.steerinfo.ems.usagedataconfig.service.IUsageDataConfigService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * UsageData服务实现：
 * @author generator
 * @version 1.0-SNAPSHORT 2019-11-06 10:53
 * 类描述
 * 修订历史：
 * 日期：2019-11-06
 * 作者：generator
 * 参考：
 * 描述：UsageData服务实现
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@Service(value = "usageDataService")
public class UsageDataServiceImpl extends BaseServiceImpl<UsageData, String> implements IUsageDataService {

    private static final Logger logger = LoggerFactory.getLogger(UsageDataServiceImpl.class);

    @Autowired
    private UsageDataMapper usageDataMapper;
    @Autowired
    IIfMesEmsSwapfileService ifMesEmsSwapfileService;
    @Autowired
    IIfEmsMesActitemService ifEmsMesActitemService;
    @Autowired
    IUsageDataConfigService usageDataConfigService;
    @Autowired
    IFormulaService formulaService;

    @Override
    protected IBaseMapper<UsageData, String> getMapper() {
        return usageDataMapper;
    }

    public List<UsageData> selectDataCodeAndDt(HashMap<String, Object> m) {
        return usageDataMapper.selectDataCodeAndDt(m);
    }
    
    @Override
	public PageList<Map<String, Object>> searchForPage(HashMap<String, Object> parmas, Integer pageNum, Integer pageSize) {
    	PageHelper.startPage(pageNum, pageSize);
    	List<Map<String,Object>>  rows = usageDataMapper.searchList(parmas);
        PageList<Map<String,Object>> pageInfo = new PageList<Map<String,Object>>(rows);
        return pageInfo;
	}

    /**
	 * 统计自动上传的能源上报数据
	 * @return
	 */
    public String getAutoSum(String clock) {
    	if(clock==null || clock.isEmpty()){
    		return "请传入统计日期";
    	}
        int addSize = 0;
        int errorSize = 0;
        logger.info("开始生成最新的能源数据。");
        // 获取所有需自动生成的项目
        List<UsageDataConfig> list = usageDataConfigService.getAutoData();
        outer:for (int i = 0; i < list.size(); i++) {
            UsageDataConfig item = list.get(i);
            String energyCode = item.getEnergyCode();
            if (energyCode == null || energyCode.length() == 0) {
                logger.info("[配置错误][ " + item.getNote() + " ]的energyCode配置错误，放弃新增");
                errorSize++;
                continue;
            }
            if (item.getProdline() == null || item.getProdline().length() == 0) {
                logger.info("[配置错误][ " + item.getNote() + " ]的prodline配置错误，放弃新增");
                errorSize++;
                continue;
            }
            if (!energyCode.startsWith("DL") && (item.getMaterialcode() == null || item.getMaterialcode().length() == 0)) {
                logger.info("[配置错误][ " + item.getNote() + " ]的materialcode配置错误，放弃新增");
                errorSize++;
                continue;
            }
            HashMap<String, Object> m = new HashMap<String, Object>();
            m.put("dataCode", energyCode);
            m.put("dt", clock);
            // 查询该数据当天是否存在
            List<UsageData> selectData = usageDataMapper.selectDataCodeAndDt(m);
            if(!selectData.isEmpty()){
                logger.info("[USAGE_DATA]表已存在[ " + item.getNote() + " ]当天的相关信息，不进行新增");
                // logger.info(selectData.toString());
            } else {
                String prodlines = item.getProdline().trim();
                BigDecimal sum = BigDecimal.ZERO;
                String memo = "";
                // 不是1开头的产线代码，表示从计量点或者项目获得数据
                if(!prodlines.startsWith("1")){
                	String ids[] = prodlines.split(",");
                	for(String itemid:ids){
                		Double db = formulaService.getValByItemid(itemid, "DAY", clock, 0);
                		if(db<0){
                			errorSize++;
                			logger.info("[可能存在的问题][ " + item.getNote() + ":"+itemid+"-"+clock+" ]数据错误，放弃新增");
                            continue outer;
                        }
                		sum = sum.add(BigDecimal.valueOf(db));
                		memo += itemid + "(" + formulaService.getFormulaLatest(itemid).getDescription() + ")" + "+";
                	}
                }else{
                	String materialcodes = item.getMaterialcode().trim();
                    String isnot = "";
                    // not[] 将执行 not in ()
                    if (materialcodes.matches("^not\\[.*\\]$")) {
                        materialcodes =  materialcodes.replaceAll("^not\\[", "").replaceAll("\\]$", "");
                        isnot = "not";
                    }
                    prodlines = "'" + prodlines.replaceAll(",", "', '") + "'";
                    materialcodes =  "'" + materialcodes.replaceAll(",", "', '") + "'";
                    HashMap<String, Object> sumMap = new HashMap<String, Object>();
                    sumMap.put("prodlines", prodlines);
                    sumMap.put("materialcodes", materialcodes);
                    sumMap.put("isnot", isnot);
                    sumMap.put("dataDay", clock);
                    // 获取对应项目的数据值汇总
                    sum = ifMesEmsSwapfileService.getSUM(sumMap);
                    if (sum == null) {
                    	errorSize++;
                        logger.info("[可能存在的问题][ " + item.getNote() + " ]当日没有数据，放弃新增");
                        continue;
                    }
                }
                memo = memo.isEmpty()?"":memo.substring(0,memo.length()-1);
                UsageData model = new UsageData();
                model.setDataCode(energyCode);
                model.setDataName(item.getNote());
                model.setDt(clock);
                model.setUsage(sum);
                model.setUnit(item.getUnit());
                model.setGranularity("DAY");
                model.setMemo(memo);
                model.setCzr("MES");
                model.setStatus("0");
                model.setCt(new Date());
                // 计算累计值
        		String startDate = "2020-12-21";
        		if(item.getStartDate()!=null){
        			startDate = item.getStartDate().trim();
        		}
        		Map<String, Object> params = new HashMap<String, Object>();
        		params.put("dataCode", energyCode);
        		params.put("startDate", startDate);
        		params.put("dt", clock);
        		try {
        			// 统计开始时间之前，累计数据为0
            		if (new SimpleDateFormat("yyyy-MM-dd").parse(startDate).after(new SimpleDateFormat("yyyy-MM-dd").parse(model.getDt()))){
            			model.setSumval(BigDecimal.ZERO);
            		}else{
            			// 获取累计值
                		Double sumval = usageDataMapper.getSumval2(params);
                		model.setSumval(model.getUsage().add(new BigDecimal(Double.toString(sumval))));
            		}
        		}catch(Exception e){
        		}
                usageDataMapper.insert(model);
                addSize++;
            }
        }
        logger.info("本次新增的数据条数：" + addSize);
		logger.info("本次错误的数据条数：" + errorSize);
        return "本次新增" + addSize + "条,失败" + errorSize + "条。";
    }

    public int updateState(UsageData usageData){
    	int r = 0;
    	if (usageData.getStatus().equals("0")){
    		// 数据同步_晋泰信和
    		r = UsageDataUtils.Insert(usageData);
    		if(r>0){
        		usageData.setStatus("1");
                usageDataMapper.updateState(usageData);
        	}
    	}
    	return r;
    }

    public List<UsageData> getEmsData(){
        return this.usageDataMapper.getEmsData();
    }

	@Override
	public void autoUpload() {
		logger.info("自动_能源上报_晋泰信和，任务开始...");
		Map<String, Object> params = new HashMap<>();
        params.put("paramkey", "ems_usage_auto_upload");
        List<Map<String, Object>> list = ifEmsMesActitemService.selectParam(params);
        String auto = "0";
        if(list.size() > 0){
        	auto = list.get(0).get("PARAM_VALUE").toString();
        }
        if(auto.equals("1")){
        	List<UsageData> updata = usageDataMapper.getEmsData();
        	List<String> errorid = new ArrayList<String>();
        	for (UsageData usageData : updata) {
        		usageData.setOperatorMan("SYSTEM");
        		usageData.setOperatorDate(new Date());
                int r = updateState(usageData);
                if(r<1){
                	errorid.add(usageData.getId());
                }
        	}
        	logger.info("本次共操作上传数据条数：" + updata.size());
    		logger.info("本次共操作上传成功数据条数：" + (updata.size() - errorid.size()));
    		logger.info("本次共操作上传失败数据条数：" + errorid.size());
    		if(errorid.size()>0){
    			logger.info("本次共操作上传失败id：" + errorid.toString());
        	}
        }else{
        	logger.info("当前设置能源上报_晋泰信和为：手动上传");
        }
    	logger.info("自动_能源上报_晋泰信和，任务结束...");
	}

	@Override
	public void restatData(String dt, String energyCode) {
		String regex="^\\d{4}-\\d{2}-\\d{2}$";
		if(dt==null || !dt.matches(regex)){
			logger.info("[时间格式错误][ " + dt + " ]");
            return;
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("energyCode", energyCode);
		UsageDataConfig udc = usageDataConfigService.getByParams(params);
		if (energyCode == null || energyCode.length() == 0) {
            logger.info("[配置错误][ " + udc.getNote() + " ]的energyCode配置错误");
            return;
        }
        if (udc== null || udc.getProdline() == null || udc.getProdline().length() == 0) {
            logger.info("[配置错误][ " + udc.getNote() + " ]的prodline配置错误");
            return;
        }
        if (!energyCode.startsWith("DL") && (udc.getMaterialcode() == null || udc.getMaterialcode().length() == 0)) {
            logger.info("[配置错误][ " + udc.getNote() + " ]的materialcode配置错误");
            return;
        }
        String prodlines = udc.getProdline().trim();
        BigDecimal sum = BigDecimal.ZERO;
        BigDecimal sumval = BigDecimal.ZERO;
        String memo = "";
        // 不是1开头的产线代码，表示从计量点或者项目获得数据
        if(!prodlines.startsWith("1")){
        	String ids[] = prodlines.split(",");
        	for(String itemid:ids){
        		Double db = formulaService.getValByItemid(itemid, "DAY", dt, 0);
        		if(db<0){
        			logger.info("[可能存在的问题][ " + udc.getNote() + ":"+itemid+"-"+dt+" ]数据错误");
        			return;
                }
        		sum = sum.add(BigDecimal.valueOf(db));
        		memo += itemid + "(" + formulaService.getFormulaLatest(itemid).getDescription() + ")" + "+";
        	}
        }else{
        	if(udc.getMaterialcode().isEmpty() || udc.getMaterialcode().trim().isEmpty()){
        		logger.info("[配置错误][ " + udc.getNote() + " ]的materialcode配置错误");
                return;
        	}
        	String materialcodes = udc.getMaterialcode().trim();
            String isnot = "";
            // not[] 将执行 not in ()
            if (materialcodes.matches("^not\\[.*\\]$")) {
                materialcodes =  materialcodes.replaceAll("^not\\[", "").replaceAll("\\]$", "");
                isnot = "not";
            }
            prodlines = "'" + prodlines.replaceAll(",", "', '") + "'";
            materialcodes =  "'" + materialcodes.replaceAll(",", "', '") + "'";
            HashMap<String, Object> sumMap = new HashMap<String, Object>();
            sumMap.put("prodlines", prodlines);
            sumMap.put("materialcodes", materialcodes);
            sumMap.put("isnot", isnot);
            sumMap.put("dataDay", dt);
            // 获取对应项目的数据值汇总
            sum = ifMesEmsSwapfileService.getSUM(sumMap);
            if (sum == null) {
                logger.info("[可能存在的问题][ " + udc.getNote() + " ]当日没有数据");
                return;
            }
        }
        memo = memo.isEmpty()?"":memo.substring(0,memo.length()-1);
        // 计算累计值
		String startDate = "2020-12-21";
		if(udc!=null && udc.getStartDate()!=null){
			startDate = udc.getStartDate().trim();
		}
		Map<String, Object> sumparams = new HashMap<String, Object>();
        sumparams.put("dataCode", energyCode);
		sumparams.put("startDate", startDate);
		sumparams.put("dt", dt);
		// 获取累计值-（2020-12-21开始，上传累计值）
		try {
			// 统计开始时间 不在 业务时间之后
    		if (!new SimpleDateFormat("yyyy-MM-dd").parse(startDate).after(new SimpleDateFormat("yyyy-MM-dd").parse(dt))){
    			// 获取累计值
        		sumval = sum.add(new BigDecimal(Double.toString(usageDataMapper.getSumval2(sumparams))));
    		}
		}catch(Exception e){
		}
        // 查询该数据当天是否存在
        HashMap<String, Object> m = new HashMap<String, Object>();
        m.put("dataCode", energyCode);
        m.put("dt", dt);
        List<UsageData> selectData = usageDataMapper.selectDataCodeAndDt(m);
        if(selectData!=null && !selectData.isEmpty()){ // 更新
        	UsageData uData = selectData.get(0);
        	uData.setUsage(sum);
        	uData.setMemo(memo);
        	uData.setSumval(sumval);
        	usageDataMapper.updateByPrimaryKeySelective(uData);
        } else {
        	UsageData model = new UsageData();
            model.setDataCode(energyCode);
            model.setDataName(udc.getNote());
            model.setDt(dt);
            model.setUsage(sum);
            model.setUnit(udc.getUnit());
            model.setGranularity("DAY");
            model.setMemo(memo);
            model.setCzr("MES");
            model.setStatus("0");
            model.setSumval(sumval);
            model.setCt(new Date());
            usageDataMapper.insert(model);
        }
	}

}
