package com.steerinfo.ems.trmcalpointvalue.controller;

import com.steerinfo.auth.utils.JwtUtil;
import com.steerinfo.framework.controller.BaseRESTfulController;
import com.steerinfo.framework.controller.RESTfulResult;
import com.steerinfo.framework.service.pagehelper.PageList;
import com.steerinfo.ems.formula.service.IFormulaService;
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.model.TRmCalpointValue;
import com.steerinfo.ems.trmcalpointvalue.service.ITRmCalpointValueService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * TRmCalpointValue RESTful接口：
 * @author generator
 * @version 1.0-SNAPSHORT 2019-10-17 03:55
 * 类描述
 * 修订历史：
 * 日期：2019-10-17
 * 作者：generator
 * 参考：
 * 描述：TRmCalpointValue RESTful接口
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@RestController
@RequestMapping("/${api.version}/trmcalpointvalues")
public class TRmCalpointValueController extends BaseRESTfulController {
	private static final Logger logger = LoggerFactory.getLogger(TRmCalpointValueController.class);

    @Autowired
    ITRmCalpointValueService tRmCalpointValueService;
    
    @Autowired
    ITRmCalpointService tRmCalpointService;
    
    @Autowired
    private TRmCalpointMapper tRmCalpointMapper;
    
    @Autowired
    IFormulaService formulaService;

