package com.gyee.alarm.service;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gyee.alarm.init.CacheContext;
import com.gyee.alarm.model.auto.ProEconAlarmType;
import com.gyee.alarm.model.auto.ProEconEarlyReport;
import com.gyee.alarm.model.auto.ProEconEarlyReportWt;
import com.gyee.alarm.model.auto.ProEconInspectOrder;
import com.gyee.alarm.model.vo.AjaxResult;
import com.gyee.alarm.model.vo.InspectOrderDto;
import com.gyee.alarm.service.auto.IProEconEarlyReportService;
import com.gyee.alarm.service.auto.IProEconEarlyReportWtService;
import com.gyee.alarm.service.auto.IProEconInspectOrderService;

import com.gyee.alarm.util.DateUtils;
import com.gyee.alarm.util.SnowflakeGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @auther: Wanghs
 * @date: 2022-09-09
 */
@Service
public class InspectOrderService  {

    @Resource
    private IProEconEarlyReportWtService proEconEarlyReportWtService;
    @Resource
    private IProEconInspectOrderService proEconInspectOrderService;

    @Resource
    private EarlyReportWindturbineService earlyReportWindturbineService;



    @Resource
    private EarlyReportService earlyReportService;
    @Resource
    private IProEconEarlyReportService proEconEarlyReportService;
    public boolean saveInspectOrder(ProEconInspectOrder order) {

        boolean saveOrder = false;
        boolean updateReport = false;

        saveOrder = proEconInspectOrderService.save(order);

        ProEconEarlyReportWt verifyReport = proEconEarlyReportWtService.getById(order.getReportWindturbineId());

        if (verifyReport != null) {
            verifyReport.setVerified(true);
            updateReport = proEconEarlyReportWtService.updateById(verifyReport);
        }
        if (saveOrder && updateReport)
            return true;
        else {
            throw new RuntimeException();
        }

    }



    public IPage<InspectOrderDto> getInspectOrderDtoPage(Integer pageNum, Integer pageSize, String windturbineId, Optional<Integer> step, Date startTime, Date endTime) {
        //节点 1-待审核，2-已审核，3-未计划，4-已计划，5-未巡检，6-已巡检
        IPage<ProEconInspectOrder> inspectOrderByStep = getInspectOrderByStep(pageNum, pageSize, step, windturbineId, startTime, endTime);
        List<InspectOrderDto> inspectOrderDtos = packInspectOrderInspectOrderDto(inspectOrderByStep.getRecords());
        Page<InspectOrderDto> pageDto = new Page<>();
        pageDto.setPages(inspectOrderByStep.getPages()).setRecords(inspectOrderDtos).setTotal(inspectOrderByStep.getTotal()).setCurrent(inspectOrderByStep.getCurrent()).setSize(inspectOrderByStep.getSize());
        return pageDto;
    }

    public List<InspectOrderDto> getInspectOrderDtoPage(String stationId, String windturbineId) {
        List<ProEconEarlyReportWt> noVerifiedPort = getNoVerifiedPort(stationId, windturbineId);
        List<InspectOrderDto> inspectOrderDtos = packWindturbineReportInspectOrderDto(noVerifiedPort);
        return inspectOrderDtos;
    }

    /**
     * @param
     * @return
     * @return java.util.List<com.gyee.wisdom.alarm.sharding.entity.ProEconEarlyReportWt>
     * @author Wanghs
     * @description 获取最近的一批报告，没有被审核过的风机报告
     * @date 2022/9/12
     **/
    private List<ProEconEarlyReportWt> getNoVerifiedPort(String stationId, String windturbineId) {

        List<ProEconEarlyReportWt> resultList = new ArrayList<>();

        //获取id最大的数据
        ProEconEarlyReport lastEarlyReport = earlyReportService.findLastEarlyReport();
        if(lastEarlyReport==null)
            return resultList;
        // 根据最后一条数据获取报告生成日期
        Date date = DateUtils.truncate(lastEarlyReport.getReportDate());
        QueryWrapper<ProEconEarlyReport> wrapper = new QueryWrapper<ProEconEarlyReport>().ge("REPORTDATE", date);
        List<ProEconEarlyReport> earlyReportList = proEconEarlyReportService.list(wrapper);
        List<String> collect = earlyReportList.stream().map(s -> s.getId()).collect(Collectors.toList());
        List<ProEconEarlyReportWt> reportWindturbineList = earlyReportWindturbineService.getReportWindturbineByReportId(collect);
        //筛选出 不是对比数据，且不是全场平局，且没有审核过的数据
        reportWindturbineList = reportWindturbineList.stream().filter(s -> s.getVerified() == false && s.getCompared() == false && !s.getWindturbineId().equals("全场平均")).collect(Collectors.toList());

        if (com.gyee.alarm.util.StringUtils.isNotBlank(windturbineId))
            reportWindturbineList = reportWindturbineList.stream().filter(s -> s.getWindturbineId().equals(windturbineId)).collect(Collectors.toList());
        if (StringUtils.isNotBlank(stationId))
            reportWindturbineList = reportWindturbineList.stream().filter(s -> s.getEarlyReport().getStationId().equals(stationId)).collect(Collectors.toList());

        return reportWindturbineList;

    }

