package com.inspect.statistics.service.impl;

import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.inspect.base.core.exception.ServiceException;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.web.domain.AjaxResult;
import com.inspect.statistics.domain.StatisticsPatrolResult;
import com.inspect.statistics.mapper.StatisticsPatrolResultMapper;
import com.inspect.statistics.service.PatrolStatisticsService;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.inspect.message.MessageUtils;

@Service
public class PatrolStatisticsServiceImpl implements PatrolStatisticsService {
    private final Logger logger = LoggerFactory.getLogger(PatrolStatisticsService.class);
    @Resource
    StatisticsPatrolResultMapper resultMapper;

    @Autowired
    private MessageUtils messageUtils;

    public List<StatisticsPatrolResult> queryPatrolResult(StatisticsPatrolResult result) {
        return this.resultMapper.queryPatrolResult(result);
    }

    public List<StatisticsPatrolResult> queryPatrolResultMulti(StatisticsPatrolResult result) {
        return this.resultMapper.queryPatrolResultMulti2(result);
    }

    public List<StatisticsPatrolResult> queryPatrolResultMultiExport(StatisticsPatrolResult result) {
        return this.resultMapper.queryPatrolResultMultiExport(result);
    }

    public Map<String, List<StatisticsPatrolResult>> queryPatrolResultCharts(StatisticsPatrolResult result) {
        List<StatisticsPatrolResult> list = this.resultMapper.queryPatrolResult(result);
        return list.stream().collect(Collectors.groupingBy((item) -> item.getPatrolDeviceName()));
    }

    public JSONArray chartsMulti(StatisticsPatrolResult result) {
//        List<StatisticsPatrolResult> list = this.resultMapper.queryPatrolResultMulti(result);
        List<StatisticsPatrolResult> list = this.resultMapper.queryPatrolResultMulti2(result);
        Map<String, List<StatisticsPatrolResult>> group = list.stream().collect(Collectors.groupingBy(StatisticsPatrolResult::getDeviceId));
        JSONArray jsonArray = new JSONArray();

        for (String deviceId : group.keySet()) {
            List<StatisticsPatrolResult> resultList = group.get(deviceId);
            if (CollectionUtils.isNotEmpty(resultList)) {
                StatisticsPatrolResult statisticsPatrolResult = resultList.get(0);
                String deviceName = statisticsPatrolResult.getDeviceName();
                JSONObject job = new JSONObject();
                job.put("deviceId", deviceId);
                job.put("deviceName", deviceName);
                job.put("data", resultList);
                jsonArray.add(job);
            }
        }

        return jsonArray;
    }

    public void verifyParam(StatisticsPatrolResult result) {
        if (StringUtils.isBlank(result.getDeviceId()) && StringUtils.isBlank(result.getDeviceIds())) {
            throw new ServiceException("设备ID不能为空");
        } else if (StringUtils.isBlank(result.getRecognitionType())) {
            throw new ServiceException("识别类型不能为空");
        } else if (result.getEndTime() == null || result.getStartTime() == null) {
            throw new ServiceException("请选择时间区间");
        }
    }