    @ApiOperation(value="获取列表", notes="分页查询")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pageNum", value = "查询页数", required = false, dataType = "Integer"),
        @ApiImplicitParam(name = "pageSize", value = "每页记录数", required = false, dataType = "Integer")
    })
    //@RequiresPermissions("trmcalpointvalue:view")
    @GetMapping(value = "/")
    public RESTfulResult list(@RequestParam HashMap parmas,Integer pageNum, Integer pageSize){
        PageList<TRmCalpointValue> list = tRmCalpointValueService.queryForPage(parmas, pageNum, pageSize);
        return success(list);
    }

    @ApiOperation(value="获取列表", notes="分页模糊查询")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pageNum", value = "查询页数", required = false, dataType = "Integer"),
        @ApiImplicitParam(name = "pageSize", value = "每页记录数", required = false, dataType = "Integer")
    })
    //@RequiresPermissions("trmcalpointvalue:view")
    @GetMapping(value = "/like/")
    public RESTfulResult listLike(@RequestParam HashMap parmas,Integer pageNum, Integer pageSize){
        PageList<TRmCalpointValue> list = tRmCalpointValueService.queryLikeForPage(parmas, pageNum, pageSize);
        return success(list);
    }
    
    @ApiOperation(value="创建", notes="根据TRmCalpointValue对象创建")
    @ApiImplicitParam(name = "tRmCalpointValue", value = "详细实体tRmCalpointValue", required = true, dataType = "TRmCalpointValue")
    //@RequiresPermissions("trmcalpointvalue:create")
    @PostMapping(value = "/")
    public RESTfulResult add(@ModelAttribute TRmCalpointValue model){
        TRmCalpointValue tRmCalpointValue = tRmCalpointValueService.add(model);
        return success(tRmCalpointValue);
    }

    @ApiOperation(value="获取详细信息", notes="根据主键来获取详细信息")
    @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true, dataType = "String")
    //@RequiresPermissions("trmcalpointvalue:view")
    @PostMapping(value = "/info", produces  = "application/json;charset=UTF-8")
    public RESTfulResult get(@RequestBody TRmCalpointValue model){
    	if(model.getClock() == null || model.getClock().isEmpty()){
    		return failed(null, "请传入时间");
    	}
    	if(model.getTimegranid() == null || model.getTimegranid().isEmpty()){
    		return failed(null, "请传入时间粒度");
    	}
    	if(model.getItemid() == null || model.getItemid().isEmpty()){
    		return failed(null, "请传入计量点编号");
    	}
    	HashMap<String, Object> m = new HashMap<String, Object>();
    	m.put("clock", model.getClock());
    	m.put("timegranid", model.getTimegranid());
    	m.put("itemid", model.getItemid());
        model.setId(m);
        TRmCalpointValue tRmCalpointValue = tRmCalpointValueService.getById(m);
        return success(tRmCalpointValue);
    }

    @ApiOperation(value="更新详细信息", notes="根据url的id来指定更新对象，并根据传过来的tRmCalpointValue信息来更新详细信息")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true, dataType = "String"),
        @ApiImplicitParam(name = "tRmCalpointValue", value = "详细实体tRmCalpointValue", required = true, dataType = "TRmCalpointValue")
    })
    //@RequiresPermissions("trmcalpointvalue:update")
    @PutMapping(value = "/update", produces  = "application/json;charset=UTF-8")
    public RESTfulResult update(@RequestBody TRmCalpointValue model){
    	if(model.getClock() == null || model.getClock().isEmpty()){
    		return failed(null, "请传入开始时间");
    	}
    	if(model.getTimegranid() == null || model.getTimegranid().isEmpty()){
    		return failed(null, "请传入时间粒度");
    	}
    	if(model.getItemid() == null || model.getItemid().isEmpty()){
    		return failed(null, "请传入计量点编号");
    	}
    	if(model.getApportvalue() == null){
    		return failed(null, "请传入最终值");
    	}
    	if(model.getActualvalue() == null){
    		return failed(null, "请传入计算值");
    	}
    	if(model.getCorrectvalue() == null){
    		return failed(null, "请传入修正值");
    	}
    	if(model.getActualvalue().add(model.getCorrectvalue()).compareTo(model.getApportvalue()) != 0){
    		return failed(null, "数值错误，最终值 = 计算值 + 修正值");
    	}
    	HashMap<String, Object> m = new HashMap<String, Object>();
    	m.put("clock", model.getClock());
    	m.put("timegranid", model.getTimegranid());
    	m.put("itemid", model.getItemid());
        model.setId(m);
        TRmCalpointValue tRmCalpointValue = tRmCalpointValueService.modifyAndCompute(model);
        if(tRmCalpointValue == null){
        	return failed(null, "修改对象不存在");
        }
        return success(tRmCalpointValue);
    }

    @ApiOperation(value="删除", notes="根据主键来指定删除对象")
    @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true, dataType = "String")
    //@RequiresPermissions("trmcalpointvalue:delete")
    @DeleteMapping(value = "/delete", produces  = "application/json;charset=UTF-8")
    public RESTfulResult delete(@RequestBody TRmCalpointValue model){
    	if(model.getClock() == null || model.getClock().isEmpty()){
    		return failed(null, "请传入开始时间");
    	}
    	if(model.getTimegranid() == null || model.getTimegranid().isEmpty()){
    		return failed(null, "请传入时间粒度");
    	}
    	if(model.getItemid() == null || model.getItemid().isEmpty()){
    		return failed(null, "请传入计量点编号");
    	}
    	HashMap<String, Object> m = new HashMap<String, Object>();
    	m.put("clock", model.getClock());
    	m.put("timegranid", model.getTimegranid());
    	m.put("itemid", model.getItemid());
        model.setId(m);
        tRmCalpointValueService.delete(m);
        return success();
    }

    @ApiOperation(value="更新详细信息", notes="根据url的id来指定更新对象，并根据传过来的tRmCalpointValue信息来更新详细信息")
    @ApiImplicitParam(name = "tRmCalpointValue", value = "详细实体tRmCalpointValue", required = true, dataType = "TRmCalpointValue")
    //@RequiresPermissions("trmcalpointvalue:update")
    @PutMapping(value = "/batchupdate", produces  = "application/json;charset=UTF-8")
    public RESTfulResult batchupdate(@RequestBody TRmCalpointValue[] model){
        int failnum = 0;
        String failmsg = "";
        List<String> errorid = new ArrayList<>();
        for (int i = 0; i< model.length; i++) {
            if (model[i].getClock() == null || model[i].getClock().isEmpty()) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "id为" + model[i].getItemid() + "数据请传入开始时间";
                continue;
            }
            if (model[i].getTimegranid() == null || model[i].getTimegranid().isEmpty()) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）数据请传入时间粒度";
                continue;
            }
            if (model[i].getItemid() == null || model[i].getItemid().isEmpty()) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）数据请传入计量点编号";
                continue;
            }
            if (model[i].getApportvalue() == null) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）数据请传入最终值";
                continue;
            }
            if (model[i].getActualvalue() == null) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）数据请传入计算值";
                continue;
            }
            if (model[i].getCorrectvalue() == null) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）数据请传入修正值";
                continue;
            }
            if (model[i].getActualvalue().add(model[i].getCorrectvalue()).compareTo(model[i].getApportvalue()) != 0) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）数据数值错误，最终值 = 计算值 + 修正值";
                continue;
            }
            HashMap<String, Object> m = new HashMap<String, Object>();
            m.put("clock", model[i].getClock());
            m.put("timegranid", model[i].getTimegranid());
            m.put("itemid", model[i].getItemid());
            model[i].setId(m);
            model[i].setUpman(JwtUtil.getUseridByToken());
            model[i].setUptime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            TRmCalpointValue tRmCalpointValue = tRmCalpointValueService.modifyAndCompute(model[i]);
            if (tRmCalpointValue == null) {
                failnum++;
                errorid.add(model[i].getItemid());
                failmsg+= "主键（id：" + model[i].getItemid() + "时间粒度:" + model[i].getTimegranid() + "时间:" + model[i].getClock() + "）修改对象不存在";
                continue;
            }
        }
        if(failnum > 0){
            return success(errorid,"51","本次共修改" + model.length + "条数据,其中成功" + (model.length - failnum) + "条,失败" + failnum + "条");
        }
        return success();
    }
    
    @ApiOperation(value="批量重新计算", notes="根据url的id来指定更新对象，并根据传过来的tRmCalpointValue信息来更新详细信息,从小时表数据更新")
    @ApiImplicitParam(name = "tRmCalpointValue", value = "详细实体tRmCalpointValue", required = true, dataType = "TRmCalpointValue")
    //@RequiresPermissions("trmcalpointvalue:update")
    @PutMapping(value = "/batchCompute", produces  = "application/json;charset=UTF-8")
    public RESTfulResult batchCompute(@RequestBody TRmCalpointValue[] model){
    	if(model.length<1){
    		return failed(null, "请勾选计量点数据");
    	}
    	// 重排计算顺序
    	List<String> l = new ArrayList<String>();
    	for (int i = 0; i< model.length; i++) {
    		TRmCalpointValue tv = model[i];
    		TRmCalpoint tRmCalpoint = tRmCalpointService.getById(tv.getItemid());
    		if(tRmCalpoint!=null && tv.getClock()!=null && tv.getTimegranid()!=null){
    			String seq = tRmCalpoint.getSeqno()==null?"0":tRmCalpoint.getSeqno()+"";
    			l.add(tRmCalpoint.getItemtype() + "," +tv.getTimegranid()+","+tv.getClock()+","+tv.getItemid()+","+seq);
    		}
    	}
    	// 调整计算顺序，虚拟点靠后0
		Collections.sort(l, new Comparator<String>() {
			public int compare(String s1, String s2) {
				String itemtype1 = s1.split(",")[0];
				String timegranid1 = s1.split(",")[1];
				String clock1 = s1.split(",")[2];
				String seqno1 = s1.split(",")[4];
				Date d1 = new Date();
				String itemtype2 = s2.split(",")[0];
				String timegranid2 = s2.split(",")[1];
				String clock2 = s2.split(",")[2];
				String seqno2 = s2.split(",")[4];
				Date d2 = new Date();
				try {
					if (itemtype1.equalsIgnoreCase(itemtype2)) {
						Calendar cal = Calendar.getInstance();
						if (timegranid1.equalsIgnoreCase("year")) {
							cal.setTime(new SimpleDateFormat("yyyy-MM-dd HH").parse(clock1 + "-12-31 23"));
							d1 = cal.getTime();
						}else if(timegranid1.equalsIgnoreCase("month")){
							cal.setTime(new SimpleDateFormat("yyyy-MM").parse(clock1));
							cal.add(Calendar.MONTH, 1);
							cal.add(Calendar.HOUR_OF_DAY, -3);
							d1 = cal.getTime();
						}else if(timegranid1.equalsIgnoreCase("day")){
							cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(clock1));
							d1 = cal.getTime();
						}else if(timegranid1.equalsIgnoreCase("shift")){
							cal.setTime(new SimpleDateFormat("yyyy-MM-dd HH").parse(clock1));
							d1 = cal.getTime();
						}
						if (timegranid2.equalsIgnoreCase("year")) {
							cal.setTime(new SimpleDateFormat("yyyy-MM-dd HH").parse(clock2 + "-12-31 23"));
							d2 = cal.getTime();
						}else if(timegranid2.equalsIgnoreCase("month")){
							cal.setTime(new SimpleDateFormat("yyyy-MM").parse(clock2));
							cal.add(Calendar.MONTH, 1);
							cal.add(Calendar.HOUR_OF_DAY, -3);
							d2 = cal.getTime();
						}else if(timegranid2.equalsIgnoreCase("day")){
							cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(clock2));
							d2 = cal.getTime();
						}else if(timegranid2.equalsIgnoreCase("shift")){
							cal.setTime(new SimpleDateFormat("yyyy-MM-dd HH").parse(clock2));
							d2 = cal.getTime();
						}
						if(d1.getTime() > d2.getTime()){
							return 1;
						}else if(d1.getTime() < d2.getTime()){
							return -1;
						}else {
							if(Integer.valueOf(seqno1) > Integer.valueOf(seqno2)){
								return 1;
							}else if(Integer.valueOf(seqno1) < Integer.valueOf(seqno2)){
								return -1;
							}else{
								return 0;
							}
						}
					} else {
						if (itemtype1.equalsIgnoreCase("VIRTUAL")) {
							return 1;
						} else if (itemtype2.equalsIgnoreCase("VIRTUAL")) {
							return -1;
						} else {
							return 0;
						}
					}
				} catch (ParseException e) {
					return 0;
				}
			}
		});
		for (int i = 0; i< l.size(); i++) {
			tRmCalpointValueService.restatCalpData(l.get(i).split(",")[3], l.get(i).split(",")[2], l.get(i).split(",")[1], JwtUtil.getUseridByToken());
		}
    	return success();
    }
    
    @ApiOperation(value="获得计量点时间段数据", notes="获得计量点时间段数据,期初、期末、计算值")
    @GetMapping(value = "/getCalpointValue")
    public RESTfulResult getCalpointValue(@RequestParam HashMap<String, Object> parmas){
    	if(parmas.get("start")==null || parmas.get("start").toString().isEmpty()){
    		return failed(null, "请传入起始时间");
    	}
    	if(parmas.get("end")==null || parmas.get("end").toString().isEmpty()){
    		return failed(null, "请传入结束时间");
    	}
    	try {
    		String start = parmas.get("start").toString();
    		String end = parmas.get("end").toString();
			if(new SimpleDateFormat("yyyy-MM-dd").parse(start).after(new Date())){
				return failed(null, "起始时间不能在今天之后");
			}
			if(new SimpleDateFormat("yyyy-MM-dd").parse(end).after(new Date())){
				return failed(null, "结束时间不能在今天之后");
			}
		} catch (ParseException e) {
			return failed(null, "时间格式错误");
		}
    	if(parmas.get("ids")==null || parmas.get("ids").toString().isEmpty()){
    		return failed(null, "请传入计量点");
    	}
    	List<Map<String, Object>> list  = tRmCalpointValueService.getCalpointValue(parmas);
        return success(list);
    }
    
    @ApiOperation(value="重新计算单个计量点数据")
    //@RequiresPermissions("trmcalpointvalue:view")
    @GetMapping(value = "/restatCal")
    public RESTfulResult restatCal(@RequestParam HashMap<String, Object> parmas, String clock, String clocke, String timegranid){
    	if (parmas == null) {
    		parmas = new HashMap<String, Object>();
    	}
		if (clock==null || clock.isEmpty()) {
    		return failed(null, "请传入起始时间");
    	}
		if (timegranid==null || timegranid.isEmpty()) {
    		return failed(null, "请传入时间粒度");
    	}
		parmas.put("useflag", "1");
		// 查询需要统计的计量点信息
		List<TRmCalpoint> l = tRmCalpointMapper.selectCalpoints(parmas);
		String res = "";
		for(TRmCalpoint tRmCalpoint : l){
			res = formulaService.reItemVal(tRmCalpoint.getItemid(),clock,timegranid,clocke);
		}
		if(!res.isEmpty()){
			return failed(null, res);
		}
        return success();
    }
    
    @ApiOperation(value="重新生成数据", notes="")
    //@RequiresPermissions("trmcalpointvalue:view")
    @GetMapping(value = "/reData")
    public RESTfulResult reData(@RequestParam HashMap<String, Object> parmas, String clock, String clocke, String timegranid){
    	if (clock==null || clock.isEmpty()) {
    		return failed(null, "请传入起始时间");
    	}
    	if (clocke==null || clocke.isEmpty()) {
    		return failed(null, "请传入结束时间");
    	}
		if (timegranid==null || timegranid.isEmpty()) {
			return failed(null, "请传入时间粒度");
    	}
    	if(parmas.get("locateid") != null && !parmas.get("locateid").toString().isEmpty()){
            String locateid = parmas.get("locateid").toString();
            if(!locateid.startsWith("'")){
            	locateid = "'" + locateid.replaceAll(",", "','").replaceAll("，", "','") + "'";
            }
            parmas.put("locateid", locateid);
        }
    	if(parmas.get("networkid") != null && !parmas.get("networkid").toString().isEmpty()){
            String networkid = parmas.get("networkid").toString();
            if(!networkid.startsWith("'")){
            	networkid = "'" + networkid.replaceAll(",", "','").replaceAll("，", "','") + "'";
            }
            parmas.put("networkid", networkid);
        }
    	if(parmas.get("energytypeid") != null && !parmas.get("energytypeid").toString().isEmpty()){
            String energytypeid = parmas.get("energytypeid").toString();
            if(!energytypeid.startsWith("'")){
            	energytypeid = "'" + energytypeid.replaceAll(",", "','").replaceAll("，", "','") + "'";
            }
            parmas.put("energytypeid", energytypeid);
        }
    	if(parmas.get("energyid") != null && !parmas.get("energyid").toString().isEmpty()){
            String energyid = parmas.get("energyid").toString();
            if(!energyid.startsWith("'")){
            	energyid = "'" + energyid.replaceAll(",", "','").replaceAll("，", "','") + "'";
            }
            parmas.put("energyid", energyid);
        }
    	if(parmas.get("propertyid") != null && !parmas.get("propertyid").toString().isEmpty()){
            String propertyid = parmas.get("propertyid").toString();
            if(!propertyid.startsWith("'")){
            	propertyid = "'" + propertyid.replaceAll(",", "','").replaceAll("，", "','") + "'";
            }
            parmas.put("propertyid", propertyid);
        }
    	String res = "";
    	parmas.put("useflag", "1");
		// 查询需要统计的计量点信息
		List<TRmCalpoint> l = tRmCalpointMapper.selectLikeByParameters(parmas);
		int size = l.size();
		for(int i = 0; i<l.size(); i++){
			if(res.isEmpty()){
				res = formulaService.reItemVal(l.get(i).getItemid(),clock,timegranid,clocke);
			}else{
				formulaService.reItemVal(l.get(i).getItemid(),clock,timegranid,clocke);
			}
			logger.info("剩下要处理的项目数：" + (size-1-i) + "(" + size + ")");
		}
		if(!res.isEmpty()){
			return success(null, res);
		}
        return success(null, res);
    }
}
