package com.njcn.process.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.constant.BizParamConstant;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.commApi.CommLineClient;
import com.njcn.device.biz.pojo.dto.LineALLInfoDTO;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.process.enums.ProcessResponseEnum;
import com.njcn.process.enums.ThsFlowTypeEnum;
import com.njcn.process.mapper.*;
import com.njcn.process.pojo.param.*;
import com.njcn.process.pojo.po.*;
import com.njcn.process.pojo.vo.*;
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
import com.njcn.process.service.IssuesService;
import com.njcn.process.service.flowable.IFlowDefinitionService;
import com.njcn.process.service.flowable.IFlowInstanceService;
import com.njcn.process.service.flowable.IFlowTaskService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 电能质量问题实现类
 *
 * @author xiaoyao
 * @version 1.0.0
 * @createTime 2022/11/14 11:03
 */
@Slf4j
@Service
@AllArgsConstructor
public class IssuesServiceImpl implements IssuesService {

    private final DeptFeignClient deptFeignClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final RStatElectricQualityProblemFlowMapper issuesMapper;

    private final RMpOnlineMonitorOverproofProblemMapper excessiveMapper;

    private final RMpGeneralSurveyOverproofProblemMapper generalSurveyMapper;

    private final RMpUserComplaintMapper complaintMapper;

    private final RMpOperationMonitorAbnormalMapper abnormalMapper;

    private final RMpElectricQualityProblemFlowDetailsMapper flowDetailsMapper;

    private final RStatElectricQualityProblemLogMapper rStatElectricQualityProblemLogMapper;

    private final FileStorageUtil fileStorageUtil;
    private final CommLineClient commLineClient;
    private final FlowableAssMapper flowableAssMapper;


    private final IFlowDefinitionService iFlowDefinitionService;

    private final IFlowInstanceService iFlowInstanceService;

    private final IFlowTaskService iFlowTaskService;

    private final FlowFormAssMapper flowFormAssMapper;
    /**
     * 新增电能质量问题流程表信息
     */
    private LocalDateTime addIssues(IssuesParam issuesParam, String powerQualityProblemNo) {
        RStatElectricQualityProblemFlow issues = new RStatElectricQualityProblemFlow();
        LocalDateTime local = LocalDateTimeUtil.now();
        BeanUtil.copyProperties(issuesParam, issues);
        issues.setPowerQualityProblemNo(powerQualityProblemNo);
        issues.setDataDate(local);
        issues.setStartTime(null);
        issues.setUpdateTime(null);
        issues.setReportProcess(DicDataEnum.NOT_REPORTED.getCode());
        issues.setReportProcessStatus(DicDataEnum.INIT.getCode());
        issuesMapper.insert(issues);
        return local;
    }

    /**
     * 生成问题编号
     */
    private String getPowerQualityProblemNo(IssuesParam issuesParam) {
        StringBuilder powerQualityProblemNo = new StringBuilder();
        powerQualityProblemNo.append(PinyinUtil.getFirstLetter(issuesParam.getOrgName(), "").toUpperCase()).append("-");
        if (DicDataEnum.ONLINE.getCode().equals(issuesParam.getProblemSources())) {
            powerQualityProblemNo.append("ZXJC");
        } else if (DicDataEnum.GENERAL.getCode().equals(issuesParam.getProblemSources())) {
            powerQualityProblemNo.append("PCCB");
        } else if (DicDataEnum.USER_COMPLAINTS.getCode().equals(issuesParam.getProblemSources())) {
            powerQualityProblemNo.append("YHTS");
        } else if (DicDataEnum.DEV_EXCEPTION.getCode().equals(issuesParam.getProblemSources())) {
            powerQualityProblemNo.append("YWYC");
        }
        String nowDate = DateUtil.format(new Date(), "yyyyMMdd");
        String processDate = DateUtil.format(new Date(), "yyyy-MM-dd");
        powerQualityProblemNo.append(nowDate);
        LambdaQueryWrapper<RStatElectricQualityProblemFlow> issuesQuery = new LambdaQueryWrapper<>();
        LocalDateTime local = LocalDateTimeUtil.parse(processDate + "T00:00:00");
        LocalDateTime localEnd = LocalDateTimeUtil.parse(processDate + "T23:59:59");
        issuesQuery.ge(RStatElectricQualityProblemFlow::getDataDate, local).le(RStatElectricQualityProblemFlow::getDataDate, localEnd);
        Integer count = issuesMapper.selectCount(issuesQuery);
        powerQualityProblemNo.append(StrUtil.padPre(String.valueOf(count + 1), 5, '0'));
        return powerQualityProblemNo.toString();
    }

