package com.steerinfo.ems.emsetiming.controller;

import com.steerinfo.framework.controller.BaseRESTfulController;
import com.steerinfo.framework.controller.RESTfulResult;
import com.steerinfo.framework.service.pagehelper.PageList;
import com.steerinfo.ems.Utils.DateUtils;
import com.steerinfo.ems.emseaihoursumtab1org.mapper.EmsEAiHourSumTab1OrgMapper;
import com.steerinfo.ems.emseaihoursumtab1org.model.EmsEAiHourSumTab1Org;
import com.steerinfo.ems.emsetiming.mapper.EmsETimingMapper;
import com.steerinfo.ems.emsetiming.model.EmsETiming;
import com.steerinfo.ems.emsetiming.service.IEmsETimingService;
import com.steerinfo.ems.formula.model.Formula;
import com.steerinfo.ems.formula.service.IFormulaService;
import com.steerinfo.ems.ifemsmesactitem.service.IIfEmsMesActitemService;
import com.steerinfo.ems.ifmesemsproductorder.service.IIfMesEmsProductorderService;
import com.steerinfo.ems.ifmesemsswapfile.model.IfMesEmsSwapfile;
import com.steerinfo.ems.ifmesemsswapfile.service.IIfMesEmsSwapfileService;
import com.steerinfo.ems.mesemsdieseloil.service.IMesEmsDieseloilService;
import com.steerinfo.ems.trmactvalue.service.ITRmActValueService;
import com.steerinfo.ems.trmcalpoint.mapper.TRmCalpointMapper;
import com.steerinfo.ems.trmcalpoint.model.TRmCalpoint;
import com.steerinfo.ems.trmcalpoint.service.ITRmCalpointService;
import com.steerinfo.ems.trmcalpointvalue.mapper.TRmCalpointValueMapper;
import com.steerinfo.ems.trmcalpointvalue.model.TRmCalpointValue;
import com.steerinfo.ems.trmcalpointvalue.service.ITRmCalpointValueService;
import com.steerinfo.ems.trmindexvalue.mapper.TRmIndexValueMapper;
import com.steerinfo.ems.trmindexvalue.model.TRmIndexValue;
import com.steerinfo.ems.trmindexvalue.service.ITRmIndexValueService;
import com.steerinfo.ems.trmworkprocmaterialvalue.service.ITRmWorkprocMaterialValueService;
import com.steerinfo.ems.trmworkprocproductvalue.service.ITRmWorkprocProductValueService;
import com.steerinfo.ems.usagedata.service.IUsageDataService;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * EmsETiming RESTful接口：
 * @author generator
 * @version 1.0-SNAPSHORT 2019-11-25 04:04
 * 类描述
 * 修订历史：
 * 日期：2019-11-25
 * 作者：generator
 * 参考：
 * 描述：EmsETiming RESTful接口
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@RestController
@RequestMapping("/${api.version}/emsetimings")
public class EmsETimingController extends BaseRESTfulController {

	@Autowired
    IEmsETimingService emsETimingService;
	
	@Autowired
    ITRmWorkprocProductValueService tRmWorkprocProductValueService;
	@Autowired
    ITRmActValueService tRmActValueService;
	
	@Autowired
    IFormulaService formulaService;
	
	@Autowired
    private JdbcTemplate jdbcTemplate;
	
    @Autowired
    private TRmCalpointValueMapper tRmCalpointValueMapper;
    
    @Autowired
    private TRmCalpointMapper tRmCalpointMapper;
	
	@Autowired
    private EmsEAiHourSumTab1OrgMapper emsEAiHourSumTab1OrgMapper;
	
	@Autowired
    private EmsETimingMapper emsETimingMapper;
	
	@Autowired
	ITRmIndexValueService tRmIndexValueService;
	
	@Autowired
    ITRmCalpointValueService tRmCalpointValueService;
	
	@Autowired
    ITRmCalpointService tRmCalpointService;
	