    private List<InspectOrderDto> packWindturbineReportInspectOrderDto(List<ProEconEarlyReportWt> earlyReportWindturbineList) {
        List<InspectOrderDto> resultList = new ArrayList<>();

        earlyReportWindturbineList.stream().forEach(s -> {

            InspectOrderDto dto = new InspectOrderDto()
                    .setReportWindturbineId(s.getId())
                    .setWindturbineId(s.getWindturbineId())
                    .setWindpowerStationId(s.getEarlyReport().getStationId())
                    .setEarlyReport(true)
                    .setEarlyReportWindturbine(s);
            resultList.add(dto);
        });
        return resultList;
    }


    private IPage<ProEconInspectOrder> getInspectOrderByStep(int pageNum, int pageSize, Optional<Integer> step, String windturbineId, Date startTime, Date endTime) {
        List<ProEconInspectOrder> resultList = new ArrayList<>();
        //节点 1-待审核，2-已审核，3-未计划，4-已计划，5-未巡检，6-已巡检
        QueryWrapper<ProEconInspectOrder> wrapper = new QueryWrapper<>();

        if (step.isPresent()) {
            if (step.get() == 2 || step.get() == 3) {
                wrapper.isNotNull("VERIFYTIME");//评审时间不为空
                wrapper.isNull("CREATEPLANTIME");//计划时间为空
                wrapper.isNull("INSPECTTIME");//巡检时间为空
            } else if (step.get() == 4 || step.get() == 5) {
                wrapper.isNotNull("VERIFYTIME");//评审时间不为空
                wrapper.isNotNull("CREATEPLANTIME");//计划时间不为空
                wrapper.isNull("INSPECTTIME");//巡检时间为空
            } else if (step.get() == 6) {
                wrapper.isNotNull("VERIFYTIME");//评审时间不为空
                wrapper.isNotNull("CREATEPLANTIME");//计划时间不为空
                wrapper.isNotNull("INSPECTTIME");//巡检时间不为空
            }
        }

        if (StringUtils.isNotBlank(windturbineId))
            wrapper.eq("WINDTURBINEID", windturbineId);
        if (startTime != null)
            wrapper.gt("VERIFYTIME", startTime);
        if (endTime != null)
            wrapper.lt("VERIFYTIME", endTime);

        Page<ProEconInspectOrder> page = new Page(pageNum, pageSize);

        IPage<ProEconInspectOrder> pageResult = proEconInspectOrderService.page(page, wrapper);


        if (pageResult.getRecords().size() > 0) {
            List<ProEconEarlyReportWt> reportWindturbineById = earlyReportWindturbineService.getReportWindturbineByIds(pageResult.getRecords().stream().map(s -> s.getReportWindturbineId()).collect(Collectors.toList()));
            pageResult.getRecords().forEach(s -> {
                Optional<ProEconEarlyReportWt> first = reportWindturbineById.stream().filter(k -> k.getId().equals(s.getReportWindturbineId())).findFirst();
                if (first.isPresent())
                    s.setProEconEarlyReportWt(first.get());
            });
        }

        return pageResult;
    }

    private List<InspectOrderDto> packInspectOrderInspectOrderDto(List<ProEconInspectOrder> orderList) {
        List<InspectOrderDto> resultList = new ArrayList<>();

        orderList.stream().forEach(s -> {
            InspectOrderDto dto = new InspectOrderDto();
            BeanUtils.copyProperties(s, dto);
            dto.setEarlyReport(false);
            resultList.add(dto);
        });

        return resultList;
    }

