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

import com.steerinfo.framework.datasource.DataSourceKey;
import com.steerinfo.framework.datasource.TargetDataSource;
import com.steerinfo.framework.mapper.IBaseMapper;
import com.steerinfo.framework.service.impl.BaseServiceImpl;
import com.steerinfo.ems.emseotiming.model.EmsEoTiming;
import com.steerinfo.ems.Utils.EmsEoAiUtil;
import com.steerinfo.ems.emseoaihoursumtab1.mapper.EmsEoAiHourSumTab1Mapper;
import com.steerinfo.ems.emseoaihoursumtab1.model.EmsEoAiHourSumTab1;
import com.steerinfo.ems.emseoaihoursumtab1org.mapper.EmsEoAiHourSumTab1OrgMapper;
import com.steerinfo.ems.emseoaihoursumtab1org.model.EmsEoAiHourSumTab1Org;
import com.steerinfo.ems.emseotiming.mapper.EmsEoTimingMapper;
import com.steerinfo.ems.emseotiming.service.IEmsEoTimingService;
import com.steerinfo.ems.trmcalpoint.mapper.TRmCalpointMapper;
import com.steerinfo.ems.trmcalpoint.model.TRmCalpoint;
import com.steerinfo.ems.trmcalpointvalue.service.ITRmCalpointValueService;

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.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;

