package com.pqs9900.serviceImpl.linedata;

import cn.hutool.core.collection.CollectionUtil;
import com.njcn.mapper.configuration.DeviceMapper;
import com.njcn.mapper.configuration.LineMapper;
import com.njcn.mapper.data.OnlineRateMapper;
import com.njcn.pojo.commons.*;
import com.njcn.pojo.commons.device.DeviceGeneral;
import com.njcn.pojo.commons.device.DeviceValue;
import com.njcn.pojo.commons.device.Status;
import com.njcn.pojo.configuration.Device;
import com.njcn.serviceimpl.configuration.DeviceServiceImpl;
import com.njcn.utils.UserUtil;
import com.pqs9900.mapper.linedata.AreaIntegralityMapper;
import com.pqs9900.pojo.linedata.HalfReportRVO;
import com.pqs9900.service.linedata.AreaIntegralityService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * system
 *
 * @author cdf
 * @date 2021/12/6
 */
@Service
public class AreaIntegralityServiceImpl implements AreaIntegralityService {
    private final static Logger logger = LoggerFactory.getLogger(AreaIntegralityServiceImpl.class);


    @Resource
    private UserUtil userUtil;

    @Resource
    private LineMapper lineMapper;

    @Resource
    private DeviceMapper deviceMapper;

    @Autowired
    private OnlineRateMapper onlineRateMapper;
    @Resource
    private AreaIntegralityMapper areaIntegralityMapper;

    /**
     * 区域统计--》数据完整性
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     * @param area      区域
     */
    @Override
    public DeviceGeneral getDataIntegrality(Date startTime, Date endTime, Integer overview, String area,
                                            String scale, String manc, String loadtype, Integer lineGrade) {
        DeviceGeneral deviceGeneral;
        List<AreaGeneralData> areaGeneralDatasTemp = userUtil.getAreaDataByInfoRun(area);
        if (CollectionUtils.isEmpty(areaGeneralDatasTemp)) {
            return null;
        }
        deviceGeneral = getDataIntegrality(startTime, endTime, overview, areaGeneralDatasTemp, scale, manc, loadtype, lineGrade);

        return deviceGeneral;
    }

    private DeviceGeneral getDataIntegrality(Date startTime, Date endTime, Integer overview, List<AreaGeneralData> areaGeneralDatas,
                                             String scale, String manc, String loadtype, Integer lineGrade) {
        DeviceGeneral deviceGeneral = new DeviceGeneral();
        List<DeviceValue> area = new ArrayList<>();
        List<Integer> deviceLindexs = new ArrayList<>();
        if (CollectionUtils.isEmpty(areaGeneralDatas)) {
            return null;
        }
        for (AreaGeneralData areaGeneralData : areaGeneralDatas) {
            if (CollectionUtils.isEmpty(areaGeneralData.getLineIndexs())) {
                continue;
            }
            deviceLindexs.addAll(areaGeneralData.getDeviceIndexs());
        }
        if (overview == 0) {
            //区域
            for (AreaGeneralData areaGeneralData : areaGeneralDatas) {
                if (CollectionUtils.isEmpty(areaGeneralData.getLineIndexs())) {
                    continue;
                }
                area.add(getDataIntegralityArea(areaGeneralData, startTime, endTime, scale, manc, loadtype, lineGrade));
            }
            deviceGeneral.setArea(area);
        } else if (overview == 1) {
            //电压等级
            deviceGeneral.setVol(getDataIntegralityVol(deviceLindexs, startTime, endTime, scale, manc, loadtype, lineGrade));
        } else if (overview == 2) {
            //终端厂家
            deviceGeneral.setInterval(getDataIntegralityCompany(deviceLindexs, startTime, endTime, scale, manc, loadtype, lineGrade));
        } else if (overview == 3) {
            //干扰源类型终
            deviceGeneral.setLoadtype(getDataIntegralityLoadType(deviceLindexs, startTime, endTime, scale, manc, loadtype, lineGrade));
        }
        return deviceGeneral;
    }