    public AjaxResult updateInspectOrder(String user, InspectOrderDto dto) {
        AjaxResult wrapper = null;
        //代表为 报告评审环节，因此需要 向InspectOrder表中新增数据
        if (StringUtils.isBlank(dto.getId())) {
            try {
                ProEconInspectOrder order = new ProEconInspectOrder();
                order.setId(String.valueOf(SnowflakeGenerator.generateId()));
                order.setVerifyTime(new Date());
                order .setVerifyUser(user);
                order .setVerifyView(dto.getVerifyView());
                order .setVerifyResult(dto.isVerifyResult());
                order .setWindturbineId(dto.getWindturbineId());
                order .setReportWindturbineId(dto.getReportWindturbineId());
                //如果不需要巡检则，巡检单直接结束
                if (!dto.isVerifyResult())
                    order.setClosed(true);
                else
                    order.setClosed(false);

                boolean saveInspectOrder = proEconInspectOrderService.save(order);
                if (saveInspectOrder)
                    wrapper = AjaxResult.success("评审成功");
                else
                    wrapper = AjaxResult.error("评审失败");
            } catch (Exception e) {
                wrapper = AjaxResult.error(JSON.toJSONString(e.getStackTrace()));
            } finally {
                return wrapper;
            }
        } else {
            ProEconInspectOrder order = proEconInspectOrderService.getById(dto.getId());

            if (order == null) {
                wrapper = AjaxResult.error("找不到对应的巡检单");
            } else {
                //计划环节
                if (order.getCreatePlanTime() == null && order.getInspectTime() == null) {
                    order.setCreatePlanUser(user);
                    order.setCreatePlanTime(dto.getCreatePlanTime() == null ? new Date() : dto.getCreatePlanTime());
                    order.setPlanStartTime(dto.getPlanStartTime());
                    order.setPlanEndTime(dto.getPlanEndTime());
                }
                //巡检环节
                else if (order.getInspectTime() == null && order.getCreatePlanTime() != null) {
                    order.setInspectUser(user);
                    order.setInspectTime(dto.getInspectTime() == null ? new Date() : dto.getInspectTime());
                    order.setInspectView(dto.getInspectView());
                    order.setAccordReport(dto.isAccordreport());
                    order.setClosed(true);
                } else {
                    return AjaxResult.error("系统异常，请联系管理员");
                }
                boolean b = proEconInspectOrderService.updateById(order);
                if (b)
                    wrapper = AjaxResult.success("更新成功");
                else
                    wrapper = AjaxResult.error("更新失败");

            }
        }
        return wrapper;
    }

    public JSONObject getOrderCountInfo(String stationId) {

        Map<String, Integer> inspectOrderCount = getInspectOrderCount(stationId);
        Map<String, Integer> noVerifyReport = getNoVerifyReport(stationId);


        JSONArray jsonArray = new JSONArray();
        int wshCount = 0;
        for (Map.Entry<String, Integer> entry :
                noVerifyReport.entrySet()) {
            JSONObject reportObject = new JSONObject();
            String partName = null;
            if(CacheContext.alarmTypeMap.containsKey(entry.getKey()))
            {
                ProEconAlarmType alarmType=CacheContext.alarmTypeMap.get(entry.getKey());
                partName=alarmType.getName();
            }

            reportObject.put("code", entry.getKey());
            reportObject.put("name", partName);
            reportObject.put("count", entry.getValue());
            wshCount = wshCount + entry.getValue();

            jsonArray.add(reportObject);
        }

        List<String> collect = noVerifyReport.keySet().stream().collect(Collectors.toList());

        if (collect.size() < 4) {

            if (!collect.contains("CLX")) {
                JSONObject reportObject = new JSONObject();
                reportObject.put("code", "CLX");
                reportObject.put("name", "齿轮箱");
                reportObject.put("count", 0);
                jsonArray.add(reportObject);
            }
            if (!collect.contains("FDJ")) {
                JSONObject reportObject = new JSONObject();
                reportObject.put("code", "FDJ");
                reportObject.put("name", "发电机");
                reportObject.put("count", 0);
                jsonArray.add(reportObject);
            }
            if (!collect.contains("BJXT")) {
                JSONObject reportObject = new JSONObject();
                reportObject.put("code", "BJXT");
                reportObject.put("name", "变桨系统");
                reportObject.put("count", 0);
                jsonArray.add(reportObject);
            }
            if (!collect.contains("CDL")) {
                JSONObject reportObject = new JSONObject();
                reportObject.put("code", "CDL");
                reportObject.put("name", "传动链");
                reportObject.put("count", 0);
                jsonArray.add(reportObject);
            }
        }


        JSONObject orderObject = new JSONObject();
        for (Map.Entry<String, Integer> entry :
                inspectOrderCount.entrySet()) {
            orderObject.put(entry.getKey(), entry.getValue());
        }
        orderObject.put("WSH", wshCount);
        String dicString = "WSH-未审核，YSH-已审核，WJH-未计划，YJH-已计划，DXJ-待巡检，YXJ-已巡检";
        JSONObject resultObject = new JSONObject();
        resultObject.put("report", jsonArray);
        resultObject.put("order", orderObject);
        resultObject.put("dic", dicString);
        return resultObject;
    }