    public AjaxResult queryNumTypeInfo(Integer num, String deviceId, String patrolDeviceCode) {
        List<StatisticsPatrolResult> list = this.resultMapper.queryNumTypeInfo(num, deviceId, patrolDeviceCode);
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException("未查询到该设备的表计任务");
        } else {
            boolean warning = true;
            String firstValue;
            if (list.size() < num) {
                warning = false;
            } else {
                firstValue = list.get(0).getValue();

                for (int i = 1; i < list.size(); ++i) {
                    String value = list.get(i).getValue();
                    if (!firstValue.equals(value)) {
                        warning = false;
                        break;
                    }
                }
            }

            if (warning) {
                firstValue = "表计任务在" + num + "次内，数据未发生变化，巡视结果有误";
                StatisticsPatrolResult patrolResult = list.get(0);
                patrolResult.setWarning(1);
                return AjaxResult.success(firstValue, list.get(0));
            } else {
                return AjaxResult.success();
            }
        }
    }

    public AjaxResult analyse(Integer type, String lineIds, double threshold) {
        AjaxResult result = AjaxResult.success();
        List<StatisticsPatrolResult> patrolResults = this.resultMapper.queryResultByIds(type, lineIds);
        if (!CollectionUtils.isEmpty(patrolResults) && patrolResults.size() == lineIds.split(StringUtils.COMMA).length) {
            List sortList = patrolResults.stream().sorted(Comparator.comparingDouble((r) -> Double.parseDouble(r.getValue()))).collect(Collectors.toList());
            sortList.get(0);
            StatisticsPatrolResult patrolResult1 = patrolResults.get(0);
            StatisticsPatrolResult patrolResult2 = patrolResults.get(patrolResults.size() - 1);
            String errorMsg;
            switch (type) {
                case 1:
                    double value1 = Double.parseDouble(patrolResult1.getValue());
                    double value2 = Double.parseDouble(patrolResult2.getValue());
                    if (Math.abs(value1 - value2) > threshold) {
                        errorMsg = "表计类任务对比，数据差值超过阈值";
                        patrolResult1.setWarning(1);
                        result = AjaxResult.success(errorMsg, patrolResult1);
                    }
                    break;
                case 2:
                    if (!StringUtils.equals(patrolResult1.getValue(), patrolResult2.getValue())) {
                        errorMsg = "位置状态类对比，数据不一致";
                        patrolResult1.setWarning(1);
                        result = AjaxResult.success(errorMsg, patrolResult1);
                    }
                    break;
                case 3:
                default:
                    this.logger.warn("数据对比分析，传入的类型不在处理范围内，不予处理");
                    throw new ServiceException("数据对比分析，传入的类型不在处理范围内");
                case 4:
                    double value3 = Double.parseDouble(patrolResult1.getValue());
                    double value4 = Double.parseDouble(patrolResult2.getValue());
                    if (Math.abs(value3 - value4) > threshold) {
                        errorMsg = "测温类任务对比，数据差值超过阈值";
                        patrolResult1.setWarning(1);
                        result = AjaxResult.success(errorMsg, patrolResult1);
                    }
            }

            return result;
        } else {
            throw new ServiceException("数据对比分析失败，传入类型不正确或数据条数不正确");
        }
    }

    public void configExport(List<StatisticsPatrolResult> patrolResults, StatisticsPatrolResult result, HttpServletResponse response) throws IOException {
        String configCol = result.getConfigCol();
        String[] configColArr = configCol.split(StringUtils.COMMA);
        if (ArrayUtils.isEmpty(configColArr)) {
            throw new ServiceException("请选择需要导出的字段");
        } else {
            ExcelWriter writer = new ExcelWriter();
            HashMap<String, String> colMap = this.colMap();
            for (String col : configColArr) {
                if (StringUtils.isNotBlank(colMap.get(col))) {
                    writer.addHeaderAlias(col, colMap.get(col));
                }
            }

            long now = System.currentTimeMillis();
            String filename = messageUtils.get("巡视结果") + now;
            filename = URLEncoder.encode(filename, "utf8");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".xls");
            response.setCharacterEncoding("utf-8");
            writer.setOnlyAlias(true);
            writer.write(patrolResults, true);
            writer.flush(response.getOutputStream());
            writer.close();
        }
    }

    public HashMap<String, String> colMap() {
        HashMap<String, String> colMap = new HashMap<>();
        colMap.put("lineId", messageUtils.get("线路名称"));
        colMap.put("patrolDeviceName", messageUtils.get("巡视设备名称"));
        colMap.put("patrolDeviceCode", messageUtils.get("巡视设备编码"));
        colMap.put("taskName", messageUtils.get("任务名称"));
        colMap.put("taskCode", messageUtils.get("任务编码"));
        colMap.put("deviceName", messageUtils.get("设备点位"));
        colMap.put("deviceId", messageUtils.get("设备点位ID"));
        colMap.put("value", messageUtils.get("识别结果"));
        colMap.put("valueUnit", messageUtils.get("识别结果带单位"));
        colMap.put("time", messageUtils.get("巡视时间"));
        colMap.put("recognitionType", messageUtils.get("识别类型"));
        colMap.put("fileType", messageUtils.get("文件类型"));
        colMap.put("taskPatrolledId", messageUtils.get("巡视任务执行ID"));
        colMap.put("valid", messageUtils.get("结论"));
        colMap.put("patrolStatusName", messageUtils.get("归档状态"));
        colMap.put("checkResult", messageUtils.get("审核结果"));
        colMap.put("dataType", messageUtils.get("巡视结果数据来源"));
        return colMap;
    }
}