    private List<DeviceValue> getDataIntegralityVol(List<Integer> deviceLindexs, Date startTime, Date endTime,
                                                    String scale, String manc, String loadtype, Integer lineGrade) {
        List<DeviceValue> deviceValues = new ArrayList<>();
        List<VoltageData> voltageDatas = userUtil.getVoltageData(deviceLindexs);
        if (CollectionUtils.isEmpty(voltageDatas)) {
            return null;
        }
        for (VoltageData voltageData : voltageDatas) {
            List<Integer> lines = voltageData.getLineIndexs();
            if (!CollectionUtils.isEmpty(lines)) {
                lines = lineMapper.siftLineIndexsByLineGrade(lines, scale, manc, loadtype, lineGrade);
                DeviceValue deviceValue = new DeviceValue();
                deviceValue.setName(voltageData.getVol());
                deviceValue.setAmounts(String.valueOf(lines.size()));
                //获取数据完整性
                deviceValue.setDataIntegrity(getIntegrality(lines, startTime, endTime));
                deviceValues.add(deviceValue);
            } else {
                DeviceValue deviceValue = new DeviceValue();
                deviceValue.setName(voltageData.getVol());
                deviceValue.setGwamounts("0");
                deviceValue.setAmounts("0");
                deviceValue.setDataIntegrity("3.1415");
                deviceValue.setGwdataIntegrity("3.1415");
            }
        }
        return deviceValues;
    }

    private List<DeviceValue> getDataIntegralityCompany(List<Integer> deviceLindexs, Date startTime, Date endTime,
                                                        String scale, String manc, String loadtype, Integer lineGrade) {
        List<DeviceValue> deviceValues = new ArrayList<>();
        List<CompanyValue> companyValues = userUtil.getCompanyData(deviceLindexs);
        if (CollectionUtils.isEmpty(companyValues)) {
            return null;
        }
        for (CompanyValue companyValue : companyValues) {
            DeviceValue deviceValue = new DeviceValue();
            deviceValue.setName(companyValue.getCompanyName());
            List<Integer> lineIndexs = companyValue.getLineIndexs();
            if (CollectionUtils.isEmpty(lineIndexs)) {
                continue;
            }
            lineIndexs = lineMapper.siftLineIndexsByLineGrade(lineIndexs, scale, manc, loadtype, lineGrade);
            if (CollectionUtils.isEmpty(lineIndexs)) {
                deviceValue.setAmounts("0");
                deviceValue.setDataIntegrity("3.1415");
                deviceValue.setGwamounts("0");
                deviceValue.setGwdataIntegrity("3.1415");
            } else {
                deviceValue.setAmounts(String.valueOf(lineIndexs.size()));
                //获取数据完整性
                deviceValue.setDataIntegrity(getIntegrality(lineIndexs, startTime, endTime));

            }
            deviceValues.add(deviceValue);
        }
        return deviceValues;
    }

    /**
     * 根据用户当前的身份，获取按电压等级的数据完整性
     */
    private List<DeviceValue> getDataIntegralityLoadType(List<Integer> deviceLindexs, Date startTime, Date endTime,
                                                         String scale, String manc, String loadtype, Integer lineGrade) {
        List<DeviceValue> deviceValues = new ArrayList<>();
        List<LoadTypeValue> loadtypes = userUtil.getLoadTypeValue(deviceLindexs);
        if (CollectionUtils.isEmpty(loadtypes)) {
            return null;
        }
        for (LoadTypeValue type : loadtypes) {
            List<Integer> lines = type.getLineIndexs();
            if (!CollectionUtils.isEmpty(lines)) {
                lines = lineMapper.siftLineIndexsByLineGrade(lines, scale, manc, loadtype, lineGrade);
                DeviceValue deviceValue = new DeviceValue();
                deviceValue.setName(type.getType());
                deviceValue.setAmounts(String.valueOf(lines.size()));
                //获取数据完整性
                deviceValue.setDataIntegrity(getIntegrality(lines, startTime, endTime));

                deviceValues.add(deviceValue);
            } else {
                DeviceValue deviceValue = new DeviceValue();
                deviceValue.setName(type.getType());
                deviceValue.setGwamounts("0");
                deviceValue.setAmounts("0");
                deviceValue.setDataIntegrity("3.1415");
                deviceValue.setGwdataIntegrity("3.1415");
            }
        }
        return deviceValues;
    }


    private DeviceValue getDataIntegralityArea(AreaGeneralData areaGeneralData, Date startTime, Date endTime,
                                               String scale, String manc, String loadtype, Integer lineGrade) {
        DeviceValue deviceValue = new DeviceValue();
        List<Integer> lines = areaGeneralData.getLineIndexs();
        lines = lineMapper.siftLineIndexsByLineGrade(lines, scale, manc, loadtype, lineGrade);
        String name = areaGeneralData.getName();
        deviceValue.setName(name);
        deviceValue.setAmounts(lines.size() + "");
        //根据监测点索引计算数据完整性
        deviceValue.setDataIntegrity(getIntegrality(lines, startTime, endTime));


        deviceValue.setDeptsIndex(areaGeneralData.getDeptIndex());
        return deviceValue;
    }