	@Autowired
    IUsageDataService usageDataService;
	
	@Autowired
    IIfEmsMesActitemService ifEmsMesActitemService;
	
	@Autowired
    IIfMesEmsSwapfileService ifMesEmsSwapfileService;
    @Autowired
    IIfMesEmsProductorderService ifMesEmsProductorderService;
    @Autowired
    IMesEmsDieseloilService mesEmsDieseloilService;
    @Autowired
    ITRmWorkprocMaterialValueService tRmWorkprocMaterialValueService;

    @ApiOperation(value="获取详细信息", notes="根据url的id来获取详细信息")
    @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true, dataType = "String")
    //@RequiresPermissions("trmunit:view")
    @GetMapping(value = "/{id}")
    public RESTfulResult get(@PathVariable String id) throws ParseException{
		String start = "2019-12-04 00:01";
		String end = "2019-12-04 00:02";
		Date startDay = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(start);
		Date endDay = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(end);
		
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("useflag", "1");
		m.put("energytypeid", "E");
		// 查询需要统计的电计量点信息
		List<TRmCalpoint> l = tRmCalpointMapper.selectCalpoints(m);
		String lastMonth = "2019-12";
		while(!startDay.after(endDay)){
			String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(startDay); // "2019-12-03"
			Date td = new Date(startDay.getTime() + 3600*24*1000);
			String today = new SimpleDateFormat("yyyy-MM-dd").format(td); // "2019-12-04";
			
			if(l!=null && l.size()>0){
				for(TRmCalpoint tRmCalpoint : l){
					String itemtype = tRmCalpoint.getItemtype(); // 类型 AUTO:自动，MANUAL:手抄，VIRTUAL:虚拟
					String itemid = tRmCalpoint.getItemid();
					String itemname = tRmCalpoint.getItemname();
					String tagTable = tRmCalpoint.getTagTable()==null? "" :tRmCalpoint.getTagTable().trim(); // 小时表
					String tagCol = tRmCalpoint.getTagCol()==null? "" :tRmCalpoint.getTagCol().trim(); // 小时表字段
					String tagBadStr = tRmCalpoint.getTagBadSymbol()==null? "-1" : tRmCalpoint.getTagBadSymbol();
					Double tagBad = -1d; // 异常点标签(读表异常时候插入的值)
					Double mod = tRmCalpoint.getTagModulus() == null? 1d : tRmCalpoint.getTagModulus().doubleValue(); // 倍率
					System.out.println("itemid---" + itemid);
					try {
						tagBad = Double.parseDouble(tagBadStr);
					} catch (NumberFormatException e) {
						System.out.println("计量点" + itemid + "的tag_bad_symbol值格式应该为负数，当前值为：" + tagBadStr);
						tagBad = -1d;
					}
					if(itemtype.equalsIgnoreCase("AUTO") && (tagTable.isEmpty() || tagCol.isEmpty())){
						System.out.println("计量点的数据表与数据列信息不完整！");
						throw new RuntimeException("请先在计量点信息维护中配置计量点的数据表与数据列！");
					}
					if(!tagTable.equalsIgnoreCase("EMS_E_AI_HOUR_SUM_TAB1")){
						System.out.println("itemid---" + itemid);
						return failed(null,"出错了！");
					}
					Short digits = tRmCalpoint.getDigits() == null ? 4 : tRmCalpoint.getDigits();
					Short digits2 = tRmCalpoint.getMeterScale() == null ? 4 : tRmCalpoint.getMeterScale(); // 准点值精度
					Double qc = 0d; // 仪表期初值
					Double qm = 0d; // 仪表期末值
					
					// 日时间粒度数据
					String sql = "select count(1) from T_RM_CALPOINT_VALUE where clock = ? and timegranid='DAY' and itemid = ?";
					int c = jdbcTemplate.queryForObject(sql, new Object[]{yesterday,itemid}, Integer.class);
					if(c>0){
						System.out.println(yesterday + "-itemid:" + itemid + " 已存在数据。");
						return failed(null,"出错了！");
					}else{
						TRmCalpointValue t = new TRmCalpointValue();
						if(itemtype.equalsIgnoreCase("AUTO")){
							t.setClock(yesterday);
							t.setTimegranid("DAY");
							t.setItemid(itemid);
							t.setItemname(itemname);
							t.setCorrectvalue(new BigDecimal("0")); // 修正值
							t.setRecTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
							// 获取仪表期初、期末值
							sql = "select nvl(round("+tagCol+", "+digits2+"),0) from "+tagTable + "_ORG where clock = ?";
							try {
								qc = jdbcTemplate.queryForObject(sql, new Object[]{yesterday + " 00"}, Double.class);
							} catch(Exception e) {
								System.out.println(yesterday + "-itemid:" + itemid + " 没有仪表期初值。");
								qc = tagBad;
							}
							try {
								qm = jdbcTemplate.queryForObject(sql, new Object[]{today + " 00"}, Double.class);
							} catch(Exception e) {
								System.out.println(today + "-itemid:" + itemid + " 没有仪表期末值。");
								qm = tagBad;
							}
							System.out.println("sql---" + sql);
							t.setMintvalue(qc==null?null:new BigDecimal(Double.toString(qc)));
							t.setMendvalue(qm==null?null:new BigDecimal(Double.toString(qm)));
							if(qm == tagBad || qc == tagBad || new BigDecimal(Double.toString(qm)).subtract(new BigDecimal(Double.toString(qc))).doubleValue()<0){
								System.out.println(today + "-itemid:" + itemid + " 没有仪表期末值。");
								return failed(null,"出错了！");
							}else{
								// 仪表期末值 - 仪表期初值
								BigDecimal ap = new BigDecimal(Double.toString(qm)).subtract(new BigDecimal(Double.toString(qc))).multiply(new BigDecimal(mod)).setScale(digits, BigDecimal.ROUND_HALF_UP);
								t.setApportvalue(ap); // 最终值
								t.setActualvalue(ap); // 计算值
							}
						}else if(itemtype.equalsIgnoreCase("MANUAL")){
							t.setClock(yesterday);
							t.setTimegranid("DAY");
							t.setItemid(itemid);
							t.setItemname(itemname);
							t.setApportvalue(new BigDecimal("0")); // 最终值
							t.setCorrectvalue(new BigDecimal("0")); // 修正值
							t.setActualvalue(new BigDecimal("0")); // 计算值
						}else if(itemtype.equalsIgnoreCase("VIRTUAL")){
							// 获得计算公式
							String formula = formulaService.getFormula(itemid,lastMonth);
							// 根据公式获取计算值
							Double dval = formulaService.getValByFormula(formula, "DAY", lastMonth, digits, 0);
							if(dval < 0){
								System.out.println(yesterday + "-itemid:" + itemid + " 计算公式错误。");
							}
							t.setClock(yesterday);
							t.setTimegranid("DAY");
							t.setItemid(itemid);
							t.setItemname(itemname);
							t.setApportvalue(new BigDecimal(Double.toString(dval))); // 最终值
							t.setCorrectvalue(new BigDecimal("0")); // 修正值
							t.setActualvalue(new BigDecimal(Double.toString(dval))); // 计算值
						}
						// 日粒度累计值 = 本月的日最终值之和
						sql = "select nvl(round(sum(apportvalue),"+digits+"),0) from T_RM_CALPOINT_VALUE where timegranid='DAY' and itemid = ? and substr(clock,0,7) = ? and clock<?";
						Double dsm = jdbcTemplate.queryForObject(sql, new Object[]{itemid,lastMonth,yesterday}, Double.class);
						if(t.getActualvalue() !=null && dsm!=null){
							t.setSumvalue(t.getActualvalue().add(new BigDecimal(Double.toString(dsm))));
						}else if(dsm!=null){
							t.setSumvalue(new BigDecimal(Double.toString(dsm)));
						}else if(t.getActualvalue() !=null){
							t.setSumvalue(t.getActualvalue());
						}
						tRmCalpointValueMapper.insertSelective(t);
					}
				}
			}
			startDay = new Date(startDay.getTime() + 3600*24*1000);
		}
		System.out.println("计量点定时统计数据任务执行完毕~");
        return success();
    }
    
    @ApiOperation(value="计算", notes="计算")
    @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true, dataType = "String")
    //@RequiresPermissions("trmunit:view")
    @GetMapping(value = "/jis/")
    public RESTfulResult jis(){
    	// 获得计算公式
		//String ff = formulaService.getFormula("ZY0000P0052B","2019-12");
		
    	String ff = "[ZY0000P0052B]*([ZY4200P0051R]/[ZY0000P0052R])";
//    	Formula formula = new Formula();
//    	formula.setClock("201912");
//    	formula.setCode("ZY9202W0021R");
//    	formula.setSourcecode(ff);
//    	formula.setTablename("T_RM_ACT_VALUE");
//    	String ck = formulaService.checkFormulaSeq(formula);
//    	System.out.println(ck);
//    	if(ck.isEmpty()){
//    		Double d = formulaService.getValByFormula(ff, "DAY", "2019-12-19", 4, 0);
//        	System.out.println(d);
//    	}
    	Double d = formulaService.getValByFormula(ff, "MONTH", "2019-12", 4, 0);
    	System.out.println(d+"");
    	return success(d);
    }
    
    @GetMapping(value = "/test/")
    public RESTfulResult test(){
    	long start = System.currentTimeMillis();
    	Map<String, Object> m = new HashMap<String, Object>();
		m.put("useflag", "1");
		m.put("itemid", "DL31W00110197");
		List<TRmCalpoint> l = tRmCalpointMapper.selectCalpoints(m);
		
		System.out.println("l.size():" + l.size());
		int startDay = 1;
		int endDay = 22;
		while(startDay<=endDay){
//			for(TRmCalpoint tRmCalpoint : l){
//				tRmCalpointValueService.restatCalData(tRmCalpoint, "2020-03-" + String.format("%02d", startDay), "DAY");
//			}
			formulaService.reItemVal("ZYA100W0011R","2020-03-" + String.format("%02d", startDay), "DAY", "");
			// formulaService.reCalculate("ZYA100W0011R","2020-03-" + String.format("%02d", startDay), "DAY");
			startDay++;
		}
		long end = System.currentTimeMillis();
		System.out.println("执行时间：" + (end-start));
    	return success("计量点个数：" + l.size() + "，执行时间：" + (end-start));
    }
    
    @GetMapping(value = "/test1/")
    public RESTfulResult test1(){
    	tRmWorkprocProductValueService.synchronousData(); // 计算并保存工序产品产量
    	tRmWorkprocMaterialValueService.synchronousData(); // 计算并保存工序原材料用量
		tRmWorkprocProductValueService.synchronousOrderData(); // 计算并保存计划工序产品产量
    	return success();
    }
    
    @GetMapping(value = "/indexVal/")
    public RESTfulResult indexVal(){
    	// 指标管理数据生成
		tRmIndexValueService.statData();
    	return success();
    }
    
    /**
     *  重新计算
     * @return
     */
    @GetMapping(value = "/rec/")
    public RESTfulResult rec(){
    	//tRmCalpointValueService.restatAllData("2019-12-01", "DAY");
    	return success();
    }
    
    @GetMapping(value = "/iff/")
    public RESTfulResult ifmesems(){
    	String fid = "202005310179";
    	IfMesEmsSwapfile swapfile = ifMesEmsSwapfileService.getById(fid);
    	System.out.println(swapfile.getProdate());
    	System.out.println(swapfile.toString());
    	return success();
    }
    
}