package com.pqs9200.controller.weeklyreport;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.njcn.enums.LogTypeEnum;
import com.njcn.pojo.advanced.SagEvent;
import com.njcn.pojo.commons.DatePojo;
import com.njcn.pojo.commons.HttpResult;
import com.njcn.pojo.commons.RedisDB;
import com.njcn.pojo.commons.device.LineInfo;
import com.njcn.service.log.UserLogDetailService;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.InstantiateUtil;
import com.njcn.utils.PubUtils;
import com.njcn.utils.redis.JedisManager;
import com.pqs9200.pojo.weeklyreport.AreaPointInfo;
import com.pqs9200.pojo.weeklyreport.SagRate;
import com.pqs9200.service.weeklyreport.WeeklyReportService;


@Controller
@RequestMapping("/weeklyreport")
public class WeeklyReportController {
    @Autowired
    private WeeklyReportService weeklyReportService;
    @Autowired
    private UserLogDetailService userLog;
    private Map<String, ExcelUtil> map;
    private InstantiateUtil<List<AreaPointInfo>> areaPointInfoInstantiateUtil;
    private InstantiateUtil<List<SagEvent>> sagEventInstantiateUtil;
    private InstantiateUtil<List<SagRate>> sagRateInstantiateUtil;
    private InstantiateUtil<List<LineInfo>> tenListInstantiateUtil;
    private InstantiateUtil<String> stringInstantiateUtil;
    byte[] pointInfo;
    byte[] voltageInfo;
    byte[] sag;
    byte[] sagReason;
    byte[] sagEvents;
    byte[] tenList;
    byte[] tenUpList;
    byte[] tenBreakList;
    @Autowired
    private JedisManager jedisManager;

    public WeeklyReportController() {
        areaPointInfoInstantiateUtil = new InstantiateUtil<>();
        sagEventInstantiateUtil = new InstantiateUtil<>();
        sagRateInstantiateUtil = new InstantiateUtil<>();
        tenListInstantiateUtil = new InstantiateUtil<>();
        stringInstantiateUtil = new InstantiateUtil<>();
        pointInfo = stringInstantiateUtil.instantiate("pointInfo");
        voltageInfo = stringInstantiateUtil.instantiate("voltageInfo");
        sag = stringInstantiateUtil.instantiate("sag");
        sagReason = stringInstantiateUtil.instantiate("sagReason");
        sagEvents = stringInstantiateUtil.instantiate("sagEvents");
        tenList = stringInstantiateUtil.instantiate("tenList");
        tenUpList = stringInstantiateUtil.instantiate("tenUpList");
        tenBreakList = stringInstantiateUtil.instantiate("tenBreakList");
        map = new HashMap<>();
    }

    @PostMapping(value = "getPointData")
    @ResponseBody
    public HttpResult getPointData(String startTime, String endTime,Boolean statFlag, HttpServletRequest request) {
        HttpResult result;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getPointData");

        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            userLog.getLog("查询暂降周报", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            return result;
        }

        List<AreaPointInfo> listPointInfo = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
            listPointInfo = weeklyReportService.getPointData(datePojo.getStartTime(), datePojo.getEndTime(),statFlag);
            userLog.getLog("查询暂降周报", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        } catch (Exception e) {
            userLog.getLog("查询暂降周报", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            return PubUtils.assignmentResult(null, 500, "暂降数据获取失败");
        }

        Collections.sort(listPointInfo);

        if (null == listPointInfo) {
            result = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            result = PubUtils.assignmentResult(listPointInfo, 200, "获取暂降次数成功");
        }

        userLog.getLog("查询暂降周报", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, pointInfo, areaPointInfoInstantiateUtil.instantiate(listPointInfo), RedisDB.SHORT_TIME);

        return result;
    }

    @PostMapping(value = "getVoltageData")
    @ResponseBody
    public HttpResult getVoltageData(String startTime, String endTime,Boolean statFlag) {
        HttpResult result;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getVoltageData");

        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return result;
        }

        List<AreaPointInfo> listVoltageInfo = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
            listVoltageInfo = weeklyReportService.getVoltageData(datePojo.getStartTime(), datePojo.getEndTime(),statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "暂降数据获取失败");
        }