    /**
     * 根据监测点索引获取当前的数据完整性
     *
     * @param lineIndexs 监测点索引
     * @param startTime  起始时间
     * @param endTime    截止时间
     */
    private String getIntegrality(List<Integer> lineIndexs, Date startTime, Date endTime) {
        SimpleValue sim;
        if (CollectionUtils.isEmpty(lineIndexs)) {
            return "3.1415";
        } else {
            sim = userUtil.selectIntegralityByLineIndexAndTime(lineIndexs, startTime, endTime);
        }
        if (null == sim || sim.getCountAll() == null || sim.getCountAll() == 0) {
            return "3.14159";
        }
        float num = Float.valueOf(sim.getCountOnline()) / Float.valueOf(sim.getCountAll()) * 100;
        //限制不超过100%
        if (num > 100) {
            return "100.0";
        }
        if (num < 0) {
            return "0.0";
        }
        DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
        return df.format(num);
    }


    /**
     * 区域统计--》终端运行状态(筛)
     *
     * @param overview 概览标识
     * @param area     区域
     */
    @Override
    public DeviceGeneral getDeviceSiftData(Integer overview, String area, String scale, String manc, String loadtype,
                                           Date startTime, Date endTime, Integer lineGrade) {
        DeviceGeneral deviceGeneral;
        List<AreaGeneralData> areaGeneralDatasTemp;

        areaGeneralDatasTemp = userUtil.getAreaDataByInfo(area);

        areaGeneralDatasTemp = userUtil.siftAreaGeneralDataByLineGrade(areaGeneralDatasTemp, scale, manc, loadtype,lineGrade);
        if (CollectionUtils.isEmpty(areaGeneralDatasTemp)) {
            return null;
        }
        deviceGeneral = getDeviceData(overview, areaGeneralDatasTemp, startTime, endTime);
        deviceGeneral.setCityName(userUtil.getCurrentDept().getArea());
        return deviceGeneral;
    }

    @Override
    public List<HalfReportRVO> getHalfReportList(Date startTime, Date endTime,String lineGrade,Integer status,Integer devFlag) {
        return areaIntegralityMapper.getLineMoreInfo(startTime,endTime,lineGrade,status,devFlag);
    }

    //抽取概览和区域统计中终端状态的共同代码
    private DeviceGeneral getDeviceData(Integer overview, List<AreaGeneralData> areaGeneralDatas, Date startTime, Date endTime) {
        DeviceGeneral deviceGeneral = new DeviceGeneral();
        List<DeviceValue> area = new ArrayList<>();
        List<Integer> deviceIndexs = new ArrayList<>();

        // 按区域
        for (AreaGeneralData areaData : areaGeneralDatas) {
            deviceIndexs.addAll(areaData.getDeviceIndexs());
        }

        if (overview == 0) {
            for (AreaGeneralData areaData : areaGeneralDatas) {
                DeviceValue de = getDeviceValueArea(areaData, startTime, endTime);
                area.add(de);
            }
            Collections.sort(area);
            deviceGeneral.setArea(area);
        } else if (overview == 1) {
            //按电压等级
            deviceGeneral.setVol(getScaleData(deviceIndexs, startTime, endTime));
        } else if (overview == 2) {
            //按终端厂家
            deviceGeneral.setInterval(getManufacturerData(deviceIndexs, startTime, endTime));
        } else if (overview == 3) {
            //按干扰源类型终
            deviceGeneral.setLoadtype(getLoadTypeData(deviceIndexs, startTime, endTime));
        }

        return deviceGeneral;
    }

    /**
     * 获取指定区域的终端运行状态
     *
     * @param areaGeneralData 部门对应的所有数据
     */
    private DeviceValue getDeviceValueArea(AreaGeneralData areaGeneralData, Date startTime, Date endTime) {
        DeviceValue deviceValue = new DeviceValue();
        // 区域名
        deviceValue.setName(areaGeneralData.getName());
        deviceValue.setDeptsIndex(areaGeneralData.getDeptIndex());
        // 终端数
        deviceValue.setAmounts(String.valueOf(areaGeneralData.getDeviceIndexs().size()));
        List<Device> devices = userUtil.getDevicesByDevIndexs(areaGeneralData.getDeviceIndexs());
        // 运行状态
        Status status = getStatus(devices);
        //获取该区域下的在线率
        if (CollectionUtils.isEmpty(areaGeneralData.getDeviceIndexs())) {
            deviceValue.setGwamounts("0");
            deviceValue.setOnline("3.1415");
            deviceValue.setGwonline("3.1415");
        } else {
            List<Integer> tempDeviceIndex = deviceMapper.getRunDeviceIndex(areaGeneralData.getDeviceIndexs());
            // 在线率
            deviceValue.setOnline(getOnline(tempDeviceIndex, startTime, endTime));
        }
        deviceValue.setStatus(status);
        return deviceValue;
    }