    /**
     * 填报在线监测超标问题
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void   addExcessiveIssues(ExcessiveParam excessiveParam) {
        IssuesParam issuesParam = new IssuesParam();
        BeanUtil.copyProperties(excessiveParam, issuesParam);
        String powerQualityProblemNo = getPowerQualityProblemNo(issuesParam);
        LocalDateTime localDateTime = addIssues(issuesParam, powerQualityProblemNo);
        RMpOnlineMonitorOverproofProblem excessive = new RMpOnlineMonitorOverproofProblem();
        BeanUtil.copyProperties(excessiveParam, excessive);
        excessive.setPowerQualityProblemNo(powerQualityProblemNo);
        excessive.setDataDate(localDateTime);
        excessiveMapper.insert(excessive);
        //生成电能质量工作流
        createflow(powerQualityProblemNo,1);

    }

    /**
     * 填报普测超标问题
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void addGeneralSurveyIssues(GeneralSurveyParam generalSurveyParam) {
        IssuesParam issuesParam = new IssuesParam();
        BeanUtil.copyProperties(generalSurveyParam, issuesParam);
        String powerQualityProblemNo = getPowerQualityProblemNo(issuesParam);
        LocalDateTime localDateTime = addIssues(issuesParam, powerQualityProblemNo);
        RMpGeneralSurveyOverproofProblem generalSurvey = new RMpGeneralSurveyOverproofProblem();
        BeanUtil.copyProperties(generalSurveyParam, generalSurvey);
        generalSurvey.setOverLimitTarget(ArrayUtil.toString(generalSurveyParam.getSteadyState()) + ArrayUtil.toString(generalSurveyParam.getTransientIndicators()));
        generalSurvey.setPowerQualityProblemNo(powerQualityProblemNo);
        generalSurvey.setDataDate(localDateTime);
        generalSurveyMapper.insert(generalSurvey);
        //生成电能质量工作流
        createflow(powerQualityProblemNo,4);

    }

    /**
     * 填报用户投诉问题
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void addComplaintIssues(ComplaintParam complaintParam) {
        IssuesParam issuesParam = new IssuesParam();
        BeanUtil.copyProperties(complaintParam, issuesParam);
        String powerQualityProblemNo = getPowerQualityProblemNo(issuesParam);
        LocalDateTime localDateTime = addIssues(issuesParam, powerQualityProblemNo);
        RMpUserComplaint complaint = new RMpUserComplaint();
        BeanUtil.copyProperties(complaintParam, complaint);
        complaint.setAbnormalTarget(ArrayUtil.toString(complaintParam.getSteadyState()) + ArrayUtil.toString(complaintParam.getTransientIndicators()));
        complaint.setPowerQualityProblemNo(powerQualityProblemNo);
        complaint.setDataDate(localDateTime);
        complaintMapper.insert(complaint);
        //生成电能质量工作流
        createflow(powerQualityProblemNo,3);
    }

    /**
     * 填报运维监控异常问题
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void addAbnormalIssues(AbnormalParam abnormalParam) {
        IssuesParam issuesParam = new IssuesParam();
        BeanUtil.copyProperties(abnormalParam, issuesParam);
        String powerQualityProblemNo = getPowerQualityProblemNo(issuesParam);
        LocalDateTime localDateTime = addIssues(issuesParam, powerQualityProblemNo);
        RMpOperationMonitorAbnormal abnormal = new RMpOperationMonitorAbnormal();
        BeanUtil.copyProperties(abnormalParam, abnormal);
        abnormal.setAbnormalTarget(ArrayUtil.toString(abnormalParam.getSteadyState()) + ArrayUtil.toString(abnormalParam.getTransientIndicators()));
        abnormal.setPowerQualityProblemNo(powerQualityProblemNo);
        abnormal.setDataDate(localDateTime);
        abnormalMapper.insert(abnormal);
        //生成电能质量工作流
        createflow(powerQualityProblemNo,2);
    }

    public Boolean createflow(String thsIndex ,Integer type) {
        String userId = RequestUtil.getUserIndex();


        //绑定工作流
        Map<String, Object> map = new HashMap<>();


            //开始流程
            FlowFormAss flowFormAss = flowFormAssMapper.selectOne(new LambdaQueryWrapper<FlowFormAss>().eq(FlowFormAss::getFormId, 3));
            if (Objects.isNull(flowFormAss)) {
                throw new BusinessException("当前功能未绑定流程,请先绑定流程");
            }
            map.put("type",type);
            String processId = iFlowDefinitionService.startProcessInstanceById(flowFormAss.getDefinitionId(), thsIndex, ThsFlowTypeEnum.powerQualityManagement.getCode(), map);
            Task task = iFlowTaskService.getTask(processId);
            FlowTaskVo flowTaskVo = new FlowTaskVo();
            flowTaskVo.setTaskId(task.getId());
            flowTaskVo.setInstanceId(processId);
            flowTaskVo.setComment(RequestUtil.getUserNickname() + "发起电能质量申请");
            map.put("auditFlag",1);
            flowTaskVo.setVariables(map);
            iFlowTaskService.complete(flowTaskVo);

        return true;
    }

    /**
     * 查询问题列表
     */
    @Override
    public Page<IssuesVO> getIssues(QueryIssuesParam param) {
        Page<IssuesVO> page = new Page<>(param.getPageNum(), param.getPageSize());
        Date dateOut = DateUtil.parse(param.getDataDate());
        Date dateBegin = new Date();
        Date dateEnd = new Date();
        if (Integer.valueOf(BizParamConstant.STAT_BIZ_YEAR).equals(param.getDataType())) {
            dateBegin = DateUtil.beginOfYear(dateOut);
            dateEnd = DateUtil.endOfYear(dateOut);
        } else if (Integer.valueOf(BizParamConstant.STAT_BIZ_QUARTER).equals(param.getDataType())) {
            dateBegin = DateUtil.beginOfQuarter(dateOut);
            dateEnd = DateUtil.endOfQuarter(dateOut);
        } else if (Integer.valueOf(BizParamConstant.STAT_BIZ_MONTH).equals(param.getDataType())) {
            dateBegin = DateUtil.beginOfMonth(dateOut);
            dateEnd = DateUtil.endOfMonth(dateOut);
        }
        List<String> deptIds = deptFeignClient.getDepSonIdtByDeptId(param.getOrgNo()).getData();

        List<IssuesVO> out = issuesMapper.getIssues(deptIds, param, DateUtil.formatDateTime(dateBegin), DateUtil.formatDateTime(dateEnd));
        if (!CollectionUtils.isEmpty(out)) {
            out.forEach(data -> data.setOrgName((deptFeignClient.getDeptById(data.getOrgNo()).getData().getName())));
            /*问题来源*/
            List<DictData> problemSourcesDictData = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.PROBLEM_SOURCES.getCode()).getData();
            problemSourcesDictData.forEach(dict -> out.stream().filter(data -> dict.getCode().equals(data.getProblemSources())).forEach(data -> data.setProblemSources(dict.getName())));
            page.setTotal(out.size());
            int pages = (int) Math.ceil(out.size() * 1.0 / param.getPageSize());
            page.setPages(pages);
            List<List<IssuesVO>> partition = Lists.partition(out, param.getPageSize());
            List<IssuesVO> issuesVOS = partition.get(param.getPageNum() - 1);
            page.setRecords(issuesVOS);
        }
        return page;
    }

    /**
     * 问题基本信息查询
     */
    private RStatElectricQualityProblemFlow issuesSelectOne(String powerQualityProblemNo) {
        LambdaQueryWrapper<RStatElectricQualityProblemFlow> issuesQuery = new LambdaQueryWrapper<>();
        issuesQuery.eq(RStatElectricQualityProblemFlow::getPowerQualityProblemNo, powerQualityProblemNo);
        return issuesMapper.selectOne(issuesQuery);
    }

    /**
     * 填报流程详情查询
     */
    private RMpElectricQualityProblemFlowDetails flowDetailSelectOne(String powerQualityProblemNo) {
        LambdaQueryWrapper<RMpElectricQualityProblemFlowDetails> flowQuery = new LambdaQueryWrapper<>();
        flowQuery.eq(RMpElectricQualityProblemFlowDetails::getPowerQualityProblemNo, powerQualityProblemNo);
        RMpElectricQualityProblemFlowDetails rMpElectricQualityProblemFlowDetails = flowDetailsMapper.selectOne(flowQuery);
        if(Objects.isNull(rMpElectricQualityProblemFlowDetails)){
            rMpElectricQualityProblemFlowDetails = new RMpElectricQualityProblemFlowDetails();
        }
        return rMpElectricQualityProblemFlowDetails;
    }

    /**
     * 处理填报信息
     */
    private FlowDetailVO processFlowDetail(RMpElectricQualityProblemFlowDetails details) {
        FlowDetailVO process = new FlowDetailVO();
        BeanUtil.copyProperties(details, process);
        if (!StrUtil.isEmpty(details.getReportProcessContentYyfx())) {
            process.setReportProcessContentYyfx(StrUtil.removeSuffix(StrUtil.removePrefix(details.getReportProcessContentYyfx(), "["), "]").split(","));
            StrUtil.trim(process.getReportProcessContentYyfx());
        }
        if (!StrUtil.isEmpty(details.getUserReportProcessContentYyfx())) {
            process.setUserReportProcessContentYyfx(StrUtil.removeSuffix(StrUtil.removePrefix(details.getUserReportProcessContentYyfx(), "["), "]").split(","));
            StrUtil.trim(process.getUserReportProcessContentYyfx());
        }
        if (!StrUtil.isEmpty(details.getReportProcessContentJhzg())) {
            process.setReportProcessContentJhzg(StrUtil.removeSuffix(StrUtil.removePrefix(details.getReportProcessContentJhzg(), "["), "]").split(","));
            StrUtil.trim(process.getReportProcessContentJhzg());
        }
        if (!StrUtil.isEmpty(details.getUserReportProcessContentJhzg())) {
            process.setUserReportProcessContentJhzg(StrUtil.removeSuffix(StrUtil.removePrefix(details.getUserReportProcessContentJhzg(), "["), "]").split(","));
            StrUtil.trim(process.getUserReportProcessContentJhzg());
        }
        if (!StrUtil.isEmpty(details.getReportProcessContentSjcq())) {
            process.setReportProcessContentSjcq(StrUtil.removeSuffix(StrUtil.removePrefix(details.getReportProcessContentSjcq(), "["), "]").split(","));
            StrUtil.trim(process.getReportProcessContentSjcq());
        }
        if (!StrUtil.isEmpty(details.getUserReportProcessContentSjcq())) {
            process.setUserReportProcessContentSjcq(StrUtil.removeSuffix(StrUtil.removePrefix(details.getUserReportProcessContentSjcq(), "["), "]").split(","));
            StrUtil.trim(process.getUserReportProcessContentSjcq());
        }
        return process;
    }

    /**
     * 查询在线监测超标问题详情
     */
    @Override
    public ExcessiveDetailVO getExcessiveDetail(String powerQualityProblemNo) {
        ExcessiveDetailVO detail = new ExcessiveDetailVO();
        BeanUtil.copyProperties(issuesSelectOne(powerQualityProblemNo), detail);
        detail.setOrgName(deptFeignClient.getDeptById(detail.getOrgNo()).getData().getName());


        LambdaQueryWrapper<RMpOnlineMonitorOverproofProblem> excessiveQuery = new LambdaQueryWrapper<>();
        excessiveQuery.eq(RMpOnlineMonitorOverproofProblem::getPowerQualityProblemNo, powerQualityProblemNo);
        RMpOnlineMonitorOverproofProblem excessiveOut = excessiveMapper.selectOne(excessiveQuery);

        BeanUtil.copyProperties(excessiveOut, detail);
        LineALLInfoDTO lineALLInfoDTO = commLineClient.getLineAllDetail(excessiveOut.getMeasurementPointId()).getData();
        detail.setBarId(lineALLInfoDTO.getLineBusbarDTO().getBusBarId());
        detail.setBarName(lineALLInfoDTO.getLineBusbarDTO().getBusBarName());
        detail.setObjName(lineALLInfoDTO.getLineLineDTO().getObjName());
        detail.setLoadType(lineALLInfoDTO.getLineLineDTO().getLoadType());
        detail.setVoltageLevel(lineALLInfoDTO.getLineLineDTO().getVoltageLevel());
        detail.setSubstationId(lineALLInfoDTO.getLineSubStationDTO().getSubStationId());
        detail.setSubstationName(lineALLInfoDTO.getLineSubStationDTO().getSubStationName());
        RMpElectricQualityProblemFlowDetails flowDetails = flowDetailSelectOne(powerQualityProblemNo);
        BeanUtil.copyProperties(processFlowDetail(flowDetails), detail);
        return detail;
    }

    /**
     * 查询用户投诉问题详情
     */
    @Override
    public GeneralSurveyVO getGeneralSurveyDetail(String powerQualityProblemNo) {
        GeneralSurveyVO detail = new GeneralSurveyVO();
        BeanUtil.copyProperties(issuesSelectOne(powerQualityProblemNo), detail);
        detail.setOrgName(deptFeignClient.getDeptById(detail.getOrgNo()).getData().getName());
        LambdaQueryWrapper<RMpGeneralSurveyOverproofProblem> generalSurveyQuery = new LambdaQueryWrapper<>();
        generalSurveyQuery.eq(RMpGeneralSurveyOverproofProblem::getPowerQualityProblemNo, powerQualityProblemNo);
        RMpGeneralSurveyOverproofProblem generalSurveyOut = generalSurveyMapper.selectOne(generalSurveyQuery);
        BeanUtil.copyProperties(generalSurveyOut, detail);
        detail.setSteadyIndicator(steadyIndicator(generalSurveyOut.getOverLimitTarget()));
        detail.setTransientIndicators(transientIndicators(generalSurveyOut.getOverLimitTarget()));
        RMpElectricQualityProblemFlowDetails flowDetails = flowDetailSelectOne(powerQualityProblemNo);
        BeanUtil.copyProperties(processFlowDetail(flowDetails), detail);
        return detail;
    }

    /**
     * 查询用户投诉问题详情
     */
    @Override
    public ComplaintVO getComplaintDetail(String powerQualityProblemNo) {
        ComplaintVO detail = new ComplaintVO();
        BeanUtil.copyProperties(issuesSelectOne(powerQualityProblemNo), detail);
        detail.setOrgName(deptFeignClient.getDeptById(detail.getOrgNo()).getData().getName());
        LambdaQueryWrapper<RMpUserComplaint> complaintQuery = new LambdaQueryWrapper<>();
        complaintQuery.eq(RMpUserComplaint::getPowerQualityProblemNo, powerQualityProblemNo);
        RMpUserComplaint complaintOut = complaintMapper.selectOne(complaintQuery);
        BeanUtil.copyProperties(complaintOut, detail);
        detail.setSteadyIndicator(steadyIndicator(complaintOut.getAbnormalTarget()));
        detail.setTransientIndicators(transientIndicators(complaintOut.getAbnormalTarget()));
        RMpElectricQualityProblemFlowDetails flowDetails = flowDetailSelectOne(powerQualityProblemNo);
        BeanUtil.copyProperties(processFlowDetail(flowDetails), detail);
        if (!StrUtil.isEmpty(complaintOut.getPowerGridAffectDev())) {
            detail.setPowerGridAffectDev(StrUtil.removeSuffix(StrUtil.removePrefix(complaintOut.getPowerGridAffectDev(), "["), "]").split(","));
            StrUtil.trim(detail.getPowerGridAffectDev());
        }
        if (!StrUtil.isEmpty(complaintOut.getUserAffectDev())) {
            detail.setUserAffectDev(StrUtil.removeSuffix(StrUtil.removePrefix(complaintOut.getUserAffectDev(), "["), "]").split(","));
            StrUtil.trim(detail.getUserAffectDev());
        }
        return detail;
    }

    /**
     * 查询运维异常问题详情
     */
    @Override
    public AbnormalVO getAbnormalDetail(String powerQualityProblemNo) {
        AbnormalVO detail = new AbnormalVO();
        BeanUtil.copyProperties(issuesSelectOne(powerQualityProblemNo), detail);
        detail.setOrgName(deptFeignClient.getDeptById(detail.getOrgNo()).getData().getName());
        LambdaQueryWrapper<RMpOperationMonitorAbnormal> abnormalQuery = new LambdaQueryWrapper<>();
        abnormalQuery.eq(RMpOperationMonitorAbnormal::getPowerQualityProblemNo, powerQualityProblemNo);
        RMpOperationMonitorAbnormal abnormalOut = abnormalMapper.selectOne(abnormalQuery);
        BeanUtil.copyProperties(abnormalOut, detail);
        detail.setSteadyIndicator(steadyIndicator(abnormalOut.getAbnormalTarget()));
        detail.setTransientIndicators(transientIndicators(abnormalOut.getAbnormalTarget()));
        RMpElectricQualityProblemFlowDetails flowDetails = flowDetailSelectOne(powerQualityProblemNo);
        BeanUtil.copyProperties(processFlowDetail(flowDetails), detail);
        if (!StrUtil.isEmpty(abnormalOut.getPowerGridAffectDev())) {
            detail.setPowerGridAffectDev(StrUtil.removeSuffix(StrUtil.removePrefix(abnormalOut.getPowerGridAffectDev(), "["), "]").split(","));
            StrUtil.trim(detail.getPowerGridAffectDev());
        }
        if (!StrUtil.isEmpty(abnormalOut.getUserAffectDev())) {
            detail.setUserAffectDev(StrUtil.removeSuffix(StrUtil.removePrefix(abnormalOut.getUserAffectDev(), "["), "]").split(","));
            StrUtil.trim(detail.getUserAffectDev());
        }
        return detail;
    }

    /**
     * 稳态指标处理
     */
    private String[] steadyIndicator(String target) {
        String[] process = StrUtil.removePrefix(target.split("]\\[")[0], "\\[").split(",");
        StrUtil.trim(process);
        return process;
    }

    /**
     * 暂态指标处理
     */
    private String[] transientIndicators(String target) {
        String[] process = StrUtil.removeSuffix(target.split("]\\[")[1], "]").split(",");
        StrUtil.trim(process);
        return process;
    }

    /**
     * 原因分析
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void reasonAnalysis(ProcessParam processParam) {
        LocalDateTime local = LocalDateTimeUtil.now();
        RMpElectricQualityProblemFlowDetails details = new RMpElectricQualityProblemFlowDetails();
        BeanUtil.copyProperties(processParam, details);
        details.setDataDateYyfx(local);
        details.setReportProcessContentYyfx(ArrayUtil.toString(processParam.getReportProcessContentYyfx()));
        details.setUserReportProcessContentYyfx(ArrayUtil.toString(processParam.getUserReportProcessContentYyfx()));
        RMpElectricQualityProblemFlowDetails rMpElectricQualityProblemFlowDetails = flowDetailsMapper.selectById(details.getPowerQualityProblemNo());
        if (rMpElectricQualityProblemFlowDetails != null) {
            flowDetailsMapper.updateById(details);
        }else {
            flowDetailsMapper.insert(details);

        }
        LambdaQueryWrapper<RStatElectricQualityProblemFlow> issuesQuery = new LambdaQueryWrapper<>();
        issuesQuery.eq(RStatElectricQualityProblemFlow::getPowerQualityProblemNo, processParam.getPowerQualityProblemNo());
        RStatElectricQualityProblemFlow issuesOut = issuesMapper.selectOne(issuesQuery);
        issuesOut.setReportProcess(DicDataEnum.CAUSE_ANALYSIS.getCode());
        issuesOut.setReportProcessStatus(DicDataEnum.AUDITT.getCode());
        issuesMapper.update(issuesOut, issuesQuery);
        if (DicDataEnum.USER_COMPLAINTS.getCode().equals(issuesOut.getProblemSources())) {
            LambdaQueryWrapper<RMpUserComplaint> complaintQuery = new LambdaQueryWrapper<>();
            complaintQuery.eq(RMpUserComplaint::getPowerQualityProblemNo, processParam.getPowerQualityProblemNo());
            RMpUserComplaint complaintOut = complaintMapper.selectOne(complaintQuery);
            complaintOut.setPowerGridAffectDev(ArrayUtil.toString(processParam.getPowerGridAffectDev()));
            complaintOut.setUserAffectDev(ArrayUtil.toString(processParam.getUserAffectDev()));
            complaintMapper.update(complaintOut, complaintQuery);
        } else if (DicDataEnum.DEV_EXCEPTION.getCode().equals(issuesOut.getProblemSources())) {
            LambdaQueryWrapper<RMpOperationMonitorAbnormal> abnormalQuery = new LambdaQueryWrapper<>();
            abnormalQuery.eq(RMpOperationMonitorAbnormal::getPowerQualityProblemNo, processParam.getPowerQualityProblemNo());
            RMpOperationMonitorAbnormal abnormalOut = abnormalMapper.selectOne(abnormalQuery);
            abnormalOut.setPowerGridAffectDev(ArrayUtil.toString(processParam.getPowerGridAffectDev()));
            abnormalOut.setUserAffectDev(ArrayUtil.toString(processParam.getUserAffectDev()));
            abnormalMapper.update(abnormalOut, abnormalQuery);
        }
    }

    /**
     * 计划整改措施、实际采取措施、成效分析
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void process(ProcessParam processParam, String code) {
        LambdaQueryWrapper<RStatElectricQualityProblemFlow> issuesQuery = new LambdaQueryWrapper<>();
        issuesQuery.eq(RStatElectricQualityProblemFlow::getPowerQualityProblemNo, processParam.getPowerQualityProblemNo());
        RStatElectricQualityProblemFlow issuesOut = issuesMapper.selectOne(issuesQuery);
        String createBy = issuesOut.getCreateBy();
        String userIndex = RequestUtil.getUserIndex();
        if(!Objects.equals(createBy,userIndex)){
            throw new BusinessException(ProcessResponseEnum.NO_PERMISSION);
        }
        if (DicDataEnum.SUCCESS.getCode().equals(issuesOut.getReportProcessStatus())) {
            LambdaQueryWrapper<RMpElectricQualityProblemFlowDetails> query = new LambdaQueryWrapper<>();
            query.eq(RMpElectricQualityProblemFlowDetails::getPowerQualityProblemNo, processParam.getPowerQualityProblemNo());
            RMpElectricQualityProblemFlowDetails details = flowDetailsMapper.selectOne(query);
            LocalDateTime local = LocalDateTimeUtil.now();
            if (DicDataEnum.PLAN_MEASURES.getCode().equals(code)) {
                details.setDataDateJhzg(local);
                details.setReportProcessContentJhzg(ArrayUtil.toString(processParam.getReportProcessContentJhzg()));
                details.setUserReportProcessContentJhzg(ArrayUtil.toString(processParam.getUserReportProcessContentJhzg()));
                details.setFileNameJhzg(processParam.getFileNameJhzg());
                details.setFilePathJhzg(processParam.getFilePathJhzg());
            } else if (DicDataEnum.ACTUAL_MEASURES.getCode().equals(code)) {
                details.setDataDateSjcq(local);
                details.setReportProcessContentSjcq(ArrayUtil.toString(processParam.getReportProcessContentSjcq()));
                details.setUserReportProcessContentSjcq(ArrayUtil.toString(processParam.getUserReportProcessContentSjcq()));
                details.setFileNameSjcq(processParam.getFileNameSjcq());
                details.setFilePathSjcq(processParam.getFilePathSjcq());
            } else if (DicDataEnum.INSIGHTS.getCode().equals(code)) {
                details.setDataDateZlxg(local);
                details.setDescriptionZlxg(processParam.getDescriptionZlxg());
                details.setFileNameZlxg(processParam.getFileNameZlxg());
                details.setFilePathZlxg(processParam.getFilePathZlxg());
            }
            flowDetailsMapper.update(details, query);
            issuesOut.setReportProcess(code);
            issuesOut.setReportProcessStatus(DicDataEnum.AUDITT.getCode());
            issuesMapper.update(issuesOut, issuesQuery);
        } else {
            throw new BusinessException(ProcessResponseEnum.PROCESS_ERROR);
        }
    }

    /**
     * 问题归档
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void archive(String powerQualityProblemNo) {
        LambdaQueryWrapper<RStatElectricQualityProblemFlow> query = new LambdaQueryWrapper<>();
        query.eq(RStatElectricQualityProblemFlow::getPowerQualityProblemNo, powerQualityProblemNo);
        RStatElectricQualityProblemFlow issuesOut = issuesMapper.selectOne(query);
        String createBy = issuesOut.getCreateBy();
        String userIndex = RequestUtil.getUserIndex();
        if(!Objects.equals(createBy,userIndex)){
            throw new BusinessException(ProcessResponseEnum.NO_PERMISSION);
        }
        if (DicDataEnum.INSIGHTS.getCode().equals(issuesOut.getReportProcess())
                && DicDataEnum.SUCCESS.getCode().equals(issuesOut.getReportProcessStatus())) {
            issuesOut.setReportProcess(DicDataEnum.ARCHIVED.getCode());
            issuesMapper.update(issuesOut, query);
        } else {
            throw new BusinessException(ProcessResponseEnum.ARCHIVE_ERROR);
        }
    }

    /**
     * 上传文件
     */
    @Override
    public String uploadFile(MultipartFile issuesFile) {
        return fileStorageUtil.getFileUrl( fileStorageUtil.uploadMultipart(issuesFile, OssPath.ELECTRICITY_QUALITY));
    }

    /**
     * 下载文件
     */
    @Override
    public String downloadFile(String powerQualityProblemNo, String reportProcess) {
        LambdaQueryWrapper<RMpElectricQualityProblemFlowDetails> issuesQuery = new LambdaQueryWrapper<>();
        issuesQuery.eq(RMpElectricQualityProblemFlowDetails::getPowerQualityProblemNo, powerQualityProblemNo);
        RMpElectricQualityProblemFlowDetails details = flowDetailsMapper.selectOne(issuesQuery);
        String filePath = null;
        if (DicDataEnum.CAUSE_ANALYSIS.getName().equals(reportProcess)) {
            filePath = details.getFilePathYyfx();
        } else if (DicDataEnum.PLAN_MEASURES.getName().equals(reportProcess)) {
            filePath = details.getFilePathJhzg();
        } else if (DicDataEnum.ACTUAL_MEASURES.getName().equals(reportProcess)) {
            filePath = details.getFilePathSjcq();
        } else if (DicDataEnum.INSIGHTS.getName().equals(reportProcess)) {
            filePath = details.getFilePathZlxg();
        }
        return filePath;
    }

    /**
     * 删除问题
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void deleteIssues(String powerQualityProblemNo) {
        LambdaQueryWrapper<RStatElectricQualityProblemFlow> query = new LambdaQueryWrapper<>();
        query.eq(RStatElectricQualityProblemFlow::getPowerQualityProblemNo, powerQualityProblemNo);
        RStatElectricQualityProblemFlow issuesOut = issuesMapper.selectOne(query);
        String createBy = issuesOut.getCreateBy();
        String userIndex = RequestUtil.getUserIndex();
        if(!Objects.equals(createBy,userIndex)){
            throw new BusinessException(ProcessResponseEnum.NO_PERMISSION);
        }
        if (DicDataEnum.ONLINE.getCode().equals(issuesOut.getProblemSources())) {
            LambdaQueryWrapper<RMpOnlineMonitorOverproofProblem> issuesQuery = new LambdaQueryWrapper<>();
            issuesQuery.eq(RMpOnlineMonitorOverproofProblem::getPowerQualityProblemNo, powerQualityProblemNo);
            excessiveMapper.delete(issuesQuery);
        } else if (DicDataEnum.GENERAL.getCode().equals(issuesOut.getProblemSources())) {
            LambdaQueryWrapper<RMpGeneralSurveyOverproofProblem> issuesQuery = new LambdaQueryWrapper<>();
            issuesQuery.eq(RMpGeneralSurveyOverproofProblem::getPowerQualityProblemNo, powerQualityProblemNo);
            generalSurveyMapper.delete(issuesQuery);
        } else if (DicDataEnum.USER_COMPLAINTS.getCode().equals(issuesOut.getProblemSources())) {
            LambdaQueryWrapper<RMpUserComplaint> issuesQuery = new LambdaQueryWrapper<>();
            issuesQuery.eq(RMpUserComplaint::getPowerQualityProblemNo, powerQualityProblemNo);
            complaintMapper.delete(issuesQuery);
        } else if (DicDataEnum.DEV_EXCEPTION.getCode().equals(issuesOut.getProblemSources())) {
            LambdaQueryWrapper<RMpOperationMonitorAbnormal> issuesQuery = new LambdaQueryWrapper<>();
            issuesQuery.eq(RMpOperationMonitorAbnormal::getPowerQualityProblemNo, powerQualityProblemNo);
            abnormalMapper.delete(issuesQuery);
        }
        LambdaQueryWrapper<RMpElectricQualityProblemFlowDetails> issuesQuery = new LambdaQueryWrapper<>();
        issuesQuery.eq(RMpElectricQualityProblemFlowDetails::getPowerQualityProblemNo, powerQualityProblemNo);
        flowDetailsMapper.delete(issuesQuery);
        issuesMapper.delete(query);
    }

    /**
     * @param orgNo
     * @Description: 查询问题及工单（当前部门下）
     * @Param: [orgNo]
     * @return: com.njcn.process.pojo.vo.IssueesAndOrderVO
     * @Author: clam
     * @Date: 2023/1/5
     */
    @Override
    public IssueesAndOrderVO queryIssuesAndOrder(String orgNo) {
        IssueesAndOrderVO issueesAndOrderVO = new IssueesAndOrderVO();

        List<String> deptIds = deptFeignClient.getDepSonIdtByDeptId(orgNo).getData();
        /*问题个数*/
        QueryWrapper<RStatElectricQualityProblemFlow> qualityProblemFlowQueryWrapper = new QueryWrapper<>();
        qualityProblemFlowQueryWrapper.select("1").
                in("orgNo", deptIds);
        Integer integer = issuesMapper.selectCount(qualityProblemFlowQueryWrapper);
        issueesAndOrderVO.setId(orgNo);
        issueesAndOrderVO.setIssueesCount(integer);
        /*已关联工单数量*/


        return issueesAndOrderVO;
    }

    /**
     * @param electricityQualityCheckParam
     * @Description: 电能质量问题审核
     * @Param: [electricityQualityCheckParam]
     * @return: java.lang.Boolean
     * @Author: clam
     * @Date: 2023/2/22
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean checkPowerQuality(ElectricityQualityCheckParam electricityQualityCheckParam) {
        boolean result = true;
        RStatElectricQualityProblemLogPO rStatElectricQualityProblemLogPO = new RStatElectricQualityProblemLogPO();
        rStatElectricQualityProblemLogPO.setPowerQualityProblemNo(electricityQualityCheckParam.getPowerQualityProblemNo());
        rStatElectricQualityProblemLogPO.setChecker(electricityQualityCheckParam.getCheckPerson());
        rStatElectricQualityProblemLogPO.setDataDate(new Date());
        rStatElectricQualityProblemLogPO.setDescription(electricityQualityCheckParam.getCheckComment());
        rStatElectricQualityProblemLogPO.setReportProcess(electricityQualityCheckParam.getReportProcess());
        rStatElectricQualityProblemLogPO.setReportProcessContent(electricityQualityCheckParam.getCheckComment());

        rStatElectricQualityProblemLogPO.setType(Objects.equals("1", electricityQualityCheckParam.getCheckResult()) ? DicDataEnum.SUCCESS.getCode() : DicDataEnum.FAIL.getCode());
        /*插入审核日志表*/
        int insert = rStatElectricQualityProblemLogMapper.insert(rStatElectricQualityProblemLogPO);
        String report_process = "";
        String report_process_status = "";
        String reportProcess = electricityQualityCheckParam.getReportProcess();
        String checkResult = electricityQualityCheckParam.getCheckResult();