/**
 * EmsEoTiming服务实现：
 * @author generator
 * @version 1.0-SNAPSHORT 2020-12-23 03:33
 * 类描述
 * 修订历史：
 * 日期：2020-12-23
 * 作者：generator
 * 参考：
 * 描述：EmsEoTiming服务实现
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@Service(value = "emsEoTimingService")
public class EmsEoTimingServiceImpl extends BaseServiceImpl<EmsEoTiming, String> implements IEmsEoTimingService {
	private static final Logger logger = LoggerFactory.getLogger(EmsEoTimingServiceImpl.class);
	
    @Autowired
    private EmsEoTimingMapper emsEoTimingMapper;

    @Override
    protected IBaseMapper<EmsEoTiming, String> getMapper() {
        return emsEoTimingMapper;
    }
    
    @Autowired
    private EmsEoAiHourSumTab1Mapper emsEoAiHourSumTab1Mapper;

    @Autowired
    private EmsEoAiHourSumTab1OrgMapper emsEoAiHourSumTab1OrgMapper;
    
    @Autowired
    private TRmCalpointMapper tRmCalpointMapper;
    
    @Autowired
    ITRmCalpointValueService tRmCalpointValueService;
    
    @Override
	@Transactional(rollbackFor=Exception.class)
    @TargetDataSource(dataSourceKey = DataSourceKey.DB_MASTER)
	public void getData() {
    	logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "-4G电数据定时获取任务执行开始");
    	
    	try {
    		//String sql4GId = "select v.itemid, v.itemname, v.itemdesc, v.itemtype, t.fourgitem from T_RM_CALPOINT v inner join T_RM_ELECTRICITY_LOCATION t on t.itemid = v.itemid where t.fourgitem like '0358%'";
    		
			/*
			 * List<Map<String, Object>> l = jdbcTemplate.queryForList(sql4GId);
			 * //获取有无线电表编号的计量点数据 if (l!=null && l.size()>0){ String fourgitemStr = "";
			 * 
			 * for(int i = 0; i < l.size(); i++) { //组合4G电表编号字符串 Map<String, Object> m =
			 * (Map<String, Object>)l.get(i); String fourgitem = m.get("fourgitem") == null
			 * ? "" : m.get("fourgitem").toString(); if(fourgitemStr.isEmpty()) {
			 * fourgitemStr = fourgitem; }else { fourgitemStr = "," + fourgitem; } }
			 * 
			 * if(fourgitemStr.length() > 0) {
			 * 
			 * } }
			 */
    		
    		//计算上一个15分钟时间点
    		Calendar cal = Calendar.getInstance();
			cal.setTime(new Date());
			cal.set(Calendar.SECOND, 0);
			int mimute = (cal.get(Calendar.MINUTE) + 1)/15 * 15;
			cal.set(Calendar.MINUTE, mimute);
			cal.add(Calendar.MINUTE, -15);
			String clock = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(cal.getTime());
			
			//生成数据对象
			boolean hasEmsEoTiming = true;
			EmsEoTiming e = null;
			e = emsEoTimingMapper.selectByPrimaryKey(clock);
			if(e == null) {
				e = new EmsEoTiming();
				e.setInsertTime(new Date());
				e.setClock(clock);
				hasEmsEoTiming = false;
			}
			
			List<Map<String, Object>> l = null;
			
			//数据赋值，正向有功
			l = getFData(clock);
			if (l!=null && l.size()>0){
				
				for(int i = 0; i < l.size(); i++) {
					Map<String, Object> m = (Map<String, Object>)l.get(i);
					String code = m.get("DEVICE_ADDRESS") == null ? "" : m.get("DEVICE_ADDRESS").toString();
					String val = m.get("FROZEN_VALUE") == null ? "" : m.get("FROZEN_VALUE").toString();
					e.setVal(code, val, "f");
				}
			}
			//数据赋值，反向有功
			l = getRData(clock);
			if (l!=null && l.size()>0){
				
				for(int i = 0; i < l.size(); i++) {
					Map<String, Object> m = (Map<String, Object>)l.get(i);
					String code = m.get("DEVICE_ADDRESS") == null ? "" : m.get("DEVICE_ADDRESS").toString();
					String val = m.get("FROZEN_VALUE") == null ? "" : m.get("FROZEN_VALUE").toString();
					e.setVal(code, val, "r");
				}
			}
			
			// 新增
			if (hasEmsEoTiming == false) {
				emsEoTimingMapper.insert(e);
			} else {
				// 更新
				emsEoTimingMapper.updateByPrimaryKeySelective(e);
			}
			// 1小时30分钟后，更新前一小时表数据(采集器有延时)
			int minute = cal.get(Calendar.MINUTE);
			if (minute >= 30) {
				String clke = new SimpleDateFormat("yyyy-MM-dd HH").format(cal.getTime());
				cal.add(Calendar.HOUR_OF_DAY, -1);
				String clk = new SimpleDateFormat("yyyy-MM-dd HH").format(cal.getTime());
				EmsEoAiHourSumTab1 eh = emsEoAiHourSumTab1Mapper.selectByPrimaryKey(clk);
				if (eh == null) {
					// String minuClock = clk+":00"; // 2019-11-20 08:00
					String minuClocke = clke + ":00"; // 2019-11-20 09:00
					// 从EMS_EO_TIMING读取小时准点值
					Map<String, Object> mp = emsEoTimingMapper.getHourPointVal(minuClocke);
					// 整点数据,特定情况下会重复插入，导致异常
					EmsEoAiHourSumTab1Org eeho = new EmsEoAiHourSumTab1Org();
					if (mp != null && mp.size() > 0) {
						eeho.setClock(clke);
						eeho.setInsertTime(new Date());
						eeho = EmsEoAiUtil.setValByMap(eeho, mp);
						emsEoAiHourSumTab1OrgMapper.insert(eeho);
					}
					// 小时累计值 = 当前小时准点值 - 前1小时小时准点值
					EmsEoAiHourSumTab1Org eehol = emsEoAiHourSumTab1OrgMapper.selectByPrimaryKey(clk);
					if (eehol == null || eehol.getClock() == null || eehol.getClock().isEmpty()
							|| eeho.getClock() == null || eeho.getClock().isEmpty()) {
						logger.error("数据表EMS_EO_AI_HOUR_SUM_TAB1_ORG缺少数据：" + clk);
					} else {
						EmsEoAiHourSumTab1 eeh = new EmsEoAiHourSumTab1();
						eeh.setClock(clk);
						eeh.setInsertTime(new Date());
						eeh = EmsEoAiUtil.setVal(eeh, eeho, eehol);
						emsEoAiHourSumTab1Mapper.insert(eeh);
					}
				}
			}
    		
            logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "-4G电数据定时获取任务执行完毕");
        } catch (Exception e) {
        	logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "-4G电数据定时获取任务执行出错了" + e.getMessage());
            throw new RuntimeException("出错了:" + e.getMessage());
        }
    }
    
    @Override
	@Transactional(rollbackFor=Exception.class)
    @TargetDataSource(dataSourceKey = DataSourceKey.DB_MASTER)
	public void getLaterData() {
		logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "-4G电later数据定时获取任务执行开始");

		// 需要新增的对象
		Map<String, EmsEoTiming> ins = new HashMap<String, EmsEoTiming>();
		// 需要修改的对象
		Map<String, EmsEoTiming> ups = new HashMap<String, EmsEoTiming>();
		// 从数据库查询过的对象
		Map<String, EmsEoTiming> ss = new HashMap<String, EmsEoTiming>();
		
		Map<String, String> cps = new HashMap<String, String>();

		try {
			// 计算时间范围
			Calendar cal = Calendar.getInstance();
			cal.setTime(new Date());
			cal.set(Calendar.SECOND, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			String clockEnd = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(cal.getTime());
			cal.add(Calendar.DAY_OF_YEAR, -1);
			String clockStart = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(cal.getTime());

			for(int i = 0; i < 2; i++) {
				List<Map<String, Object>> all = null;
				String dataType = null;
				if(i == 0) {
					all = getLaterFData(clockStart, clockEnd);
					dataType = "f";
				}
				else if(i == 1) {
					all = getLaterRData(clockStart, clockEnd);
					dataType = "r";
				}
	
				if (all != null && all.size() > 0) {
					for (int ii = 0; ii < all.size(); ii++) {
						Map<String, Object> item = (Map<String, Object>) all.get(ii);
						String clock = item.get("FROZEN_TIME") == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm").format(item.get("FROZEN_TIME"));
						
						if (clock != null && clock != "") {
							// 生成数据对象
							EmsEoTiming e = null;
							// 是否已经查找过该对象
							if (ss.containsKey(clock)) {
								e = ss.get(clock);
							} else {
								e = emsEoTimingMapper.selectByPrimaryKey(clock);
							}
	
							if (e == null) {
								if (!ss.containsKey(clock)) {
									ss.put(clock, null);
								}
	
								if (ins.containsKey(clock)) {
									e = ins.get(clock);
								} else {
									e = new EmsEoTiming();
									e.setInsertTime(new Date());
									e.setClock(clock);
									ins.put(clock, e);
								}
							} else {
								if (!ss.containsKey(clock)) {
									ss.put(clock, e);
								}
								if (ups.containsKey(clock)) {
									e = ups.get(clock);
								} else {
									ups.put(clock, e);
								}
							}
	
							String code = item.get("DEVICE_ADDRESS") == null ? "" : item.get("DEVICE_ADDRESS").toString();
							String val = item.get("FROZEN_VALUE") == null ? "" : item.get("FROZEN_VALUE").toString();
							e.setVal(code, val, dataType);
							
							cps.put(clock, "EMS_EO_TIMING." + dataType.toUpperCase() + code);
	
						}
					}
				}
			}
			
			//System.out.println(ins);
			
			// 新增
			for (EmsEoTiming ee : ins.values()) {
				emsEoTimingMapper.insert(ee);
				System.out.println(ee.getClock());
			}
			// 更新
			for (EmsEoTiming ee : ups.values()) {
				emsEoTimingMapper.updateByPrimaryKeySelective(ee);
			}
			
			Map<String, EmsEoTiming> all = new HashMap<String, EmsEoTiming>();
			all.putAll(ins);
			all.putAll(ups);

			// 更新小时数据点
			for (String clockpoint : all.keySet()) {
				Date d = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(clockpoint);
				cal.setTime(d);
				if(cal.get(Calendar.MINUTE) != 0) continue;  //不是整点，不影响计算
				String clk = new SimpleDateFormat("yyyy-MM-dd HH").format(cal.getTime());
				cal.add(Calendar.HOUR_OF_DAY, 1);   //应该计算前后两小时的数据
				String clke = new SimpleDateFormat("yyyy-MM-dd HH").format(cal.getTime());
				
				// String minuClock = clk+":00"; // 2019-11-20 08:00
				String minuClocke = clke + ":00"; // 2019-11-20 09:00
				// 从EMS_EO_TIMING读取小时准点值
				Map<String, Object> mp = emsEoTimingMapper.getHourPointVal(minuClocke);
				if(mp == null || mp.size() == 0) {
					logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "无整点数据：" + clockpoint);
					continue;   //获取准点值失败，跳过
				}
				// 更新整点数据
				EmsEoAiHourSumTab1Org eeho = null;
				eeho = emsEoAiHourSumTab1OrgMapper.selectByPrimaryKey(clke);
				if(eeho == null) {
					eeho = new EmsEoAiHourSumTab1Org();
					eeho.setClock(clke);
					eeho.setInsertTime(new Date());
					eeho = EmsEoAiUtil.setValByMap(eeho, mp);
					emsEoAiHourSumTab1OrgMapper.insert(eeho);
				}else {
					eeho.setInsertTime(new Date());
					eeho = EmsEoAiUtil.setValByMap(eeho, mp);
					emsEoAiHourSumTab1OrgMapper.updateByPrimaryKey(eeho);
				}
				// 小时累计值 = 当前小时准点值 - 前1小时小时准点值
				EmsEoAiHourSumTab1Org eehol = emsEoAiHourSumTab1OrgMapper.selectByPrimaryKey(clk);
				if (eehol == null || eeho == null || eehol.getClock() == null || eehol.getClock().isEmpty()
						|| eeho.getClock() == null || eeho.getClock().isEmpty()) {
					logger.error("数据表EMS_EO_AI_HOUR_SUM_TAB1_ORG缺少数据：" + clk);
				} else {
					EmsEoAiHourSumTab1 eeh = null;
					eeh = emsEoAiHourSumTab1Mapper.selectByPrimaryKey(clk);
					if(eeh == null) {
						eeh = new EmsEoAiHourSumTab1();
						eeh.setClock(clk);
						eeh.setInsertTime(new Date());
						eeh = EmsEoAiUtil.setVal(eeh, eeho, eehol);
						emsEoAiHourSumTab1Mapper.insert(eeh);
					}else {
						eeh.setInsertTime(new Date());
						eeh = EmsEoAiUtil.setVal(eeh, eeho, eehol);
						emsEoAiHourSumTab1Mapper.updateByPrimaryKey(eeh);
					}
				}
			}
			
			//更新计量点数据
			for (String clockpoint : cps.keySet()){
				Date d = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(clockpoint);
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(d);
				String today = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
					
				Map<String, Object> m = new HashMap<String, Object>();
				String content = cps.get(clockpoint);
				m.put("btype2", content);
				List<TRmCalpoint> list = tRmCalpointMapper.selectByParameters(m);
				if(list != null && list.size() > 0) {
					TRmCalpoint tRmCalpoint = list.get(0);
						
					String mintimegranid = tRmCalpoint.getMintimegranid()==null? "DAY" : tRmCalpoint.getMintimegranid();
					// 最小粒度日时间粒度数据
					if(mintimegranid.equalsIgnoreCase("DAY") || mintimegranid.equalsIgnoreCase("SHIFT")){
						tRmCalpointValueService.restatCalData(tRmCalpoint, today, "DAY", "系统");
					}
				}
			}

			logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "-4G电later数据定时获取任务执行完毕");
		} catch (Exception e) {
			logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "-4G电later数据定时获取任务执行出错了"
					+ e.getMessage());
			throw new RuntimeException("出错了:" + e.getMessage());
		}
	}
    
    @Override
	public List<Map<String, Object>> getFData(String clock) {
    	try {
    		return emsEoTimingMapper.getFData(clock);
    	} catch(Exception e) {
    		return null;
    	}
    }
    
    @Override
	public List<Map<String, Object>> getRData(String clock) {
    	return emsEoTimingMapper.getRData(clock);
    }
    
    @Override
	public List<Map<String, Object>> getLaterFData(String clock, String clockEnd) {
    	try {
    		HashMap<String, Object> m = new HashMap<String, Object>();
    		m.put("clock", clock);
    		m.put("clockEnd", clockEnd);
    		return emsEoTimingMapper.getLaterFData(m);
    	} catch(Exception e) {
    		return null;
    	}
    }
    
    @Override
	public List<Map<String, Object>> getLaterRData(String clock, String clockEnd) {
    	try {
    		HashMap<String, Object> m = new HashMap<String, Object>();
    		m.put("clock", clock);
    		m.put("clockEnd", clockEnd);
    		return emsEoTimingMapper.getLaterRData(m);
    	} catch(Exception e) {
    		return null;
    	}
    }
}