        Collections.sort(listVoltageInfo);

        if (null == listVoltageInfo) {
            result = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            result = PubUtils.assignmentResult(listVoltageInfo, 200, "获取暂降次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, voltageInfo, areaPointInfoInstantiateUtil.instantiate(listVoltageInfo), RedisDB.SHORT_TIME);

        return result;
    }

    @SuppressWarnings("unchecked")
    @PostMapping("/createExcel")
    @ResponseBody
    public HttpResult createExcel(String deptspic, String deptsevent, String voltagepic, String voltageevent,
                                  String sagpic) {
        HttpResult httpResult = new HttpResult();
        String[] sheetName = {"暂态总体概况", "暂态严重度统计", "暂态原因统计", "详细事件列表", "暂降次数统计", "暂升次数统计", "短时中断次数统计"};

        ExcelUtil excelUtil = new ExcelUtil(sheetName);
        excelUtil.setUserLog(userLog);
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);
        List<AreaPointInfo> listPointInfo = areaPointInfoInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, pointInfo));
        List<AreaPointInfo> listVoltageInfo = areaPointInfoInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, voltageInfo));
        List<SagEvent> listSag = sagEventInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, sag));
        List<SagRate> listSagReason = sagRateInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, sagReason));
        List<SagEvent> listSagEvents = sagEventInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, sagEvents));
        List<LineInfo> ListTenList = tenListInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, tenList));
        List<LineInfo> ListTenUpList = tenListInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, tenUpList));
        List<LineInfo> ListTenBreakList = tenListInstantiateUtil.deInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndexs, tenBreakList));

        try {
            // 解析图片流
            excelUtil.translate(deptspic, voltagepic, deptsevent, voltageevent, sagpic);

            // 暂态总体概况
            excelUtil.writePointInfo(excelUtil.getListSheet().get(0), listPointInfo, listVoltageInfo);

            // 暂态严重度统计(前五)
            excelUtil.writeSagData(excelUtil.getListSheet().get(1), listSag, 1);

            // 暂态原因统计
            excelUtil.writeSagReason(excelUtil.getListSheet().get(2), listSagReason);

            // 详细事件列表
            excelUtil.writeSagData(excelUtil.getListSheet().get(3), listSagEvents, 2);

            // 暂降次数统计
            excelUtil.writeTenList(excelUtil.getListSheet().get(4), ListTenList);

            // 暂升次数统计
            excelUtil.writeTenUpList(excelUtil.getListSheet().get(5), ListTenUpList);

            // 短时中断次数统计
            excelUtil.writeTenBreakList(excelUtil.getListSheet().get(6), ListTenBreakList);
        } catch (Exception e) {
            httpResult.setCode(500);
            return httpResult;
        }

        map.put(userIndex, excelUtil);
        httpResult.setCode(200);
        return httpResult;
    }

    @GetMapping(value = "/exportExcel")
    public void exportExcel(HttpServletResponse response, HttpServletRequest request) {
        String userIndex = TokenManager.getUserId();
        ExcelUtil excelUtil = map.get(userIndex);
        excelUtil.exportFile(excelUtil.getWorkbook(), response, request);
    }

    @PostMapping(value = "getSagData")
    @ResponseBody
    public HttpResult getSagData(String startTime, String endTime,Boolean statFlag) {
        HttpResult httpResult;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getSagData");

        if (!datePojo.getValidity()) {
            httpResult = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return httpResult;
        }

        List<SagEvent> listSag = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
            listSag = weeklyReportService.getSagData(datePojo.getStartTime(), datePojo.getEndTime(),statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "暂降数据获取失败");
        }

        if (null == listSag) {
            httpResult = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            httpResult = PubUtils.assignmentResult(listSag, 200, "获取暂降次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, sag, sagEventInstantiateUtil.instantiate(listSag), RedisDB.SHORT_TIME);

        return httpResult;
    }

    @PostMapping(value = "getSagReasonData")
    @ResponseBody
    public HttpResult getSagReasonData(String startTime, String endTime,Boolean statFlag) {
        HttpResult httpResult;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getSagReasonData");

        if (!datePojo.getValidity()) {
            httpResult = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return httpResult;
        }

        List<SagRate> listSagReason = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
            listSagReason = weeklyReportService.getSagReasonData(datePojo.getStartTime(), datePojo.getEndTime(),statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "暂降数据获取失败");
        }

        if (null == listSagReason) {
            httpResult = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            httpResult = PubUtils.assignmentResult(listSagReason, 200, "获取暂降次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, sagReason, sagRateInstantiateUtil.instantiate(listSagReason), RedisDB.SHORT_TIME);

        return httpResult;
    }

    @PostMapping(value = "getSagEvents")
    @ResponseBody
    public HttpResult getSagEvents(String startTime, String endTime,Boolean statFlag) {
        HttpResult httpResult;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getSagEvents");

        if (!datePojo.getValidity()) {
            httpResult = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return httpResult;
        }

        List<SagEvent> listSagEvents = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
            listSagEvents = weeklyReportService.getSagEvents(datePojo.getStartTime(), datePojo.getEndTime(),statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "暂降数据获取失败");
        }

        if (null == listSagEvents) {
            httpResult = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            httpResult = PubUtils.assignmentResult(listSagEvents, 200, "获取暂降次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, sagEvents, sagEventInstantiateUtil.instantiate(listSagEvents), RedisDB.SHORT_TIME);

        return httpResult;
    }


    @PostMapping(value = "getTenList")
    @ResponseBody
    public HttpResult getTenList(String startTime, String endTime,Boolean statFlag) {
        HttpResult httpResult;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getTenList");

        if (!datePojo.getValidity()) {
            httpResult = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return httpResult;
        }

        List<LineInfo> lineInfo = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
        	lineInfo = weeklyReportService.getTenList(datePojo.getStartTime(), datePojo.getEndTime(),1,statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "暂降数据获取失败");
        }

        if (null == lineInfo) {
            httpResult = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            httpResult = PubUtils.assignmentResult(lineInfo, 200, "获取暂降次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, tenList, tenListInstantiateUtil.instantiate(lineInfo), RedisDB.SHORT_TIME);

        return httpResult;
    }

    @PostMapping(value = "getTenUpList")
    @ResponseBody
    public HttpResult getTenUpList(String startTime, String endTime,Boolean statFlag) {
        HttpResult httpResult;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getTenUpList");

        if (!datePojo.getValidity()) {
            httpResult = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return httpResult;
        }

        List<LineInfo> lineInfo = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
        	lineInfo = weeklyReportService.getTenList(datePojo.getStartTime(), datePojo.getEndTime(),2,statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "暂升数据获取失败");
        }

        if (null == lineInfo) {
            httpResult = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            httpResult = PubUtils.assignmentResult(lineInfo, 200, "获取暂升次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, tenUpList, tenListInstantiateUtil.instantiate(lineInfo), RedisDB.SHORT_TIME);

        return httpResult;
    }

    @PostMapping(value = "getTenBreakList")
    @ResponseBody
    public HttpResult getTenBreakList(String startTime, String endTime,Boolean statFlag) {
        HttpResult httpResult;
        DatePojo datePojo = PubUtils.validateDate(startTime, endTime, "getTenBreakList");

        if (!datePojo.getValidity()) {
            httpResult = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return httpResult;
        }

        List<LineInfo> lineInfo = new ArrayList<>();
        String userIndex = TokenManager.getUserId();
        byte[] userIndexs = stringInstantiateUtil.instantiate(userIndex);

        try {
        	lineInfo = weeklyReportService.getTenList(datePojo.getStartTime(), datePojo.getEndTime(),3,statFlag);
        } catch (Exception e) {
            return PubUtils.assignmentResult(null, 500, "短时中断数据获取失败");
        }

        if (null == lineInfo) {
            httpResult = PubUtils.assignmentResult(null, 500, "无暂降数据");
        } else {
            httpResult = PubUtils.assignmentResult(lineInfo, 200, "获取短时中断次数成功");
        }

        jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndexs, tenBreakList, tenListInstantiateUtil.instantiate(lineInfo), RedisDB.SHORT_TIME);

        return httpResult;
    }
}
