package com.njcn.device.pq.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.common.service.GeneralDeviceService;
import com.njcn.device.common.service.TerminalBaseService;
import com.njcn.device.device.mapper.DeviceMapper;
import com.njcn.device.line.mapper.LineDetailMapper;
import com.njcn.device.line.service.LineService;
import com.njcn.device.pq.enums.LineBaseEnum;
import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.param.DeviceInfoParam;
import com.njcn.device.pq.pojo.param.RunManageParam;
import com.njcn.device.pq.pojo.po.Line;
import com.njcn.device.pq.pojo.po.LineDetail;
import com.njcn.device.pq.pojo.vo.*;
import com.njcn.device.pq.service.RunManageService;
import com.njcn.device.userledger.service.UserLedgerService;
import com.njcn.supervision.pojo.vo.user.NewUserReportVO;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.enums.StatisticsEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * @author denghuajun
 * @version 1.0.0
 * @date 2022/3/30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RunManageServiceImpl implements RunManageService {

    private final LineService lineService;

    private final GeneralDeviceService generalDeviceService;

    private final DeviceMapper deviceMapper;

    private final DicDataFeignClient dicDataFeignClient;

    private final TerminalBaseService terminalBaseService;

    private final LineDetailMapper lineDetailMapper;

    private final UserLedgerService userLedgerService;


    /**
     * 通用监测点台账，区别冀北版本的
     * @author cdf
     * @date 2026/3/22
     */
    @Override
    public Page<RunManageVO> getLineLedgerComm(RunManageParam runManageParam) {
        Page<RunManageVO> pageResult = new Page<>(PageFactory.getPageNum(runManageParam),PageFactory.getPageSize(runManageParam));
        List<String> lineIndexes ;
        if(CollUtil.isNotEmpty(runManageParam.getIds())){
            lineIndexes =runManageParam.getIds();
        }else{
            DeviceInfoParam deviceInfoParam = new DeviceInfoParam();
            BeanUtil.copyProperties(runManageParam, deviceInfoParam);
            deviceInfoParam.setServerName("pqs-common");
            List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, null, Stream.of(1).collect(Collectors.toList()));
            lineIndexes = generalDeviceDTOList.stream().flatMap(list -> list.getLineIndexes().stream()).collect(Collectors.toList());
        }
        if(CollectionUtil.isEmpty(lineIndexes)){
            return pageResult;
        }
        pageResult =  deviceMapper.getRunManageCommList(new Page<>(PageFactory.getPageNum(runManageParam),PageFactory.getPageSize(runManageParam)),lineIndexes, runManageParam.getComFlag(),Objects.isNull(runManageParam.getRunFlag())?new ArrayList<>():runManageParam.getRunFlag(), Objects.isNull(runManageParam.getSearchValue())?null:runManageParam.getSearchValue());
        return pageResult;
    }


    @Override
    public List<RunManageVO> getLineLedger(RunManageParam runManageParam) {
        List<RunManageVO> resultList = new ArrayList<>();
        List<String> lineIndexes ;
        if(CollUtil.isNotEmpty(runManageParam.getIds())){
            lineIndexes =runManageParam.getIds();
        }else{
            DeviceInfoParam deviceInfoParam = new DeviceInfoParam();
            BeanUtil.copyProperties(runManageParam, deviceInfoParam);
            deviceInfoParam.setServerName("pqs-common");
            List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, null, Stream.of(1).collect(Collectors.toList()));
            lineIndexes = generalDeviceDTOList.stream().flatMap(list -> list.getLineIndexes().stream()).collect(Collectors.toList());
        }
        if (!CollectionUtils.isEmpty(lineIndexes)) {
            resultList = deviceMapper.getRunManageList(lineIndexes, runManageParam.getComFlag(),Objects.isNull(runManageParam.getRunFlag())?new ArrayList<>():runManageParam.getRunFlag(), Objects.isNull(runManageParam.getSearchValue())?null:runManageParam.getSearchValue());
            if(CollUtil.isNotEmpty(resultList)){
                List<String> objIds = resultList.stream().map(RunManageVO::getObjId).collect(Collectors.toList());
                Map<String,NewUserReportVO> runManageVOMap = userLedgerService.getUserReportByIds(objIds).stream().collect(Collectors.toMap(NewUserReportVO::getId,Function.identity()));
                resultList.forEach(it->{
                    if(StrUtil.isNotBlank(it.getObjId())){
                        if(runManageVOMap.containsKey(it.getObjId())){
                            it.setObjName(runManageVOMap.get(it.getObjId()).getProjectName());
                        }
                    }
                });
            }
        }
        return resultList;
    }

    @Override
    public Page<RunTimeVO> getRuntimeDetail(RunManageParam runManageParam) {
        DeviceInfoParam deviceInfoParam = new DeviceInfoParam();
        BeanUtil.copyProperties(runManageParam, deviceInfoParam);
        deviceInfoParam.setServerName("pqs-common");
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, runManageParam.getRunFlag(), Stream.of(1).collect(Collectors.toList()));

            List<String> devIndexes = generalDeviceDTOList.stream().flatMap(list -> list.getDeviceIndexes().stream()).collect(Collectors.toList());
            List<String> manuList = runManageParam.getManufacturer().stream().map(SimpleDTO::getId).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(devIndexes)) {
                return  new Page<>(PageFactory.getPageNum(runManageParam), PageFactory.getPageSize(runManageParam));
            }
            return deviceMapper.getRunManageDevList(new Page<>(PageFactory.getPageNum(runManageParam), PageFactory.getPageSize(runManageParam)),devIndexes, runManageParam.getComFlag(), runManageParam.getRunFlag(), manuList, runManageParam.getSearchValue());
    }

    @Override
    public Page<RunTimeVO> getDeviceLedger(RunManageParam runManageParam) {
        DeviceInfoParam deviceInfoParam = new DeviceInfoParam();
        BeanUtil.copyProperties(runManageParam, deviceInfoParam);
        deviceInfoParam.setServerName("pqs-common");
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, runManageParam.getRunFlag(), Stream.of(1).collect(Collectors.toList()));
        if (CollectionUtils.isEmpty(generalDeviceDTOList)) {
            throw new BusinessException("当前部门没有装置台账");
        }
        List<String> devIndexes = generalDeviceDTOList.stream().flatMap(list -> list.getDeviceIndexes().stream()).collect(Collectors.toList());
        if(CollUtil.isEmpty(devIndexes)){
            return new Page<>();
        }
        Page<RunTimeVO> deviceLedger = deviceMapper.getDeviceLedger(new Page<>(PageFactory.getPageNum(runManageParam), PageFactory.getPageSize(runManageParam)), devIndexes, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), runManageParam.getSearchValue());
        List<String> devID = deviceLedger.getRecords().stream().map(RunTimeVO::getId).collect(Collectors.toList());
        if(CollUtil.isNotEmpty(devID)){
            //添加装置用户性质
            List<DevDetail.DevPowerFlag> devPowerFlags = deviceMapper.selectDevPowerFlagByIds(devID);
            Map<String, List<DevDetail.DevPowerFlag>> devPowerFlag =
                    devPowerFlags.stream().collect(Collectors.groupingBy(DevDetail.DevPowerFlag::getDevIndex));
            deviceLedger.getRecords().stream().forEach(
                    vo -> {
                        if (devPowerFlag.containsKey(vo.getId())) {
                            String powerFlagStr = Optional.ofNullable(devPowerFlag.get(vo.getId()))
                                    .orElse(Collections.emptyList())
                                    .stream()
                                    .map(DevDetail.DevPowerFlag::getPowerFlag)
                                    .distinct()
                                    .collect(Collectors.joining("/"));
                            vo.setPowerFlag(powerFlagStr);
                        }
                    }
            );
        }
        return deviceLedger;
    }

    /**
     * 评价筛选
     *
     * @param evaluate
     * @param onlineEvaluate
     * @return
     */
    private boolean filterOnlineEvaluate(String evaluate, Double onlineEvaluate) {
        if (onlineEvaluate != null) {
            onlineEvaluate = onlineEvaluate * 100;
            switch (evaluate) {
                case "优":
                    if (onlineEvaluate > 90) {
                        return true;
                    }
                    return false;
                case "良":
                    if (60 < onlineEvaluate && onlineEvaluate <= 90) {
                        return true;
                    }
                    return false;
                case "差":
                    if (onlineEvaluate <= 60) {
                        return true;
                    }
                    return false;
            }
        }
        return false;
    }

    @Override
    public List<TerminalLedgerVO> getTerminalLedger(DeviceInfoParam deviceInfoParam) {
        //定义待返回终端信息
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceService.getDeviceInfo(deviceInfoParam, Stream.of(0).collect(Collectors.toList()), Stream.of(1).collect(Collectors.toList()));
        List<TerminalLedgerVO> terminalLedgerVOList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(generalDeviceDTOList)) {

            for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
                if (CollectionUtil.isNotEmpty(generalDeviceDTO.getLineIndexes())) {
                    TerminalLedgerVO terminalLedgerVO = new TerminalLedgerVO();
                    terminalLedgerVO.setAreaIndex(generalDeviceDTO.getIndex());
                    terminalLedgerVO.setAreaName(generalDeviceDTO.getName());

                    List<TerminalLedgerVO.TemData> itemDataList = new ArrayList<>();
                    itemDataList.add(filterScale(generalDeviceDTO, deviceInfoParam.getScale()));
                    itemDataList.add(filterLoadType(generalDeviceDTO, deviceInfoParam.getLoadType()));
                    itemDataList.add(filterManufacturer(generalDeviceDTO, deviceInfoParam.getManufacturer()));
                    itemDataList.add(filterMonitor(generalDeviceDTO, deviceInfoParam.getMonitorFlag()));

                    terminalLedgerVO.setList(itemDataList);
                    terminalLedgerVOList.add(terminalLedgerVO);
                }
            }
        } else {

        }
        return terminalLedgerVOList;
    }

    /**
     * 过滤电压等级
     */
    private TerminalLedgerVO.TemData filterScale(GeneralDeviceDTO generalDeviceDTO, List<SimpleDTO> scales) {
        TerminalLedgerVO.TemData temData = new TerminalLedgerVO.TemData();
        temData.setName(DicDataTypeEnum.DEV_VOLTAGE_STAND.getName());
        //如果电压等级集合为空，则查询所有的电压等级
        if (CollectionUtil.isEmpty(scales)) {
            List<DictData> scaleDictData = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_VOLTAGE.getName()).getData();
            scales = scaleDictData.stream().map(dictData -> {
                SimpleDTO simpleDTO = new SimpleDTO();
                BeanUtil.copyProperties(dictData, simpleDTO);
                return simpleDTO;
            }).collect(Collectors.toList());
        }
        //监测点为空，则返回空的分类数据
        if (CollectionUtil.isEmpty(generalDeviceDTO.getLineIndexes())) {
            return null;
        }
        List<Line> lines = terminalBaseService.getLineById(generalDeviceDTO.getLineIndexes());
        List<TerminalLedgerVO.ItemData> itemDataList = new ArrayList<>();
        for (SimpleDTO simpleDTO : scales) {
            List<String> voltageScaleIds = terminalBaseService.getVoltageIdByScale(generalDeviceDTO.getVoltageIndexes(), simpleDTO.getId());
            GeneralDeviceDTO general = assembleDataByLine(simpleDTO, lines, voltageScaleIds, LineBaseEnum.SUB_V_LEVEL.getCode());
            toCountMod(itemDataList, general, 1);
        }
        temData.setList(itemDataList);
        return temData;
    }

    /**
     * 过滤干扰源类型
     */
    private TerminalLedgerVO.TemData filterLoadType(GeneralDeviceDTO generalDeviceDTO, List<SimpleDTO> loadType) {
        TerminalLedgerVO.TemData temData = new TerminalLedgerVO.TemData();
        temData.setName(DicDataTypeEnum.INTERFERENCE_SOURCE_TYPE.getName());
        if (CollectionUtil.isEmpty(loadType)) {
            //如果为空则加载所有干扰源类型
            List<DictData> loadTypeDictData = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.INTERFERENCE_SOURCE_TYPE.getName()).getData();
            loadType = loadTypeDictData.stream().map(dictData -> {
                SimpleDTO simpleDTO = new SimpleDTO();
                BeanUtil.copyProperties(dictData, simpleDTO);
                return simpleDTO;
            }).collect(Collectors.toList());
        }
        //监测点为空，则返回空的分类数据
        if (CollectionUtil.isEmpty(generalDeviceDTO.getLineIndexes())) {
            return null;
        }
        List<Line> lines = terminalBaseService.getLineById(generalDeviceDTO.getLineIndexes());
        List<TerminalLedgerVO.ItemData> itemDataList = new ArrayList<>();
        for (SimpleDTO simpleDTO : loadType) {
            List<String> lineLoadTypeIds = terminalBaseService.getLineIdByLoadType(generalDeviceDTO.getLineIndexes(), simpleDTO.getId());
            GeneralDeviceDTO general = assembleDataByLine(simpleDTO, lines, lineLoadTypeIds, LineBaseEnum.LINE_LEVEL.getCode());
            toCountMod(itemDataList, general, 2);

        }
        temData.setList(itemDataList);
        return temData;
    }

    /**
     * 过滤厂家
     */
    private TerminalLedgerVO.TemData filterManufacturer(GeneralDeviceDTO generalDeviceDTO, List<SimpleDTO> manufacturer) {
        TerminalLedgerVO.TemData temData = new TerminalLedgerVO.TemData();
        temData.setName(DicDataTypeEnum.DEV_MANUFACTURER.getName());
        if (CollectionUtil.isEmpty(manufacturer)) {
            //如果为空则加载所有干扰源类型
            List<DictData> manufacturerDictData = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_MANUFACTURER.getName()).getData();
            manufacturer = manufacturerDictData.stream().map(dictData -> {
                SimpleDTO simpleDTO = new SimpleDTO();
                BeanUtil.copyProperties(dictData, simpleDTO);
                return simpleDTO;
            }).collect(Collectors.toList());
        }
        //监测点为空，则返回空的分类数据
        if (CollectionUtil.isEmpty(generalDeviceDTO.getLineIndexes())) {
            return null;
        }
        List<Line> lines = terminalBaseService.getLineById(generalDeviceDTO.getLineIndexes());
        List<TerminalLedgerVO.ItemData> itemDataList = new ArrayList<>();
        for (SimpleDTO simpleDTO : manufacturer) {
            List<String> devIds = terminalBaseService.getDeviceIdByManufacturer(generalDeviceDTO.getDeviceIndexes(), simpleDTO.getId());
            GeneralDeviceDTO general = assembleDataByLine(simpleDTO, lines, devIds, LineBaseEnum.DEVICE_LEVEL.getCode());
            toCountMod(itemDataList, general, 2);
        }
        temData.setList(itemDataList);
        return temData;
    }

    /**
     * 上报类型
     */
    private TerminalLedgerVO.TemData filterMonitor(GeneralDeviceDTO generalDeviceDTO, Integer monitorFlag) {
        TerminalLedgerVO.TemData temData = new TerminalLedgerVO.TemData();
        temData.setName(StatisticsEnum.REPORT_TYPE.getName());
        List<Line> lines = terminalBaseService.getLineById(generalDeviceDTO.getLineIndexes());
        List<String> lineIds = lines.stream().map(Line::getId).collect(Collectors.toList());
        List<LineDetail> lineDetailList = lineDetailMapper.selectBatchIds(lineIds);
        List<TerminalLedgerVO.ItemData> itemDataList = new ArrayList<>();
        if (monitorFlag == 2) {
            List<String> line1 = lineDetailList.stream().filter((item) -> item.getMonitorFlag() == 1).map(LineDetail::getId).collect(Collectors.toList());
            SimpleDTO simpleDTO = new SimpleDTO();
            simpleDTO.setName("灿能上报");
            GeneralDeviceDTO general = assembleDataByLine(simpleDTO, lines, line1, LineBaseEnum.LINE_LEVEL.getCode());
            toCountMod(itemDataList, general, 2);

            List<String> line2 = lineDetailList.stream().filter((item) -> item.getMonitorFlag() == 0).map(LineDetail::getId).collect(Collectors.toList());
            SimpleDTO simpleDTO2 = new SimpleDTO();
            simpleDTO2.setName("非灿能上报");
            GeneralDeviceDTO general2 = assembleDataByLine(simpleDTO2, lines, line2, LineBaseEnum.LINE_LEVEL.getCode());
            toCountMod(itemDataList, general2, 2);


        } else if (monitorFlag == 1) {
            SimpleDTO simpleDTO = new SimpleDTO();
            simpleDTO.setName("灿能上报");
            GeneralDeviceDTO general = assembleDataByLine(simpleDTO, lines, generalDeviceDTO.getLineIndexes(), LineBaseEnum.LINE_LEVEL.getCode());
            toCountMod(itemDataList, general, 2);

        } else if (monitorFlag == 0) {
            SimpleDTO simpleDTO = new SimpleDTO();
            simpleDTO.setName("非灿能上报");
            GeneralDeviceDTO general = assembleDataByLine(simpleDTO, lines, generalDeviceDTO.getLineIndexes(), LineBaseEnum.LINE_LEVEL.getCode());
            toCountMod(itemDataList, general, 2);
        }
        temData.setList(itemDataList);
        return temData;
    }

    private GeneralDeviceDTO assembleDataByLine(SimpleDTO simpleDTO, List<Line> lines, List<String> keyIds, Integer level) {
        GeneralDeviceDTO generalDeviceDTO = new GeneralDeviceDTO();
        if (LineBaseEnum.SUB_V_LEVEL.getCode().equals(level)) {
            generalDeviceDTO.setName(simpleDTO.getValue());
        } else {
            generalDeviceDTO.setName(simpleDTO.getName());
        }
        generalDeviceDTO.setIndex(simpleDTO.getId());
        if (CollectionUtil.isNotEmpty(keyIds)) {
            List<Line> tempLines = lines.stream().filter(line -> {
                String[] idsArray = line.getPids().split(",");
                if (level.equals(LineBaseEnum.LINE_LEVEL.getCode())) {
                    return keyIds.contains(line.getId());
                } else {
                    return keyIds.contains(idsArray[level]);
                }
            }).collect(Collectors.toList());
            List<String> subIndexes = new ArrayList<>(), deviceIndexes = new ArrayList<>(), lineIndexes = new ArrayList<>();
            for (Line line : tempLines) {
                String[] idsArray = line.getPids().split(",");
                subIndexes.add(idsArray[LineBaseEnum.SUB_LEVEL.getCode()]);
                deviceIndexes.add(idsArray[LineBaseEnum.DEVICE_LEVEL.getCode()]);
                lineIndexes.add(line.getId());
            }
            //排重，入参到终端综合体
            generalDeviceDTO.setSubIndexes(subIndexes.stream().distinct().collect(Collectors.toList()));
            generalDeviceDTO.setDeviceIndexes(deviceIndexes.stream().distinct().collect(Collectors.toList()));
            generalDeviceDTO.setLineIndexes(lineIndexes.stream().distinct().collect(Collectors.toList()));
        }
        return generalDeviceDTO;
    }

    /**
     * 数据组装
     */
    private void toCountMod(List<TerminalLedgerVO.ItemData> itemDataList, GeneralDeviceDTO general, int type) {
        if (general.getLineIndexes().size() != 0 || general.getDeviceIndexes().size() != 0 || general.getSubIndexes().size() != 0) {
            TerminalLedgerVO.ItemData itemData = new TerminalLedgerVO.ItemData();
            if (type == 1) {
                //电压时候进行排序处理
                itemData.setVoltage(Float.parseFloat(general.getName()));
            }
            itemData.setLineCount(general.getLineIndexes().size());
            itemData.setDevCount(general.getDeviceIndexes().size());
            itemData.setSubCount(general.getSubIndexes().size());
            itemData.setDicIndex(general.getIndex());
            itemData.setDicName(general.getName());
            itemDataList.add(itemData);
        }
    }


}