//        if (DicDataEnum.CAUSE_ANALYSIS.getCode().equals(reportProcess)) {
//            if (Objects.equals("1", checkResult)) {
//                report_process_status = DicDataEnum.SUCCESS.getCode();
//                report_process = DicDataEnum.PLAN_MEASURES.getCode();
//            } else {
//                report_process_status = DicDataEnum.FAIL.getCode();
//                report_process = DicDataEnum.CAUSE_ANALYSIS.getCode();
//            }
//        } else if (DicDataEnum.PLAN_MEASURES.getCode().equals(reportProcess)) {
//            if (Objects.equals("1", checkResult)) {
//                report_process_status = DicDataEnum.SUCCESS.getCode();
//                report_process = DicDataEnum.ACTUAL_MEASURES.getCode();
//            } else {
//                report_process_status = DicDataEnum.FAIL.getCode();
//                report_process = DicDataEnum.PLAN_MEASURES.getCode();
//            }
//
//        } else if (DicDataEnum.ACTUAL_MEASURES.getCode().equals(reportProcess)) {
//            if (Objects.equals("1", checkResult)) {
//                report_process_status = DicDataEnum.AUDITT.getCode();
//                report_process = DicDataEnum.INSIGHTS.getCode();
//            } else {
//                report_process_status = DicDataEnum.FAIL.getCode();
//                report_process = DicDataEnum.ACTUAL_MEASURES.getCode();
//            }
//
//        } else if (DicDataEnum.INSIGHTS.getCode().equals(reportProcess)) {
//
//            if (Objects.equals("1", checkResult)) {
//                report_process_status = DicDataEnum.AUDITT.getCode();
//                report_process = DicDataEnum.ARCHIVED.getCode();
//            } else {
//                report_process_status = DicDataEnum.FAIL.getCode();
//                report_process = DicDataEnum.INSIGHTS.getCode();
//            }
//        }
        if (Objects.equals ("1", checkResult)) {
            report_process_status = DicDataEnum.SUCCESS.getCode ( );
        } else {
            report_process_status = DicDataEnum.FAIL.getCode ( );
        }
        UpdateWrapper<RStatElectricQualityProblemFlow> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("power_quality_problem_no", electricityQualityCheckParam.getPowerQualityProblemNo());
