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

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.bpm.api.BpmProcessFeignClient;
import com.njcn.bpm.enums.BpmProcessInstanceStatusEnum;
import com.njcn.bpm.enums.BpmTaskStatusEnum;
import com.njcn.bpm.pojo.dto.BpmInstanceInfo;
import com.njcn.bpm.pojo.dto.BpmProcessInstanceCreateReqDTO;
import com.njcn.bpm.pojo.param.instance.BpmProcessInstanceCancelParam;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.SubGetBase;
import com.njcn.device.biz.pojo.param.SubstationParam;
import com.njcn.device.pms.utils.PubUtil;
import com.njcn.device.pq.api.NodeClient;
import com.njcn.device.pq.pojo.po.Node;
import com.njcn.poi.excel.ExcelUtil;
import com.njcn.poi.excel.PullDown;
import com.njcn.poi.util.PoiUtil;
import com.njcn.supervision.enums.FlowStatusEnum;
import com.njcn.supervision.enums.SupervisionKeyEnum;
import com.njcn.supervision.enums.SupervisionResponseEnum;
import com.njcn.supervision.mapper.device.SupervisionDevMainReportPOMapper;
import com.njcn.supervision.pojo.dto.SupervisionDevMainReportExcel;
import com.njcn.supervision.pojo.param.device.SupervisionDevMainReportParam;
import com.njcn.supervision.pojo.param.device.SupervisionTempDeviceReportParam;
import com.njcn.supervision.pojo.po.device.SupervisionDevMainReportPO;
import com.njcn.supervision.pojo.po.device.SupervisionTempDeviceReport;
import com.njcn.supervision.pojo.vo.device.SupervisionDevMainReportVO;
import com.njcn.supervision.service.device.SupervisionDevMainReportPOService;
import com.njcn.supervision.service.device.SupervisionTempDeviceReportService;
import com.njcn.supervision.utils.InstanceUtil;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.user.pojo.vo.UserVO;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.utils.RequestUtil;
import com.njcn.web.utils.WebUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Description:
 * Date: 2024/5/10  18:10【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SupervisionDevMainReportPOServiceImpl extends ServiceImpl<SupervisionDevMainReportPOMapper, SupervisionDevMainReportPO> implements SupervisionDevMainReportPOService {


    private final BpmProcessFeignClient bpmProcessFeignClient;
    private final SupervisionTempDeviceReportService supervisionTempDeviceReportService;
    private final DeptFeignClient deptFeignClient;
    private final UserFeignClient userFeignClient;
    private final DicDataFeignClient dicDataFeignClient;
    private final NodeClient nodeClient;
    private final CommTerminalGeneralClient commterminalGeneralClient;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addDevReport(SupervisionDevMainReportParam supervisionDevMainReportParam) {

        SupervisionDevMainReportPO supervisionDevMainReportPO = new SupervisionDevMainReportPO();
        BeanUtils.copyProperties(supervisionDevMainReportParam, supervisionDevMainReportPO);
        if (Objects.equals(supervisionDevMainReportParam.getSaveOrCheckflag(), "2")) {
            checkIp(supervisionDevMainReportParam, !StringUtils.isEmpty(supervisionDevMainReportParam.getId()));
        }

        //设置状态
        if (Objects.equals(supervisionDevMainReportParam.getSaveOrCheckflag(), "1")) {
            supervisionDevMainReportPO.setStatus(BpmTaskStatusEnum.WAIT.getStatus());

        } else {
            supervisionDevMainReportPO.setStatus(BpmTaskStatusEnum.RUNNING.getStatus());

        }
        if (ObjectUtil.isNotNull(supervisionDevMainReportParam.getImportType())) {
            supervisionDevMainReportPO.setImportType(supervisionDevMainReportParam.getImportType());
            if (supervisionDevMainReportParam.getImportType() == 1) {
                supervisionDevMainReportPO.setStatus(FlowStatusEnum.APPROVE.getCode());
            }
        } else {
            supervisionDevMainReportPO.setImportType(0);
        }

        supervisionDevMainReportPO.setState(DataStateEnum.ENABLE.getCode());
        this.saveOrUpdate(supervisionDevMainReportPO);
        String id = supervisionDevMainReportPO.getId();
        supervisionDevMainReportPO = this.baseMapper.selectById(id);

        //存储临时终端信息
        SupervisionTempDeviceReportParam supervisionTempDeviceReportParam = supervisionDevMainReportParam.getSupervisionTempDeviceReportParam();
        SupervisionTempDeviceReport supervisionTempDeviceReportPO = new SupervisionTempDeviceReport();
        BeanUtils.copyProperties(supervisionTempDeviceReportParam, supervisionTempDeviceReportPO);
        supervisionTempDeviceReportPO.setId(id);
        supervisionTempDeviceReportService.saveOrUpdate(supervisionTempDeviceReportPO);

        //存储临时监测点信息
//        SupervisionTempLineReportParam supervisionTempLineReportParam = supervisionDevMainReportParam.getSupervisionTempLineReportParam();
//        SupervisionTempLineReport supervisionTempLineReport = new SupervisionTempLineReport();
//        BeanUtils.copyProperties(supervisionTempLineReportParam, supervisionTempLineReport);
//        supervisionTempDeviceReportPO.setId(id);
//        supervisionTempLineReportService.save(supervisionTempLineReport);
        // 发起 BPM 流程
        // 如何未提交审则不需要发起 BPM 流程
        if (Objects.equals(supervisionDevMainReportParam.getSaveOrCheckflag(), "2")) {
            Map<String, Object> processInstanceVariables = new HashMap<>(16);
            BpmProcessInstanceCreateReqDTO bpmProcessInstanceCreateReqDTO = new BpmProcessInstanceCreateReqDTO();
            bpmProcessInstanceCreateReqDTO.setProcessDefinitionKey(SupervisionKeyEnum.DEVICE_INFO_ADD.getKey());
            bpmProcessInstanceCreateReqDTO.setBusinessKey(id);
            bpmProcessInstanceCreateReqDTO.setStartUserSelectAssignees(supervisionDevMainReportParam.getStartUserSelectAssignees());
            bpmProcessInstanceCreateReqDTO.setVariables(processInstanceVariables);
            String processInstanceId = bpmProcessFeignClient.createProcessInstance(supervisionDevMainReportPO.getCreateBy(), bpmProcessInstanceCreateReqDTO).getData();
            // 将工作流的编号，更新到流程单中
            supervisionDevMainReportPO.setProcessInstanceId(processInstanceId);
            this.baseMapper.updateById(supervisionDevMainReportPO);
        }
        return id;
    }

    @Override
    public String updateDevReport(SupervisionDevMainReportParam.SupervisionDevMainReportParamUpdate supervisionDevMainReportParam) {
        //校验ip
        if (Objects.equals(supervisionDevMainReportParam.getSaveOrCheckflag(), "2")) {
            checkIp(supervisionDevMainReportParam, !StringUtils.isEmpty(supervisionDevMainReportParam.getId()));
        }
        SupervisionDevMainReportPO supervisionDevMainReportPO = this.baseMapper.selectById(supervisionDevMainReportParam.getId());
        //判断是否有权限操作
        InstanceUtil.judgeUserPower(RequestUtil.getUserIndex(), supervisionDevMainReportPO.getCreateBy());
        supervisionDevMainReportParam.setProcessInstanceId(supervisionDevMainReportPO.getProcessInstanceId());
        supervisionDevMainReportParam.setHistoryInstanceId(supervisionDevMainReportPO.getHistoryInstanceId());
        BeanUtils.copyProperties(supervisionDevMainReportParam, supervisionDevMainReportPO);
        supervisionDevMainReportPO.setStatus(BpmTaskStatusEnum.RUNNING.getStatus());
        supervisionDevMainReportPO.setState(DataStateEnum.ENABLE.getCode());
        //处理历史流程id列表
        String historyInstanceIds = InstanceUtil.dealHistoryId(supervisionDevMainReportPO.getProcessInstanceId(), supervisionDevMainReportPO.getHistoryInstanceId());
        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>(16);
        BpmProcessInstanceCreateReqDTO bpmProcessInstanceCreateReqDTO = new BpmProcessInstanceCreateReqDTO();
        bpmProcessInstanceCreateReqDTO.setProcessDefinitionKey(SupervisionKeyEnum.DEVICE_INFO_ADD.getKey());
        bpmProcessInstanceCreateReqDTO.setBusinessKey(supervisionDevMainReportPO.getId());
        bpmProcessInstanceCreateReqDTO.setStartUserSelectAssignees(supervisionDevMainReportParam.getStartUserSelectAssignees());
        bpmProcessInstanceCreateReqDTO.setVariables(processInstanceVariables);
        String processInstanceId = bpmProcessFeignClient.createProcessInstance(supervisionDevMainReportPO.getCreateBy(), bpmProcessInstanceCreateReqDTO).getData();
        // 将工作流的编号，更新到流程单中
        supervisionDevMainReportPO.setProcessInstanceId(processInstanceId);
        //保存历史流程id列表
        supervisionDevMainReportPO.setHistoryInstanceId(historyInstanceIds);
        this.baseMapper.updateById(supervisionDevMainReportPO);
        return supervisionDevMainReportPO.getId();
    }


    @Override
    public boolean auditDevReport(SupervisionDevMainReportParam.SupervisionDevMainReportParamUpdate supervisionDevMainReportParamUpdate) {
        return true;
    }

    @Override
    public Boolean removeDevReport(List<String> ids) {
//        this.lambdaUpdate().set(SupervisionDevMainReportPO::getState,)
        return true;
    }

    @Override
    public Page<SupervisionDevMainReportVO> getDevReport(SupervisionDevMainReportParam.SupervisionDevMainReportQuery supervisionDevMainReportQuery) {
        QueryWrapper<SupervisionDevMainReportVO> queryWrapper = new QueryWrapper<>();
        //获取当前用户部门所有同事的id，查看该部门下所有的数据
        List<String> colleaguesIds = userFeignClient.getColleaguesIdByUserId(RequestUtil.getUserIndex()).getData();
        queryWrapper.in("supervision_dev_main_report.create_by", colleaguesIds)
                .eq("supervision_dev_main_report.state", DataStateEnum.ENABLE.getCode());
        if (StrUtil.isNotBlank(supervisionDevMainReportQuery.getOrgNo())) {
            /*获取直接下属子单位*/
            List<String> data = deptFeignClient.getDepSonIdtByDeptId(supervisionDevMainReportQuery.getOrgNo()).getData();
            queryWrapper.in("supervision_dev_main_report.org_id", data);
        }
        queryWrapper
                .and(CollUtil.isNotEmpty(InstanceUtil.filterTaskStatus()),w -> w.in("supervision_dev_main_report.status", InstanceUtil.filterTaskStatus())
                        .or()
                        .eq("supervision_dev_main_report.create_by", RequestUtil.getUserIndex())
                );

        if (Objects.nonNull(supervisionDevMainReportQuery.getStatus())) {
            queryWrapper.eq("supervision_dev_main_report.status", supervisionDevMainReportQuery.getStatus());
        }
        if (StrUtil.isNotBlank(supervisionDevMainReportQuery.getSearchValue())) {
            queryWrapper.and(x -> x
                    .like("dev.substation_name", supervisionDevMainReportQuery.getSearchValue())
                    .or()
                    .like("dev.monitoring_terminal_code", supervisionDevMainReportQuery.getSearchValue())
                    .or()
                    .like("dev.monitoring_terminal_name", supervisionDevMainReportQuery.getSearchValue())
            );
        }
        //添加上时间范围
        if (Objects.nonNull(supervisionDevMainReportQuery.getSearchBeginTime()) && Objects.nonNull(supervisionDevMainReportQuery.getSearchEndTime())) {
            queryWrapper.between("supervision_dev_main_report.Create_Time",
                    DateUtil.beginOfDay(DateUtil.parse(supervisionDevMainReportQuery.getSearchBeginTime())),
                    DateUtil.endOfDay(DateUtil.parse(supervisionDevMainReportQuery.getSearchEndTime())));
        }
        queryWrapper.orderByDesc("supervision_dev_main_report.Update_Time");
        Page<SupervisionDevMainReportVO> page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(supervisionDevMainReportQuery), PageFactory.getPageSize(supervisionDevMainReportQuery)), queryWrapper);
        page.getRecords().forEach(temp -> {
//            temp.setOrgName((deptFeignClient.getDeptById(temp.getOrgId()).getData().getName()));
            //处理特殊字段，用户名、部门名
            UserVO userVO = userFeignClient.getUserById(temp.getReporter()).getData();
            temp.setReporter(userVO.getName());
            temp.setOrgName(deptFeignClient.getDeptById(temp.getOrgId()).getData().getName());
        });
        return page;
    }

    @Override
    public void updateProcessStatus(String businessKey, Integer status) {
        this.lambdaUpdate().set(SupervisionDevMainReportPO::getStatus, status).eq(SupervisionDevMainReportPO::getId, businessKey).update();
    }

    @Override
    public BpmInstanceInfo getInstanceInfo(String businessId) {
        BpmInstanceInfo bpmInstanceInfo = new BpmInstanceInfo();
        SupervisionDevMainReportVO supervisionDevMainReportVO = this.querySurveyDetail(businessId);
        if(Objects.isNull(supervisionDevMainReportVO)){
            return null;
        }
        bpmInstanceInfo.setHistoryInstanceId(supervisionDevMainReportVO.getHistoryInstanceId());
        String sign = supervisionDevMainReportVO.getOrgName()
                .concat(StrPool.SLASH)
                .concat(supervisionDevMainReportVO.getSupervisionTempDeviceReport().getSubstationName())
                .concat(StrPool.SLASH)
                .concat(supervisionDevMainReportVO.getSupervisionTempDeviceReport().getMonitoringTerminalName());
        bpmInstanceInfo.setInstanceSign(sign);
        return bpmInstanceInfo;
    }

    @Override
    public Set<String> getAllRejectInstanceIds() {
        Set<String> rejectInstanceIds = new HashSet<>();
        //查询当前用户创建的createBy的流程审核不通过的
        LambdaQueryWrapper<SupervisionDevMainReportPO> supervisionDevMainReportPOLambdaQueryWrapper = new LambdaQueryWrapper<>();
        supervisionDevMainReportPOLambdaQueryWrapper.eq(SupervisionDevMainReportPO::getCreateBy, RequestUtil.getUserIndex())
                .eq(SupervisionDevMainReportPO::getStatus, BpmProcessInstanceStatusEnum.REJECT.getStatus())
                .eq(SupervisionDevMainReportPO::getState, DataStateEnum.ENABLE.getCode())
                .select(SupervisionDevMainReportPO::getProcessInstanceId);
        List<SupervisionDevMainReportPO> supervisionDevMainReportPOS = this.baseMapper.selectList(supervisionDevMainReportPOLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(supervisionDevMainReportPOS)) {
            List<String> result = supervisionDevMainReportPOS.stream().map(SupervisionDevMainReportPO::getProcessInstanceId).collect(Collectors.toList());
            rejectInstanceIds.addAll(result);
        }
        return rejectInstanceIds;
    }

    @Override
    public String cancelDevMainReport(BpmProcessInstanceCancelParam cancelReqVO) {
        //准备取消该流程，需要远程调用接口
        SupervisionDevMainReportPO supervisionDevMainReportPO = this.baseMapper.selectById(cancelReqVO.getId());
        //取消流程
        bpmProcessFeignClient.cancelProcessInstanceByStartUser(cancelReqVO);
        //更新状态
        supervisionDevMainReportPO.setStatus(BpmProcessInstanceStatusEnum.CANCEL.getStatus());
        this.updateById(supervisionDevMainReportPO);
        return supervisionDevMainReportPO.getId();
    }

    @Override
    public List<SupervisionTempDeviceReport> getDeviceList() {
        String deptIndex = RequestUtil.getDeptIndex();
        List<String> data = deptFeignClient.getDepSonIdtByDeptId(deptIndex).getData();

        List<SupervisionDevMainReportPO> list = this.lambdaQuery()
                .eq(SupervisionDevMainReportPO::getStatus, 2)
                .in(CollectionUtil.isNotEmpty(data), SupervisionDevMainReportPO::getOrgId, data)
                .list();
        if (CollectionUtil.isNotEmpty(list)) {
            List<String> collect = list.stream().map(SupervisionDevMainReportPO::getId).collect(Collectors.toList());
            return supervisionTempDeviceReportService.lambdaQuery().in(SupervisionTempDeviceReport::getId, collect).list();
        }
        return new ArrayList<>();
    }

    @Override
    public SupervisionDevMainReportVO querySurveyDetail(String id) {
        SupervisionDevMainReportVO supervisionDevMainReportVO = new SupervisionDevMainReportVO();
        SupervisionDevMainReportPO byId = this.getById(id);
        BeanUtils.copyProperties(byId, supervisionDevMainReportVO);
        UserVO userVO = userFeignClient.getUserById(byId.getReporter()).getData();
        supervisionDevMainReportVO.setReporter(userVO.getName());
        supervisionDevMainReportVO.setOrgName(deptFeignClient.getDeptById(byId.getOrgId()).getData().getName());

        SupervisionTempDeviceReport supervisionTempDeviceReport = supervisionTempDeviceReportService.lambdaQuery().eq(SupervisionTempDeviceReport::getId, id).one();
//        supervisionTempDeviceReport.setSubstation(lineFeignClient.getSubstationInfo(supervisionTempDeviceReport.getSubstation()).getData().getName());
        if (StringUtils.isNotEmpty(supervisionTempDeviceReport.getPowerCompany())) {
            supervisionTempDeviceReport.setPowerCompany(deptFeignClient.getDeptById(supervisionTempDeviceReport.getPowerCompany()).getData().getName());
        }
        supervisionDevMainReportVO.setSupervisionTempDeviceReport(supervisionTempDeviceReport);
        return supervisionDevMainReportVO;
    }

    @Override
    public void downloadDevTemplate() {
        ExportParams exportParams = new ExportParams("终端入网检测数据模板（带*字段均是必填,请严格按照模板标准填入数据）", "终端入网检测数据信息");
        //所属地市
        List<DictData> jiBeiArea = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.JIBEI_AREA.getCode()).getData();
        //所属供电公司
        List<DeptDTO> depts = deptFeignClient.getDepSonDetailByDeptId(RequestUtil.getDeptIndex()).getData();
        //终端型号
        List<DictData> devType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_TYPE.getCode()).getData();
        //通讯类型
        List<DictData> frontType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.FRONT_TYPE.getCode()).getData();
        //获取所有前置机
        List<Node> nodes = nodeClient.nodeAllList().getData();

        //接线方式
        List<DictData> devConnect = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_CONNECT.getCode()).getData();
        //厂家
        List<DictData> devManufacturer = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_MANUFACTURER.getCode()).getData();
        //电压互感器类型
        List<DictData> voltageTransformer = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.VOLTAGE_TRANSFORMER.getCode()).getData();
        //中性点接线方式
        List<DictData> neutralPoint = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.Neutral_Point.getCode()).getData();
        SubstationParam substationParam=new SubstationParam();
        substationParam.setOrgIds(depts.stream().map(DeptDTO::getId).distinct().collect(Collectors.toList()));
        List<SubGetBase> data = commterminalGeneralClient.tagOrIdGetSub(substationParam).getData();

        List<PullDown> pullDowns = new ArrayList<>();

        PullDown pullDown;
        pullDown = new PullDown();
        pullDown.setFirstCol(0);
        pullDown.setLastCol(0);
        pullDown.setIsText(true);
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(10);
        pullDown.setLastCol(10);
        pullDown.setIsText(true);
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(11);
        pullDown.setLastCol(11);
        pullDown.setIsText(true);
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(20);
        pullDown.setLastCol(20);
        pullDown.setIsText(true);
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(1);
        pullDown.setLastCol(1);
        pullDown.setStrings(jiBeiArea.stream().map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);

        //缺少变电站名称
        pullDown = new PullDown();
        pullDown.setFirstCol(2);
        pullDown.setLastCol(2);
        pullDown.setStrings(data.stream().map(SubGetBase::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(3);
        pullDown.setLastCol(3);
        pullDown.setStrings(depts.stream().map(DeptDTO::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(4);
        pullDown.setLastCol(4);
        pullDown.setStrings(devType.stream().map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(6);
        pullDown.setLastCol(6);
        pullDown.setStrings(frontType.stream().filter(x -> !"CLD".equals(x.getCode()) && !"61850".equals(x.getCode())).map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(12);
        pullDown.setLastCol(12);
        pullDown.setStrings(nodes.stream().map(Node::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);

        //监测终端安装位置 0：电网侧 1：用户侧
        pullDown = new PullDown();
        pullDown.setFirstCol(13);
        pullDown.setLastCol(13);
        pullDown.setStrings(Stream.of("电网侧", "用户侧").collect(Collectors.toList()));
        pullDowns.add(pullDown);

        //终端模型 0：虚拟终端 1：实际终端 2：离线
        pullDown = new PullDown();
        pullDown.setFirstCol(16);
        pullDown.setLastCol(16);
        pullDown.setStrings(Stream.of("实际终端", "虚拟终端", "离线").collect(Collectors.toList()));
        pullDowns.add(pullDown);

        //数据类型 0：暂态系统 1：稳态系统 2：两个系统
        pullDown = new PullDown();
        pullDown.setFirstCol(17);
        pullDown.setLastCol(17);
        pullDown.setStrings(Stream.of("两个系统", "暂态系统", "稳态系统").collect(Collectors.toList()));
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(18);
        pullDown.setLastCol(18);
        pullDown.setStrings(devConnect.stream().map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(19);
        pullDown.setLastCol(19);
        pullDown.setStrings(devManufacturer.stream().map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(21);
        pullDown.setLastCol(21);
        pullDown.setStrings(voltageTransformer.stream().map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(22);
        pullDown.setLastCol(22);
        pullDown.setStrings(neutralPoint.stream().map(DictData::getName).distinct().collect(Collectors.toList()));
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(25);
        pullDown.setLastCol(25);
        pullDown.setStrings(Stream.of("关闭", "开启").collect(Collectors.toList()));
        pullDowns.add(pullDown);

        pullDown = new PullDown();
        pullDown.setFirstCol(26);
        pullDown.setLastCol(26);
        pullDown.setStrings(Stream.of("关闭", "开启").collect(Collectors.toList()));
        pullDowns.add(pullDown);

        //召唤标志 0：周期触发 1：变位触发
        pullDown = new PullDown();
        pullDown.setFirstCol(27);
        pullDown.setLastCol(27);
        pullDown.setStrings(Stream.of("周期触发", "变位触发").collect(Collectors.toList()));
        pullDowns.add(pullDown);


        pullDown = new PullDown();
        pullDown.setFirstCol(28);
        pullDown.setLastCol(28);
        pullDown.setStrings(Stream.of("否", "是").collect(Collectors.toList()));
        pullDowns.add(pullDown);

        ExcelUtil.exportExcelPullDown(exportParams, "终端入网检测数据模板.xlsx", pullDowns, SupervisionDevMainReportExcel.class, new ArrayList<>());

    }

    @Override
    public void importDevData(MultipartFile file, HttpServletResponse response) {
        log.info("beginImport-------------------"+ LocalDateTime.now());
        ImportParams params = new ImportParams();
        //表头
        params.setHeadRows(1);
        //标题
        params.setTitleRows(1);
        params.setNeedVerify(true);
        params.setStartSheetIndex(0);
        params.setSheetNum(1);
        List<SupervisionDevMainReportExcel> devExcels;
        try {
            List<SupervisionDevMainReportExcel> sensitiveUserExcelExcelImportResult = ExcelImportUtil.importExcel(file.getInputStream(), SupervisionDevMainReportExcel.class, params);
            // 过滤掉空的数据
            devExcels = sensitiveUserExcelExcelImportResult.stream().filter(x -> StringUtils.isNotBlank(x.getCity())).collect(Collectors.toList());
            if(CollectionUtil.isEmpty(devExcels)){
                throw new BusinessException(SupervisionResponseEnum.IMPORT_DEV_DATA_ERROR);
            }
            //如果存在非法数据，将不合格的数据导出
//            if (sensitiveUserExcelExcelImportResult.isVerifyFail()) {
//                PoiUtil.exportFileByWorkbook(sensitiveUserExcelExcelImportResult.getFailWorkbook(), "非法数据.xlsx", response);
//            } else {
//                devExcels = sensitiveUserExcelExcelImportResult.getList();
//            }
        } catch (Exception e) {
            throw new BusinessException(SupervisionResponseEnum.IMPORT_DEV_ERROR);
        }
        List<SupervisionDevMainReportExcel.ExcelMsg> devMsgList =  new ArrayList<>();
        log.info("beginqueryjiBeiArea-------------------"+ LocalDateTime.now());

        //所属地市
        List<DictData> jiBeiArea = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.JIBEI_AREA.getCode()).getData();
        log.info("beginquerydeptS-------------------"+ LocalDateTime.now());

        //所属供电公司
        List<DeptDTO> deptS = deptFeignClient.getDeptDescendantIndexes(RequestUtil.getDeptIndex(), WebUtil.filterDeptType()).getData();
        Map<String, String> deptMap = deptS.stream().collect(Collectors.toMap(DeptDTO::getName, DeptDTO::getId, (k1, k2) -> k1));

        //终端型号
        List<DictData> devType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_TYPE.getCode()).getData();
        //通讯类型
        List<DictData> frontType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.FRONT_TYPE.getCode()).getData();
        //获取所有前置机
        List<Node> nodes = nodeClient.nodeAllList().getData();
        Map<String, String> nodeMap = nodes.stream().collect(Collectors.toMap(Node::getName, Node::getId, (k1, k2) -> k1));
        log.info("beginquerydevConnect-------------------"+ LocalDateTime.now());

        //接线方式
        List<DictData> devConnect = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_CONNECT.getCode()).getData();

        //厂家
        List<DictData> devManufacturer = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_MANUFACTURER.getCode()).getData();
        //电压互感器类型
        List<DictData> voltageTransformer = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.VOLTAGE_TRANSFORMER.getCode()).getData();
        //中性点接线方式
        List<DictData> neutralPoint = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.Neutral_Point.getCode()).getData();
        log.info("beginqueryneutralPoint-------------------"+ LocalDateTime.now());

        SubstationParam substationParam=new SubstationParam();
        substationParam.setOrgIds(deptS.stream().map(DeptDTO::getId).distinct().collect(Collectors.toList()));
        log.info("beginquerySubGetBase-------------------"+ LocalDateTime.now());

        List<SubGetBase> data = commterminalGeneralClient.tagOrIdGetSub(substationParam).getData();
        log.info("endquerySubGetBase-------------------"+ LocalDateTime.now());

        SupervisionDevMainReportPO po;
        if (CollectionUtil.isNotEmpty(devExcels)) {
            for (SupervisionDevMainReportExcel dev : devExcels) {
                //todo 需要根据变电站id进行匹配
                List<SubGetBase> subList = data.stream().filter(x -> x.getName().equals(dev.getSubstation())).collect(Collectors.toList());
                if(CollUtil.isEmpty(subList)){
                    //该用户已经录入
                    SupervisionDevMainReportExcel.ExcelMsg sensitiveUserExcelMsg = new SupervisionDevMainReportExcel.ExcelMsg();
                    BeanUtils.copyProperties(dev, sensitiveUserExcelMsg);
                    sensitiveUserExcelMsg.setMsg(dev.getTerminalIp().concat("变电站不存在,请检查变电站信息是否是下拉框信息!"));
                    devMsgList.add(sensitiveUserExcelMsg);
                    continue;
                }
                LambdaQueryWrapper<SupervisionTempDeviceReport> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper
                        .eq(SupervisionTempDeviceReport::getSubstationName, dev.getSubstation())
                        .eq(SupervisionTempDeviceReport::getTerminalIp, dev.getTerminalIp());
                List<SupervisionTempDeviceReport> list = supervisionTempDeviceReportService.getBaseMapper().selectList(lambdaQueryWrapper);
                if (CollectionUtil.isNotEmpty(list)) {
                    //过滤已取消的申请和删除的
                    List<String> collect = list.stream().map(SupervisionTempDeviceReport::getId).collect(Collectors.toList());
                    List<SupervisionDevMainReportPO> list1 = this.lambdaQuery().in(SupervisionDevMainReportPO::getId, collect).list();
                    list1 = list1.stream()
                            .filter(userReportPO -> !userReportPO.getStatus().equals(FlowStatusEnum.CANCEL.getCode()))
                            .filter(userReportPO -> userReportPO.getState().equals(DataStateEnum.ENABLE.getCode()))
                            .collect(Collectors.toList());
                    //如果还存在，则说明有人申请过了
                    if (CollectionUtil.isNotEmpty(list1)) {
                        //该用户已经录入
                        SupervisionDevMainReportExcel.ExcelMsg sensitiveUserExcelMsg = new SupervisionDevMainReportExcel.ExcelMsg();
                        BeanUtils.copyProperties(dev, sensitiveUserExcelMsg);
                        sensitiveUserExcelMsg.setMsg(dev.getTerminalIp().concat("Ip已占用"));
                        devMsgList.add(sensitiveUserExcelMsg);
                        continue;
                    }
                }
                //基础报告信息
                po = new SupervisionDevMainReportPO();
                po.setReporter(RequestUtil.getUserIndex());
                po.setReportDate(LocalDate.now());
                //解决导入部门问题
                List<String> DeptIds =  deptS.stream().filter(x -> x.getName().equals(dev.getCity())).map(DeptDTO::getId).collect(Collectors.toList());
                po.setOrgId(CollUtil.isNotEmpty(DeptIds)?DeptIds.get(0):RequestUtil.getDeptIndex());

                po.setExpectedProductionDate(DateUtil.parseDate(dev.getExpectedProductionDate()).toLocalDateTime().toLocalDate());
                po.setCity(PubUtil.getDicById(dev.getCity(), jiBeiArea));
                po.setUserStatus("1");
//                po.setAcceptanceInspectionReport();
//                po.setAcceptanceInspectionReportSingle();
//                po.setTypeExperimentReport();
//                po.setFactoryInspectionReport();
//                po.setPerformanceTestReport();
//                po.setInformationSecurityTestReport();
//                po.setOtherAttachments();
                po.setImportType(1);
                po.setStatus(2);
                po.setState(DataStateEnum.ENABLE.getCode());
                //终端基础信息
                StringBuilder msg = new StringBuilder();
                SupervisionTempDeviceReport devDetails = new SupervisionTempDeviceReport();
                if(deptMap.containsKey(dev.getPowerCompany())){
                    devDetails.setPowerCompany(deptMap.get(dev.getPowerCompany()));
                    devDetails.setPowerCompany(deptMap.get(dev.getPowerCompany()));
                }else{
                    msg.append("所属供电公司不存在!");
                }
                //todo 需要根据变电站id进行匹配
                devDetails.setCustomSubstationFlag(0);
                devDetails.setSubstation(subList.get(0).getId());
                devDetails.setSubstationName(dev.getSubstation());
                devDetails.setSubstationVoltageLevel(subList.get(0).getVoltageLevel());
                devDetails.setLongitude(subList.get(0).getLat());
                devDetails.setLatitude(subList.get(0).getLng());

                devDetails.setMonitoringTerminalCode(dev.getMonitoringTerminalName());
                devDetails.setMonitoringTerminalName(dev.getMonitoringTerminalName());
                String dy = PubUtil.getDicById(dev.getVoltageTransformerType(), voltageTransformer);
                if(StrUtil.isNotBlank(dy)){
                    devDetails.setVoltageTransformerType(dy);
                }else{
                    msg.append("电压互感器类型不存在!");
                }
                String jx = PubUtil.getDicById(dev.getTerminalWiringMethodType(), devConnect);
                if(StrUtil.isNotBlank(jx)){
                    devDetails.setTerminalWiringMethodType(jx);
                }else{
                    msg.append("终端接线方式类型不存在!");
                }
                String zx = PubUtil.getDicById(dev.getNeutralPointWiringMethod(), neutralPoint);
                if(StrUtil.isNotBlank(zx)){
                    devDetails.setNeutralPointWiringMethod(zx);
                }else{
                    msg.append("中性点接线方式不存在!");
                }
                String cj = PubUtil.getDicById(dev.getManufacturer(), devManufacturer);
                if(StrUtil.isNotBlank(cj)){
                    devDetails.setManufacturer(cj);
                }else{
                    msg.append("厂家不存在!");
                }
                devDetails.setManufacturerDeviceNumber(dev.getManufacturerDeviceNumber());
                devDetails.setTerminalIp(dev.getTerminalIp());

                String xh = PubUtil.getDicById(dev.getTerminalType(), devType);
                if(StrUtil.isNotBlank(xh)){
                    devDetails.setTerminalType(xh);
                }else{
                    msg.append("终端型号不存在!");
                }
                devDetails.setTerminalPort(dev.getTerminalPort());
                if(nodeMap.containsKey(dev.getFrontEndMachine())){
                    devDetails.setFrontEndMachine(nodeMap.get(dev.getFrontEndMachine()));
                }else{
                    msg.append("所属前置机不存在!");
                }
                devDetails.setCurrentTerminalDetectionTime(DateUtil.parseDate(dev.getCurrentTerminalDetectionTime()).toLocalDateTime());
                devDetails.setNextTerminalInspectionTime(DateUtil.parseDate(dev.getCurrentTerminalDetectionTime()).toLocalDateTime().plusYears(5));
                devDetails.setIdentificationCode(dev.getIdentificationCode());
                devDetails.setTerminalSecretKey(dev.getTerminalSecretKey());
                devDetails.setTerminalModel(dev.getTerminalModel());
                devDetails.setDataType(dev.getDataType());
                devDetails.setCommunicationStatus("0");
                devDetails.setSimCardNumber(dev.getSimCardNumber());
                devDetails.setCommissioningTime(DateUtil.parseDate(dev.getCommissioningTime()).toLocalDateTime());
                devDetails.setDataUpdateTime(StrUtil.isNotBlank(dev.getDataUpdateTime())?DateUtil.parseDate(dev.getDataUpdateTime()).toLocalDateTime():null);
                devDetails.setTimeSyncFunction(Integer.parseInt(dev.getTimeSyncFunction()));
                devDetails.setElectroplatingFunction(Integer.parseInt(dev.getElectroplatingFunction()));
                devDetails.setMonitoringDeviceInstallationPosition(dev.getMonitoringDeviceInstallationPosition());
                devDetails.setSummonFlag(dev.getSummonFlag());
                devDetails.setAlarmFunction(dev.getAlarmFunction());
                devDetails.setContractNumber(dev.getContractNumber());
                String tx = PubUtil.getDicById(dev.getFrontType(), frontType);
                if(StrUtil.isNotBlank(tx)){
                    devDetails.setFrontType(tx);
                }else{
                    msg.append("通讯类型不存在!");
                }
                String string = msg.toString();
                if(StrUtil.isNotBlank(string)){
                    SupervisionDevMainReportExcel.ExcelMsg sensitiveUserExcelMsg = new SupervisionDevMainReportExcel.ExcelMsg();
                    BeanUtils.copyProperties(dev, sensitiveUserExcelMsg);
                    sensitiveUserExcelMsg.setMsg(string);
                    devMsgList.add(sensitiveUserExcelMsg);
                    continue;
                }
                this.save(po);
                devDetails.setId(po.getId());
                supervisionTempDeviceReportService.saveOrUpdate(devDetails);
            }
        }
        //判断有没有错误信息
        if (CollectionUtil.isNotEmpty(devMsgList)) {
            ExcelUtil.exportExcel("失败列表.xlsx", SupervisionDevMainReportExcel.ExcelMsg.class, devMsgList);
        }
    }

    @Override
    public Boolean deleteDevReport(List<String> supervisionId) {
        List<SupervisionDevMainReportPO> supervisionDevMainReportPOS = this.listByIds(supervisionId);
        if(CollUtil.isEmpty(supervisionDevMainReportPOS)){
            throw new BusinessException(SupervisionResponseEnum.EXISTENCE_OR_NOT);
        }
        //判断是否有权限操作
        List<String> collect = supervisionDevMainReportPOS.stream().map(SupervisionDevMainReportPO::getCreateBy).distinct().collect(Collectors.toList());
        long count = supervisionDevMainReportPOS.stream().filter(x -> !BpmTaskStatusEnum.WAIT.getStatus().equals(x.getStatus())).count();
        InstanceUtil.deleteRole(RequestUtil.getUserIndex(), collect, count);
        return this.update(new LambdaUpdateWrapper<SupervisionDevMainReportPO>().set(SupervisionDevMainReportPO::getState, DataStateEnum.DELETED.getCode())
                .in(SupervisionDevMainReportPO::getId, supervisionId));
    }

    /**
     * @Description: 判断设备ip是否重复，如果重复提示
     * @param supervisionDevMainReportParam 终端详情 isExcludeSelf是否排除自己，一般新增不排除，更新时需要排除自己
     * @Author: clam
     * @Date: 2024/5/11
     */
    private void checkIp(SupervisionDevMainReportParam supervisionDevMainReportParam, boolean isExcludeSelf) {
        //如果保存不填ip则不校验
        if (!StringUtils.isEmpty(supervisionDevMainReportParam.getSupervisionTempDeviceReportParam().getTerminalIp())) {

            LambdaQueryWrapper<SupervisionTempDeviceReport> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper
                    .eq(SupervisionTempDeviceReport::getSubstation, supervisionDevMainReportParam.getSupervisionTempDeviceReportParam().getSubstation())
                    .eq(SupervisionTempDeviceReport::getTerminalIp, supervisionDevMainReportParam.getSupervisionTempDeviceReportParam().getTerminalIp());
            //更新的时候，需排除当前记录
            if (isExcludeSelf) {
                if (supervisionDevMainReportParam instanceof SupervisionDevMainReportParam.SupervisionDevMainReportParamUpdate) {
                    lambdaQueryWrapper.ne(SupervisionTempDeviceReport::getId, ((SupervisionDevMainReportParam.SupervisionDevMainReportParamUpdate) supervisionDevMainReportParam).getId());
                } else {
                    lambdaQueryWrapper.ne(SupervisionTempDeviceReport::getId, (supervisionDevMainReportParam).getId());

                }

            }
            List<SupervisionTempDeviceReport> list = supervisionTempDeviceReportService.getBaseMapper().selectList(lambdaQueryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                //过滤已取消的申请和删除的
                List<String> collect = list.stream().map(SupervisionTempDeviceReport::getId).collect(Collectors.toList());
                List<SupervisionDevMainReportPO> list1 = this.lambdaQuery().in(SupervisionDevMainReportPO::getId, collect).list();
                list1 = list1.stream()
                        .filter(userReportPO -> !userReportPO.getStatus().equals(FlowStatusEnum.CANCEL.getCode()))
                        .filter(userReportPO -> userReportPO.getState().equals(DataStateEnum.ENABLE.getCode()))
                        .collect(Collectors.toList());
                //如果还存在，则说明有人申请过了
                if (CollectionUtil.isNotEmpty(list1)) {
                    throw new BusinessException(supervisionDevMainReportParam.getSupervisionTempDeviceReportParam().getTerminalIp().concat("Ip已占用"));
                }
            }
        }
    }
}