    /**
     * 按终端厂家获取终端运行状态
     */
    private List<DeviceValue> getManufacturerData(List<Integer> deviceIndexs, Date startTime, Date endTime) {
        List<DeviceValue> interval = new ArrayList<>();

        List<CompanyValue> companyValues = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(deviceIndexs)) {

            if (deviceIndexs.size() > 1000) {
                int count = deviceIndexs.size() / 1000 + 1;
                for (int i = 0; i < count; i++) {
                    List<CompanyValue> temRes = null;
                    if (deviceIndexs.size() > 1000) {
                        List<Integer> temList = deviceIndexs.subList(0, 1000);
                        temRes = userUtil.getCompanyData(temList);
                        temList.clear();
                    } else {
                        temRes = userUtil.getCompanyData(deviceIndexs);
                    }
                    if (CollectionUtil.isNotEmpty(temRes)) {
                        companyValues.addAll(temRes);
                    }
                }
            } else {
                companyValues = userUtil.getCompanyData(deviceIndexs);
            }
        }


        if (CollectionUtils.isEmpty(companyValues)) {
            return null;
        }
        for (CompanyValue companyValue : companyValues) {
            DeviceValue deviceValue = new DeviceValue();
            deviceValue.setName(companyValue.getCompanyName());
            List<Integer> devIndexs = companyValue.getDeviceIndexs();
            if (CollectionUtils.isEmpty(devIndexs)) {
                deviceValue.setStatus(new Status());
                deviceValue.setAmounts("0");
                deviceValue.setOnline("3.1415");
                deviceValue.setGwonline("3.1415");
                deviceValue.setGwamounts("0");
            } else {
                deviceValue.setAmounts(String.valueOf(companyValue.getDeviceIndexs().size()));
                List<Device> devices = userUtil.getDevicesByDevIndexs(companyValue.getDeviceIndexs());
                deviceValue.setStatus(getStatus(devices));
                List<Integer> tempDeviceIndex = deviceMapper.getRunDeviceIndex(companyValue.getDeviceIndexs());
                // 在线率
                deviceValue.setOnline(getOnline(tempDeviceIndex, startTime, endTime));
            }
            interval.add(deviceValue);
        }
        Collections.sort(interval);
        return interval;
    }

    /**
     * 按电压等级获取终端运行状态
     */
    private List<DeviceValue> getScaleData(List<Integer> deviceIndexs, Date startTime, Date endTime) {
        List<DeviceValue> interval = new ArrayList<>();
        List<VoltageData> voltageValues = userUtil.getVoltageData(deviceIndexs);
        if (CollectionUtils.isEmpty(voltageValues)) {
            return null;
        }
        for (VoltageData voltageValue : voltageValues) {
            DeviceValue deviceValue = new DeviceValue();
            deviceValue.setName(voltageValue.getVol());
            List<Integer> devIndexs = voltageValue.getDeviceIndexs();
            if (CollectionUtils.isEmpty(devIndexs)) {
                continue;
            } else {
                deviceValue.setAmounts(String.valueOf(voltageValue.getDeviceIndexs().size()));
                List<Device> devices = userUtil.getDevicesByDevIndexs(voltageValue.getDeviceIndexs());
                deviceValue.setStatus(getStatus(devices));
                List<Integer> tempDeviceIndex = deviceMapper.getRunDeviceIndex(voltageValue.getDeviceIndexs());
                // 在线率
                deviceValue.setOnline(getOnline(tempDeviceIndex, startTime, endTime));
            }
            interval.add(deviceValue);
        }
        Collections.sort(interval);
        return interval;
    }

    /**
     * 按干扰源类型终获取终端运行状态
     */
    private List<DeviceValue> getLoadTypeData(List<Integer> deviceIndexs, Date startTime, Date endTime) {
        List<DeviceValue> interval = new ArrayList<>();
        List<LoadTypeValue> loadtypeValues = userUtil.getLoadTypeValue(deviceIndexs);
        if (CollectionUtils.isEmpty(loadtypeValues)) {
            return null;
        }
        for (LoadTypeValue loadtypeValue : loadtypeValues) {
            DeviceValue deviceValue = new DeviceValue();
            deviceValue.setName(loadtypeValue.getType());
            List<Integer> devIndexs = loadtypeValue.getDevIndexs();
            if (CollectionUtils.isEmpty(devIndexs)) {
                continue;
            } else {
                deviceValue.setAmounts(String.valueOf(loadtypeValue.getDevIndexs().size()));
                List<Device> devices = userUtil.getDevicesByDevIndexs(loadtypeValue.getDevIndexs());
                deviceValue.setStatus(getStatus(devices));
                List<Integer> tempDeviceIndex = deviceMapper.getRunDeviceIndex(loadtypeValue.getDevIndexs());
                // 在线率
                deviceValue.setOnline(getOnline(tempDeviceIndex, startTime, endTime));
            }
            interval.add(deviceValue);
        }
        Collections.sort(interval);
        return interval;
    }

    /**
     * 根据传递的终端集合，获取出这些终端的运行状态
     *
     * @param device 终端集合
     */
    private Status getStatus(List<Device> device) {
        Integer normal = 0;
        Integer breaks = 0;
        Integer shutdown = 0;
        if (CollectionUtils.isEmpty(device)) {
            return new Status();
        } else {
            for (Device device2 : device) {
                if (device2.getDevFlag() == 0) {
                    normal = normal + 1;
                } else if (device2.getDevFlag() == 1) {
                    breaks = breaks + 1;
                } else {
                    shutdown = shutdown + 1;
                }
            }
        }
        Status temp = new Status();
        Integer counts;
        counts = normal + breaks + shutdown;
        temp.setBreaksData(breaks);
        temp.setNormalData(normal);
        temp.setShutdownData(shutdown);
        float num = Float.valueOf(normal) / Float.valueOf(counts);
        num = num * 100;
        DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
        temp.setNormal(df.format(num));
        float bre = Float.valueOf(breaks) / Float.valueOf(counts);
        bre = bre * 100;
        temp.setBreaks(df.format(bre));
        float sh = Float.valueOf(shutdown) / Float.valueOf(counts);
        sh = sh * 100;
        temp.setShutdown(df.format(sh));
        return temp;
    }

    /**
     * 根据终端索引获取当前的在线率
     *
     * @param devIndex  终端索引
     * @param startTime 起始时间
     * @param endTime   截止时间
     */
    private String getOnline(List<Integer> devIndex, Date startTime, Date endTime) {
        SimpleValue sim;
        if (CollectionUtils.isEmpty(devIndex)) {
            return "3.1415";
        } else {
            sim = selectOnlineRateByDeviceIndexAndTime(devIndex, startTime, endTime);
        }
        if (null == sim || sim.getCountAll() == null || sim.getCountAll() == 0) {
            return "3.14159";
        }
        float num = Float.valueOf(sim.getCountOnline()) / Float.valueOf(sim.getCountAll()) * 100;
        if (num > 100) {
            return "100.0";
        }
        if (num < 0) {
            return "0.0";
        }
        DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
        return df.format(num);
    }

    /**
     * 根据终端索引获取在线率
     */
    private SimpleValue selectOnlineRateByDeviceIndexAndTime(List<Integer> devIndex, Date startTime, Date endTime) {
        SimpleValue sim = new SimpleValue();
        try {
            //根据终端
            List<Integer> devIndexTemp = new ArrayList<>(devIndex);
            int length = devIndexTemp.size();
            if (length > 1000) {
                //需要循环的次数
                int times = length / 1000 + 1;
                for (int i = 1; i <= times; i++) {
                    if (length > 1000) {
                        List<Integer> temp = devIndexTemp.subList(0, 1000);
                        SimpleValue simTemp = onlineRateMapper.selectOnlineRateByDeviceIndexAndTime(temp, startTime, endTime);
                        if (simTemp != null) {
                            sim = userUtil.mergeSim(sim, simTemp);
                        }
                        temp.clear();
                        length = length - 1000;
                    } else {
                        SimpleValue simTemp = onlineRateMapper.selectOnlineRateByDeviceIndexAndTime(devIndexTemp, startTime, endTime);
                        if (simTemp != null) {
                            sim.setCountOnline(sim.getCountOnline() + simTemp.getCountOnline());
                            sim.setCountAll(sim.getCountAll() + simTemp.getCountAll());
                        }
                    }
                }
            } else {
                sim = onlineRateMapper.selectOnlineRateByDeviceIndexAndTime(devIndex, startTime, endTime);
            }
        } catch (Exception e) {
            logger.error("查询终端在线率发生异常，异常是" + e.getMessage());
        }
        return sim;
    }
}