//        updateWrapper.set("report_process", report_process);
        updateWrapper.set("report_process_status", report_process_status);
        int i = issuesMapper.update(null, updateWrapper);
        result = insert == 1 && i == 1;
        return result;
    }

    /**
     * @param powerQualityProblemNo
     * @Description: 历史审核记录查询
     * @Param: [powerQualityProblemNo]
     * @return: java.util.List<com.njcn.process.pojo.vo.RStatElectricQualityProblemLogVO>
     * @Author: clam
     * @Date: 2023/2/23
     */
    @Override
    public List<RStatElectricQualityProblemLogVO> queryCheckTrack(String powerQualityProblemNo) {

        //部门处理：根据部门code取名称
        List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
        Map<String, String> pvTerminalTreeVOMap = dept.stream().
                collect(Collectors.
                        toMap(PvTerminalTreeVO::getId,
                                PvTerminalTreeVO::getName));
        List<RStatElectricQualityProblemLogVO> rStatElectricQualityProblemLogVOList = rStatElectricQualityProblemLogMapper.selectByProblemNo(powerQualityProblemNo);

        rStatElectricQualityProblemLogVOList.stream ().forEach (temp->temp.setOrgName (pvTerminalTreeVOMap.get (temp.getOrgName ())));

        return rStatElectricQualityProblemLogVOList;
    }

}