    public Map<String, Integer> getInspectOrderCount(String stationId) {

        List<ProEconInspectOrder> list = new ArrayList<>();
        if (StringUtils.isNotBlank(stationId)) {
            QueryWrapper<ProEconInspectOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("WINDPOWERSTATIONID", stationId);
            list = proEconInspectOrderService.list(wrapper);
        } else {
            list = proEconInspectOrderService.list();
        }

        //已审核
        List<ProEconInspectOrder> ysh_collect = list.stream().filter(s -> s.getVerifyTime() != null && s.getCreatePlanTime() == null && s.getInspectTime() == null).collect(Collectors.toList());

        //待计划
        List<ProEconInspectOrder> wjh_collect = list.stream().filter(s -> s.getVerifyTime() != null && s.getCreatePlanTime() == null && s.getInspectTime() == null && s.getClosed() == false).collect(Collectors.toList());

        //已计划 待巡检
        List<ProEconInspectOrder> yjh_collect = list.stream().filter(s -> s.getVerifyTime() != null && s.getCreatePlanTime() != null && s.getInspectTime() == null).collect(Collectors.toList());

        //已巡检
        List<ProEconInspectOrder> yxj_collect = list.stream().filter(s -> s.getVerifyTime() != null && s.getCreatePlanTime() != null && s.getInspectTime() != null && s.getClosed() == true).collect(Collectors.toList());

        Map<String, Integer> resultMap = new HashMap<>();

        resultMap.put("YSH", ysh_collect.size());
        resultMap.put("WJH", wjh_collect.size());
        resultMap.put("YJH", yjh_collect.size());
        resultMap.put("DXJ", yjh_collect.size());
        resultMap.put("YXJ", yxj_collect.size());

        return resultMap;

    }

    public Map<String, Integer> getNoVerifyReport(String stationId) {

        Map<String, Integer> resultMap = new HashMap<>();

        Map<String, List<ProEconEarlyReportWt>> map = new HashMap<>();
        List<ProEconEarlyReportWt> noVerifiedPort = getNoVerifiedPort(stationId, "");
        for (ProEconEarlyReportWt windturbine :
                noVerifiedPort) {
            String relatedParts = windturbine.getEarlyReport().getRelatedParts();
            if (!map.containsKey(relatedParts)) {
                map.put(relatedParts, new ArrayList<>());
            }
            List<ProEconEarlyReportWt> earlyReportWindturbines = map.get(relatedParts);
            earlyReportWindturbines.add(windturbine);
        }

        for (Map.Entry<String, List<ProEconEarlyReportWt>> entry :
                map.entrySet()) {
            if (!resultMap.containsKey(entry.getKey())) {
                resultMap.put(entry.getKey(), entry.getValue().size());
            }
        }

        return resultMap;
    }

    public List<InspectOrderDto> getOrderDtoList(Date startTime, Date endTime) {

        QueryWrapper<ProEconInspectOrder> wrapper = new QueryWrapper<>();
        if (startTime != null)
            wrapper.gt("VERIFYTIME", startTime);
        if (endTime != null)
            wrapper.lt("VERIFYTIME", endTime);
        wrapper.eq("VERIFYRESULT", true);

        List<ProEconInspectOrder> list = proEconInspectOrderService.list(wrapper);
        List<InspectOrderDto> orderDtoList = packInspectOrderInspectOrderDto(list);
        if (orderDtoList.size() > 0) {
            List<ProEconEarlyReportWt> reportWindturbineById = earlyReportWindturbineService.getReportWindturbineByIds(list.stream().map(s -> s.getReportWindturbineId()).collect(Collectors.toList()));
            orderDtoList.forEach(s -> {
                Optional<ProEconEarlyReportWt> first = reportWindturbineById.stream().filter(k -> k.getId().equals(s.getReportWindturbineId())).findFirst();
                if (first.isPresent())
                    s.setEarlyReportWindturbine(first.get());
            });
        }
        return orderDtoList;
    }

}
