package com.njcn.process.service.impl;

import cn.hutool.core.collection.CollUtil;
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.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
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.minioss.bo.MinIoUploadResDTO;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.enums.OssResponseEnum;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.process.enums.AuditProcessEnum;
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.RGeneralSurveyPlanDetailService;
import com.njcn.process.service.RGeneralSurveyPlanPOService;
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.user.api.DeptFeignClient;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.user.pojo.po.Dept;
import com.njcn.user.pojo.po.User;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.user.pojo.vo.UserVO;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * Description:
 * 接口文档访问地址：http://serverIP:port/swagger-ui.html
 * Date: 2022/11/11  11:24【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurveyPlanPOMapper, RGeneralSurveyPlanPO> implements RGeneralSurveyPlanPOService {

    private final RGeneralSurveyPlanDetailService rGeneralSurveyPlanDetailService;
    private final RGeneralSurveyPlanPOMapper rGeneralSurveyPlanPOMapper;
    private final RGeneralSurveyPlanDetailMapper rGeneralSurveyPlanDetailMapper;
    private final DeptFeignClient deptFeignClient;
    private final FileStorageUtil fileStorageUtil;
    private final CommTerminalGeneralClient commTerminalGeneralClient;
    private final RSurveyCycleMapper rSurveyCycleMapper;
    private final RSurveyPlanConfigService rSurveyPlanConfigService;

    private final IFlowDefinitionService iFlowDefinitionService;

    private final IFlowInstanceService iFlowInstanceService;

    private final IFlowTaskService iFlowTaskService;

    private final UserFeignClient userFeignClient;

    private final FlowableAssMapper flowableAssMapper;

    private final FlowFormAssMapper flowFormAssMapper;

    private final DicDataFeignClient dicDataFeignClient;


    /**
     * @param rGeneralSurveyPlanAddParm
     * @Description: addPlan
     * @Param: [rGeneralSurveyPlanAddParm]
     * @return: java.lang.Boolean
     * @Author: clam
     * @Date: 2022/11/14
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addPlan(RGeneralSurveyPlanAddParm rGeneralSurveyPlanAddParm) {

        RGeneralSurveyPlanPO rGeneralSurveyPlanPO = new RGeneralSurveyPlanPO();
        BeanUtils.copyProperties(rGeneralSurveyPlanAddParm, rGeneralSurveyPlanPO);

        /**查出周期id**/

        QueryWrapper<RSurveyCyclePO> rSurveyCyclePOQueryWrapper = new QueryWrapper();
        rSurveyCyclePOQueryWrapper.le("start_year", rGeneralSurveyPlanPO.getPlanEndTime());
        rSurveyCyclePOQueryWrapper.ge("end_year", rGeneralSurveyPlanPO.getPlanEndTime());
        RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);

        rGeneralSurveyPlanPO.setCycleId(rSurveyCyclePO.getId());

        rGeneralSurveyPlanPO.setCreatePerson(RequestUtil.getUserIndex());


        RGeneralSurveyPlanPO generalSurveyPlanPO = this.getOne(new LambdaQueryWrapper<RGeneralSurveyPlanPO>()
                .eq(RGeneralSurveyPlanPO::getPlanNo, rGeneralSurveyPlanAddParm.getPlanNo()));

        rGeneralSurveyPlanPO.setStatus(AuditProcessEnum.New.getStatus());
        if (Objects.isNull(generalSurveyPlanPO)) {
            this.save(rGeneralSurveyPlanPO);
        } else {
            if (rGeneralSurveyPlanPO.getStatus() == AuditProcessEnum.New.getStatus() || rGeneralSurveyPlanPO.getStatus() == AuditProcessEnum.AuditRefuse.getStatus()) {
                this.updateByMultiId(rGeneralSurveyPlanPO);
            } else {
                throw new BusinessException("存在相同普测计划编号,请勿重复新建");
            }
        }

        QueryWrapper<RGeneralSurveyPlanDetail> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(RGeneralSurveyPlanDetail::getPlanNo, rGeneralSurveyPlanAddParm.getPlanNo());
        rGeneralSurveyPlanDetailService.remove(queryWrapper);
        List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetailList = new ArrayList<>();

        SubstationParam param = new SubstationParam();
        param.setPowerIds(rGeneralSurveyPlanAddParm.getSubIds());
        List<SubGetBase> stationList = commTerminalGeneralClient.tagOrIdGetSub(param).getData();
        for (SubGetBase stat : stationList) {
            RGeneralSurveyPlanDetail rGeneralSurveyPlanDetail = new RGeneralSurveyPlanDetail();
            rGeneralSurveyPlanDetail.setPlanNo(rGeneralSurveyPlanAddParm.getPlanNo());
            rGeneralSurveyPlanDetail.setOrgNo(stat.getOrgId());
            rGeneralSurveyPlanDetail.setOrgName(stat.getOrgName());
            rGeneralSurveyPlanDetail.setSubId(stat.getId());
            rGeneralSurveyPlanDetail.setSubName(stat.getName());
            /*目前时间与计划开始时间，结束时间一致*/
            rGeneralSurveyPlanDetail.setGeneralSurveyStartTime(rGeneralSurveyPlanAddParm.getPlanStartTime());
            rGeneralSurveyPlanDetail.setGeneralSurveyTime(rGeneralSurveyPlanAddParm.getPlanStartTime());
            rGeneralSurveyPlanDetail.setGeneralSurveyEndTime(rGeneralSurveyPlanAddParm.getPlanEndTime());
            rGeneralSurveyPlanDetail.setPlanNo(rGeneralSurveyPlanAddParm.getPlanNo());
            rGeneralSurveyPlanDetail.setGeneralSurveyLeader(rGeneralSurveyPlanAddParm.getLeader());
            rGeneralSurveyPlanDetail.setVoltageLevel(stat.getVoltageLevel());
            rGeneralSurveyPlanDetailList.add(rGeneralSurveyPlanDetail);
        }
        rGeneralSurveyPlanDetailService.saveOrUpdateBatchByMultiId(rGeneralSurveyPlanDetailList, 500);

        return true;
    }

    /**
     * @param rGeneralSurveyPlanQueryParm
     * @Description: query
     * @Param: [rGeneralSurveyPlanQueryParm]
     * @return: java.util.List<com.njcn.process.pojo.vo.RGeneralSurveyPlanVO>
     * @Author: clam
     * @Date: 2022/11/15
     */
    @Override
    public IPage<RGeneralSurveyPlanVO> query(RGeneralSurveyPlanQueryParm rGeneralSurveyPlanQueryParm, List<String> statusList, String type) {
        IPage<RGeneralSurveyPlanPO> page = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
        IPage<RGeneralSurveyPlanVO> returnpage = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());

        String loginUserDept = RequestUtil.getDeptIndex();
        String loginUsrId = RequestUtil.getUserIndex();
        List<String> childrenDeptIds = deptFeignClient.getDepSonIdtByDeptId(loginUserDept).getData();
        childrenDeptIds = childrenDeptIds.stream().filter(item -> !Objects.equals(item, loginUserDept)).distinct().collect(Collectors.toList());
        List<User> userList = userFeignClient.getUserInfoByDeptIds(childrenDeptIds).getData();
        User my = new User();
        my.setId(loginUsrId);
        my.setName(RequestUtil.getUserNickname());
        userList.add(my);
        List<String> userIds = userList.stream().map(User::getId).collect(Collectors.toList());

        LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new LambdaQueryWrapper<>();
        /*type=1：新建页面：查看自己负责的计划；type=2：审核页面：审核者==当前用户；结果页面：查看自己负责的计划*/
        if (type == "1" || type == "3") {
            queryWrapper.in(RGeneralSurveyPlanPO::getCreatePerson, userIds);
        }
        if (type == "2") {
            queryWrapper.eq(RGeneralSurveyPlanPO::getCheckPerson, loginUsrId);
        }
        if (!StringUtils.isEmpty(rGeneralSurveyPlanQueryParm.getOrgNo())) {
            List<String> data = deptFeignClient.getDepSonIdtByDeptId(rGeneralSurveyPlanQueryParm.getOrgNo()).getData();

            queryWrapper.in(RGeneralSurveyPlanPO::getOrgNo, data);
        }
        if (!StringUtils.isEmpty(rGeneralSurveyPlanQueryParm.getStatus())) {
            queryWrapper.eq(RGeneralSurveyPlanPO::getStatus, rGeneralSurveyPlanQueryParm.getStatus());
        }
        if (!StringUtils.isEmpty(rGeneralSurveyPlanQueryParm.getIsFileUpload())) {
            queryWrapper.eq(RGeneralSurveyPlanPO::getIsFileUpload, rGeneralSurveyPlanQueryParm.getIsFileUpload());
        }
        if (!Objects.isNull(rGeneralSurveyPlanQueryParm.getPlanStartTime())) {
            queryWrapper.ge(RGeneralSurveyPlanPO::getPlanStartTime, rGeneralSurveyPlanQueryParm.getPlanStartTime());
        }
        if (!Objects.isNull(rGeneralSurveyPlanQueryParm.getPlanEndTime())) {
            queryWrapper.le(RGeneralSurveyPlanPO::getPlanStartTime, rGeneralSurveyPlanQueryParm.getPlanEndTime());
        }
        queryWrapper.in(RGeneralSurveyPlanPO::getStatus, statusList);
        queryWrapper.orderByAsc(RGeneralSurveyPlanPO::getStatus).orderByDesc(RGeneralSurveyPlanPO::getPlanCreateTime);
        IPage<RGeneralSurveyPlanPO> rGeneralSurveyPlanPOIPage = rGeneralSurveyPlanPOMapper.selectPage(page, queryWrapper);
        List<RGeneralSurveyPlanPO> rGeneralSurveyPlanPOS = rGeneralSurveyPlanPOIPage.getRecords();
        if (CollectionUtils.isEmpty(rGeneralSurveyPlanPOS)) {
            return returnpage;
        }

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


        List<String> collect = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getPlanNo).collect(Collectors.toList());
        LambdaQueryWrapper<RGeneralSurveyPlanDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(RGeneralSurveyPlanDetail::getPlanNo, collect);
        List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(lambdaQueryWrapper);
        List<RGeneralSurveyPlanVO> rGeneralSurveyPlanVOList = new ArrayList<>();

        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        List<String> checkIds = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getCheckPerson).filter(Objects::nonNull).collect(Collectors.toList());
        List<User> checkUserList = userFeignClient.getUserByIdList(checkIds).getData();
        Map<String, User> checkMap = checkUserList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        rGeneralSurveyPlanPOS.forEach(temp -> {
            RGeneralSurveyPlanVO rGeneralSurveyPlanVO = new RGeneralSurveyPlanVO();
            BeanUtils.copyProperties(temp, rGeneralSurveyPlanVO);
            List<String> collect1 = rGeneralSurveyPlanDetails.stream().
                    filter(surveyPlanDetail -> Objects.equals(surveyPlanDetail.getPlanNo(), temp.getPlanNo())).
                    map(RGeneralSurveyPlanDetail::getSubId).collect(Collectors.toList());
            rGeneralSurveyPlanVO.setSubCount(collect1.size());
            rGeneralSurveyPlanVO.setSubIds(collect1);
            rGeneralSurveyPlanVO.setIsFileUpload(ObjectUtil.isNull(temp.getIsFileUpload()) ? 0 : temp.getIsFileUpload());

            rGeneralSurveyPlanVO.setOrgName(pvTerminalTreeVOMap.get(temp.getOrgNo())); //单位名称
            rGeneralSurveyPlanVO.setCreatePersonName(userMap.get(temp.getCreatePerson()).getName());

            if (StrUtil.isNotBlank(temp.getCheckPerson())) {
                rGeneralSurveyPlanVO.setCheckPerson(checkMap.get(temp.getCheckPerson()).getName());
            }

            rGeneralSurveyPlanVOList.add(rGeneralSurveyPlanVO);
        });
        returnpage.setRecords(rGeneralSurveyPlanVOList);
        returnpage.setTotal(rGeneralSurveyPlanPOIPage.getTotal());
        return returnpage;
    }

    @Override
    public RGeneralSurveyPlanVO queryPlanOne(String planId) {

        RGeneralSurveyPlanPO rGeneralSurveyPlanPO = this.getOne(new LambdaQueryWrapper<RGeneralSurveyPlanPO>().eq(RGeneralSurveyPlanPO::getPlanNo, planId));

        LambdaQueryWrapper<RGeneralSurveyPlanDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(RGeneralSurveyPlanDetail::getPlanNo, planId);
        List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(lambdaQueryWrapper);

        RGeneralSurveyPlanVO rGeneralSurveyPlanVO = new RGeneralSurveyPlanVO();
        BeanUtils.copyProperties(rGeneralSurveyPlanPO, rGeneralSurveyPlanVO);

        rGeneralSurveyPlanVO.setSubCount(rGeneralSurveyPlanDetails.size());
        rGeneralSurveyPlanVO.setSubIds(rGeneralSurveyPlanDetails.stream().map(RGeneralSurveyPlanDetail::getSubId).collect(Collectors.toList()));
        rGeneralSurveyPlanVO.setIsFileUpload(ObjectUtil.isNull(rGeneralSurveyPlanPO.getIsFileUpload()) ? 0 : rGeneralSurveyPlanPO.getIsFileUpload());


        Dept dept = deptFeignClient.getDeptById(rGeneralSurveyPlanPO.getOrgNo()).getData();
        UserVO user = userFeignClient.getUserById(rGeneralSurveyPlanPO.getCreatePerson()).getData();

        rGeneralSurveyPlanVO.setOrgName(dept.getName()); //单位名称
        rGeneralSurveyPlanVO.setCreatePersonName(user.getName());

        if (StrUtil.isNotBlank(rGeneralSurveyPlanPO.getCheckPerson())) {
            UserVO checkUser = userFeignClient.getUserById(rGeneralSurveyPlanPO.getCheckPerson()).getData();
            rGeneralSurveyPlanVO.setCheckPerson(checkUser.getName());
        }

        return rGeneralSurveyPlanVO;
    }

    /**
     * @param surveyResultUploadParam
     * @Description: surveyResultUpload
     * @Param: [surveyResultUploadParam]
     * @return: boolean
     * @Author: clam
     * @Date: 2022/11/18
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean surveyResultUpload(SurveyResultUploadParam surveyResultUploadParam) {
        boolean result = true;
        RGeneralSurveyPlanPO rGeneralSurveyPlanPO = new RGeneralSurveyPlanPO();
        rGeneralSurveyPlanPO.setPlanNo(surveyResultUploadParam.getPlanId());
        rGeneralSurveyPlanPO = this.selectByMultiId(rGeneralSurveyPlanPO);
        String filePath = rGeneralSurveyPlanPO.getFilePath();
        filePath = Optional.ofNullable(filePath).orElse("");
        Integer fileCount = rGeneralSurveyPlanPO.getFileCount();
        fileCount = Optional.ofNullable(fileCount).orElse(0);
        for (int i = 0; i < surveyResultUploadParam.getFile().length; i++) {
            String OriginalFilename = surveyResultUploadParam.getFile()[i].getOriginalFilename();
            String fileStoragePath = fileStorageUtil.uploadMultipart(surveyResultUploadParam.getFile()[i], OssPath.SURVEY_RESULT);
            /*filePath格式：minIo服务文件名+##+原始文件名+；*/
            filePath = filePath + fileStoragePath + "##" + OriginalFilename + ";";
            fileCount++;
        }

        rGeneralSurveyPlanPO.setFileCount(fileCount);
        rGeneralSurveyPlanPO.setFilePath(filePath);
        rGeneralSurveyPlanPO.setIsFileUpload(1);
        rGeneralSurveyPlanPO.setUploadTime(new Date());
        this.saveOrUpdateByMultiId(rGeneralSurveyPlanPO);

        return result;
    }

    /**
     * @param planNo
     * @Description: surveyResultDownload
     * @Param: [surveyResultUploadParam]
     * @return: java.util.List<java.lang.String>
     * @Author: clam
     * @Date: 2022/11/18
     */
    @Override
    public List<MinIoUploadResDTO> surveyResultDownload(String planNo) {
        RGeneralSurveyPlanPO rGeneralSurveyPlanPO = new RGeneralSurveyPlanPO();
        rGeneralSurveyPlanPO.setPlanNo(planNo);
        rGeneralSurveyPlanPO = this.selectByMultiId(rGeneralSurveyPlanPO);
        String filePath = rGeneralSurveyPlanPO.getFilePath();
        if (StringUtils.isEmpty(filePath)) {
            throw new BusinessException(OssResponseEnum.DOWNLOAD_FILE_ERROR);
        }
        String[] split = filePath.substring(0, filePath.length() - 1).split(";");
        List<MinIoUploadResDTO> collect = Stream.of(split).map(temp -> {
            String[] split1 = temp.split("##");
            String OriginalFilename = split1[1];
            String minoFileName = split1[0];
            MinIoUploadResDTO dto = new MinIoUploadResDTO(OriginalFilename, fileStorageUtil.getFileUrl(minoFileName));
            return dto;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * @Description: exportSurveyPlan
     * @Param: []
     * @return: java.util.List<com.njcn.process.pojo.vo.SurveyPlanExcel>
     * @Author: clam
     * @Date: 2022/11/21
     */
    @Override
    public List<SurveyPlanExcel> exportSurveyPlan(List<String> planIdList) {
        List<SurveyPlanExcel> surveyPlanExcels = new ArrayList<>();
        LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RGeneralSurveyPlanPO::getPlanNo, planIdList);
        List<RGeneralSurveyPlanPO> rGeneralSurveyPlanPOS = rGeneralSurveyPlanPOMapper.selectList(queryWrapper);
        LambdaQueryWrapper<RGeneralSurveyPlanDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(RGeneralSurveyPlanDetail::getPlanNo, planIdList);
        List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(lambdaQueryWrapper);

        //部门处理：根据部门code取名称
        List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
        Map<String, String> pvTerminalTreeVOMap = dept.stream().
                collect(Collectors.
                        toMap(PvTerminalTreeVO::getId,
                                PvTerminalTreeVO::getName));
        rGeneralSurveyPlanPOS.forEach(temp -> {
            SurveyPlanExcel surveyPlanExcel = new SurveyPlanExcel();
            BeanUtils.copyProperties(temp, surveyPlanExcel);

//            long Busbarcount = rGeneralSurveyPlanDetails.stream ( ).
//                    filter (surveyPlanDetail -> Objects.equals (surveyPlanDetail.getPlanNo ( ), temp.getPlanNo ( ))).
//                    map (RGeneralSurveyPlanDetail::getBusbarId).distinct ( ).count ( );

            long Subcount = rGeneralSurveyPlanDetails.stream().
                    filter(surveyPlanDetail -> Objects.equals(surveyPlanDetail.getPlanNo(), temp.getPlanNo())).
                    map(RGeneralSurveyPlanDetail::getSubId).distinct().count();
//            surveyPlanExcel.setBusCount (Busbarcount);
            surveyPlanExcel.setSubCount(Subcount);
            surveyPlanExcel.setOrgNo(pvTerminalTreeVOMap.get(surveyPlanExcel.getOrgNo()));
            surveyPlanExcel.setStatus(getPlanStatus(temp.getStatus()));
            surveyPlanExcels.add(surveyPlanExcel);
        });

        return surveyPlanExcels;
    }

    private String getPlanStatus(int status) {
        String result = "";
        switch (status) {
            case 0:
                result = "新建";
                break;
            case 1:
                result = "待审核";
                break;
            case 3:
                result = "审核未通过";
                break;
            case 4:
                result = "已发布";
                break;
            case 5:
                result = "已完成";
                break;
            default:
                result = "";
        }
        return result;
    }

    /**
     * @param questionQueryParm
     * @Description: querySurveyPlanOnQuestion
     * @Param: [questionQueryParm]
     * @return: java.util.List<com.njcn.process.pojo.vo.RGeneralSurveyPlanDetailOnQuestionVO>
     * @Author: clam
     * @Date: 2022/11/30
     */
    @Override
    public List<RGeneralSurveyPlanDetailOnQuestionVO> querySurveyPlanOnQuestion(SurveyPlanQuestionQueryParm questionQueryParm) {

        /*获取直接下属子单位*/
        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId (questionQueryParm.getOrgNo()).getData ( );
        if (CollUtil.isEmpty(deptDTOList)) {
            return Collections.emptyList();
        }
        List<String> deptIdList = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        List<RGeneralSurveyPlanDetailOnQuestionVO> rGeneralSurveyPlanDetailOnQuestionVOS = rGeneralSurveyPlanDetailMapper.querySurveyPlanOnQuestion(questionQueryParm, deptIdList);
        rGeneralSurveyPlanDetailOnQuestionVOS.forEach(temp->{
            temp.setVoltageLevelName(dicDataFeignClient.getDicDataById(temp.getVoltageLevel()).getData().getName());
        });
        return rGeneralSurveyPlanDetailOnQuestionVOS;
    }

    /**
     * @param questionQueryParm
     * @Description: 更具questionQueryParm查计划名称
     * @Param: [questionQueryParm]
     * @return: java.util.List<com.njcn.process.pojo.param.SurveyPlanQuestionQueryParm>
     * @Author: clam
     * @Date: 2022/12/1
     */
    @Override
    public List<RGeneralSurveyPlanPO> querySurveyPlanName(SurveyPlanQuestionQueryParm questionQueryParm) {

        List<String> data = deptFeignClient.getDepSonIdtByDeptId(questionQueryParm.getOrgNo()).getData();

        QueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("plan_name").
                in("org_no", data).
                eq("DATE_FORMAT(upload_time, '%Y-%m')", new SimpleDateFormat("yyyy-MM").
                        format(questionQueryParm.getPlanStartTime()));
        List<RGeneralSurveyPlanPO> list = this.list(queryWrapper);

        return list;
    }

    /**
     * @param rGeneralSurveyPlanChcekParm
     * @Description: checkPlanAudit
     * @Param: [rGeneralSurveyPlanChcekParm]
     * @return: java.lang.Boolean
     * @Author: clam
     * @Date: 2023/2/22
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean checkPlanAudit(RGeneralSurveyPlanChcekParm rGeneralSurveyPlanChcekParm) {

        RGeneralSurveyPlanPO rGeneralSurveyPlanPO = this.lambdaQuery().eq(RGeneralSurveyPlanPO::getPlanNo, rGeneralSurveyPlanChcekParm.getPlanNo()).one();
        if (rGeneralSurveyPlanPO.getStatus() != AuditProcessEnum.WaitAudit.getStatus()) {
            throw new BusinessException("当前流程非待审核状态");
        }
        boolean result = true;
        UpdateWrapper<RGeneralSurveyPlanPO> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("plan_no", rGeneralSurveyPlanChcekParm.getPlanNo());
        updateWrapper.set("check_comment", rGeneralSurveyPlanChcekParm.getCheckComment());
//        updateWrapper.set ("check_person", rGeneralSurveyPlanChcekParm.getCheckPerson ( ));
        updateWrapper.set("status", Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? AuditProcessEnum.Release.getStatus() : AuditProcessEnum.AuditRefuse.getStatus());
        result = this.update(updateWrapper);

        //处理流程
        FlowableAss flowableAss = flowableAssMapper.selectOne(new LambdaQueryWrapper<FlowableAss>().eq(FlowableAss::getThsIndex, rGeneralSurveyPlanChcekParm.getPlanNo()));
        if(Objects.isNull(flowableAss)){
            throw new BusinessException("当前功能未绑定流程,请联系管理员处理");
        }
        String auditResult = Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? "同意" : "拒绝";

        Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
        FlowTaskVo flowTaskVo = new FlowTaskVo();
        flowTaskVo.setTaskId(task.getId());
        flowTaskVo.setComment(RequestUtil.getUserNickname() + auditResult + " 编号为" + rGeneralSurveyPlanChcekParm.getPlanNo() + "的计划,理由：" + rGeneralSurveyPlanChcekParm.getCheckComment());
        if (Objects.equals("0", rGeneralSurveyPlanChcekParm.getCheckResult())) {
            //拒绝,则回退到申请步骤
            iFlowTaskService.taskReject(flowTaskVo);
        } else {
            //同意
            flowTaskVo.setInstanceId(flowableAss.getExecIndex());
            Map<String, Object> map = new HashMap<>();
            map.put("auditFlag", 1);
            flowTaskVo.setVariables(map);
            iFlowTaskService.complete(flowTaskVo);
        }
        return result;
    }


    @Override
    public RGeneralSurveyPlanAddParm querySubStatation(Integer statetionNum) {
        /*查询所有电站并过滤已经参加当期普测电站*/
        List<SubGetBase> list = commTerminalGeneralClient.tagOrIdGetSub(new SubstationParam()).getData();


        /**查出当前周期id**/
        QueryWrapper<RSurveyCyclePO> rSurveyCyclePOQueryWrapper = new QueryWrapper();
        rSurveyCyclePOQueryWrapper.le("start_year", LocalDate.now());
        rSurveyCyclePOQueryWrapper.ge("end_year", LocalDate.now());
        RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);


        LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RGeneralSurveyPlanPO::getCycleId, rSurveyCyclePO.getId());
        List<RGeneralSurveyPlanPO> rGeneralSurveyPlanPOS = rGeneralSurveyPlanPOMapper.selectList(queryWrapper);
        List<String> planIds = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getPlanNo).collect(Collectors.toList());
        List<String> subIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(planIds)) {
            QueryWrapper<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetailQueryWrapper = new QueryWrapper();
            rGeneralSurveyPlanDetailQueryWrapper.in("plan_no", planIds);
            List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(rGeneralSurveyPlanDetailQueryWrapper);
            subIds = rGeneralSurveyPlanDetails.stream().map(RGeneralSurveyPlanDetail::getSubId).collect(Collectors.toList());
        }


        List<String> finalSubIds = subIds;
        List<SubGetBase> filterList = list.stream().filter(temp -> !finalSubIds.contains(temp.getId())).collect(Collectors.toList());
        List<SubGetBase> addList = new ArrayList<>();

        List<RSurveyPlanConfigPO> rSurveyPlanConfigPOList = rSurveyPlanConfigService.list();
        Map<String, RSurveyPlanConfigPO> orgIdMap = rSurveyPlanConfigPOList.stream().
                collect(Collectors.toMap(RSurveyPlanConfigPO::getOrgId, temp -> temp));
        List<PvTerminalTreeVO> data = deptFeignClient.allDeptList().getData();
        data.stream().forEach(temp -> {
            DeptSubstationVO deptSubstationVO = new DeptSubstationVO();
            BeanUtils.copyProperties(temp, deptSubstationVO);
            /*如果存在电站占比配置随机抽出配置电站个数*/
            if (orgIdMap.containsKey(temp.getId())) {
                List<SubGetBase> collect = filterList.stream().filter(statationStat -> Objects.
                        equals(statationStat.getOrgId(), temp.getId())).collect(Collectors.toList());
                RSurveyPlanConfigPO rSurveyPlanConfigPO = orgIdMap.get(temp.getId());
                //向上取整
                int v = (int) Math.ceil(rSurveyPlanConfigPO.getProportion() *
                        statetionNum);
                if (collect.size() >= v) {
                    Collections.shuffle(collect);
                    List<SubGetBase> lastList = collect.stream().limit(v).collect(Collectors.toList());
                    addList.addAll(lastList);
                } else {
                    addList.addAll(collect);
                }
            }

        });


        if (statetionNum > addList.size()) {
            /*取差集，当通过比例抽取变电站不够时 重差集里取*/
            List<SubGetBase> collect = filterList.stream().filter(o -> !addList.contains(o)).collect(Collectors.toList());
            int differenceCount = statetionNum - addList.size();
            Collections.shuffle(collect);
            List<SubGetBase> lastList = collect.stream().limit(differenceCount).collect(Collectors.toList());
            addList.addAll(lastList);
        }
        List<String> result = addList.stream().map(SubGetBase::getId).collect(Collectors.toList());
        RGeneralSurveyPlanAddParm rGeneralSurveyPlanAddParm = new RGeneralSurveyPlanAddParm();
        rGeneralSurveyPlanAddParm.setSubIds(result);
        return rGeneralSurveyPlanAddParm;
    }

    @Override
    public List<DeptSubstationVO> initDetpStataionTree(String orgdid) {

        /*查询所有电站并过滤已经参加当期普测电站*/

        /**查出当前周期id**/
        QueryWrapper<RSurveyCyclePO> rSurveyCyclePOQueryWrapper = new QueryWrapper();
        rSurveyCyclePOQueryWrapper.le("start_year", LocalDate.now());
        rSurveyCyclePOQueryWrapper.ge("end_year", LocalDate.now());
        RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);
        /**
         * 不存则新建周期
         */
        if (Objects.equals(rSurveyCyclePO, null)) {
            List<RSurveyCyclePO> rSurveyCyclePOS = rSurveyCycleMapper.selectList(null);
            int cycleNum = 0;
            if (CollectionUtils.isEmpty(rSurveyCyclePOS)) {

                cycleNum = 5;
            } else {
                rSurveyCyclePOS = rSurveyCyclePOS.stream()
                        .sorted(Comparator.comparing(RSurveyCyclePO::getEndYear).reversed())
                        .collect(Collectors.toList());

                cycleNum = rSurveyCyclePOS.get(0).getSurveyCycle();
            }
            LocalDate enddate = LocalDate.now().plusYears(cycleNum);
            rSurveyCyclePO = new RSurveyCyclePO();
            rSurveyCyclePO.setStartYear(LocalDate.now());
            rSurveyCyclePO.setEndYear(enddate);
            rSurveyCyclePO.setSurveyCycle(cycleNum);
            rSurveyCycleMapper.insert(rSurveyCyclePO);
        }

        LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RGeneralSurveyPlanPO::getCycleId, rSurveyCyclePO.getId());
        queryWrapper1.in(RGeneralSurveyPlanPO::getStatus, Stream.of(3, 4).collect(Collectors.toList()));
        List<RGeneralSurveyPlanPO> rGeneralSurveyPlanPOS = rGeneralSurveyPlanPOMapper.selectList(queryWrapper1);
        List<String> planIds = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getPlanNo).collect(Collectors.toList());
        List<String> subIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(planIds)) {
            QueryWrapper<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetailQueryWrapper = new QueryWrapper();
            rGeneralSurveyPlanDetailQueryWrapper.in("plan_no", planIds);
            List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(rGeneralSurveyPlanDetailQueryWrapper);
            subIds = rGeneralSurveyPlanDetails.stream().map(RGeneralSurveyPlanDetail::getSubId).collect(Collectors.toList());
        }


        List<String> finalSubIds = subIds;
        List<PvTerminalTreeVO> data = deptFeignClient.allDeptList().getData();
        List<DeptSubstationVO> deptSubstationVOList = data.stream().map(temp -> {
            DeptSubstationVO deptSubstationVO = new DeptSubstationVO();
            BeanUtils.copyProperties(temp, deptSubstationVO);
            deptSubstationVO.setDisabled(true);
            deptSubstationVO.setFlag(true);
            SubstationParam param = new SubstationParam();
            param.setOrgIds(Arrays.asList(temp.getCode()));
            List<SubGetBase> list1 = commTerminalGeneralClient.tagOrIdGetSub(param).getData();
            List<DeptSubstationVO> children = deptSubstationVO.getChildren();
            List<DeptSubstationVO> collect = list1.stream().map(statationStat -> {
                DeptSubstationVO deptSubstationVO1 = new DeptSubstationVO();
                deptSubstationVO1.setId(statationStat.getId());
                deptSubstationVO1.setPid(temp.getId());
                deptSubstationVO1.setName(statationStat.getName());
                if (finalSubIds.contains(statationStat.getId())) {
                    deptSubstationVO1.setDisabled(true);
                }
                deptSubstationVO1.setFlag(true);
                return deptSubstationVO1;
            }).collect(Collectors.toList());
            children.addAll(collect);

            return deptSubstationVO;
        }).collect(Collectors.toList());

        // 遍历两次data来组装带有children关联性的对象，如果找到子级就删除result的数据
        List<DeptSubstationVO> result = new ArrayList<>(deptSubstationVOList);
        for (DeptSubstationVO pv : deptSubstationVOList) {
            for (DeptSubstationVO pv2 : deptSubstationVOList) {

                /*如果本级id与数据的父id相同，就说明是子父级关系*/
                if (pv.getId().equals(pv2.getPid())) {
                    pv.getChildren().add(pv2);
                    result.remove(pv2);
                }
            }
        }

        result = recursion(result.get(0), orgdid);
        return result;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public RSurveyCycleVO addPlanCycle(Integer cycleNum) {

        /**查出当前周期id**/
        QueryWrapper<RSurveyCyclePO> rSurveyCyclePOQueryWrapper = new QueryWrapper();
        rSurveyCyclePOQueryWrapper.le("start_year", LocalDate.now());
        rSurveyCyclePOQueryWrapper.ge("end_year", LocalDate.now());
        RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);

        int insert = 0;
        Boolean flag = true;
        if (Objects.equals(rSurveyCyclePO, null)) {
            rSurveyCyclePO = new RSurveyCyclePO();
            LocalDate enddate = LocalDate.now().plusYears(cycleNum);
            rSurveyCyclePO.setStartYear(LocalDate.now());
            rSurveyCyclePO.setEndYear(enddate);
            rSurveyCyclePO.setSurveyCycle(cycleNum);
            insert = rSurveyCycleMapper.insert(rSurveyCyclePO);
        } else {
            flag = false;
        }
        RSurveyCycleVO rSurveyCycleVO = new RSurveyCycleVO();
        BeanUtils.copyProperties(rSurveyCyclePO, rSurveyCycleVO);
        rSurveyCycleVO.setFlag(flag);
        return rSurveyCycleVO;
    }

    @Override
    public Boolean submitAuditUser(RGeneralSurveyPlanAuditUserParam rGeneralSurveyPlanAuditUserParam) {
        String userId = RequestUtil.getUserIndex();
        List<String> planIds = rGeneralSurveyPlanAuditUserParam.getPlanIds();


        Integer count = this.lambdaQuery().in(RGeneralSurveyPlanPO::getPlanNo, planIds).eq(RGeneralSurveyPlanPO::getCreatePerson, userId).count();
        if (count != planIds.size()) {
            throw new BusinessException("只可以操作自己创建的计划!");
        }

        this.update(new LambdaUpdateWrapper<RGeneralSurveyPlanPO>()
                .in(RGeneralSurveyPlanPO::getPlanNo, planIds)
                .set(RGeneralSurveyPlanPO::getStatus, AuditProcessEnum.WaitAudit.getStatus()).set(RGeneralSurveyPlanPO::getCheckPerson, rGeneralSurveyPlanAuditUserParam.getAuditUser())
        );


        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deletePlan(List<String> planIds) {
        //判断是否满足删除条件
        long count = this.lambdaQuery().in(RGeneralSurveyPlanPO::getPlanNo, planIds).notIn(RGeneralSurveyPlanPO::getStatus, Stream.of(AuditProcessEnum.New.getStatus(), AuditProcessEnum.AuditRefuse.getStatus()).collect(Collectors.toList())).count();
        if (count > 0) {
            throw new BusinessException("无法删除新建和未通过状态之外的计划");
        }
        this.remove(new LambdaQueryWrapper<RGeneralSurveyPlanPO>().in(RGeneralSurveyPlanPO::getPlanNo, planIds));
        //删除相关的电站关联信息

        rGeneralSurveyPlanDetailMapper.delete(new LambdaQueryWrapper<RGeneralSurveyPlanDetail>().in(RGeneralSurveyPlanDetail::getPlanNo, planIds));

        //删除同时如果是驳回状态需要同时删除流程
        for (String plan : planIds) {
            FlowableAss flowableAss = flowableAssMapper.selectOne(new LambdaQueryWrapper<FlowableAss>().eq(FlowableAss::getThsIndex, plan));
            if (Objects.nonNull(flowableAss)) {
                iFlowInstanceService.delete(flowableAss.getExecIndex(), "测试删除");
                flowableAssMapper.deleteById(flowableAss.getThsIndex());
            }


        }
        return true;
    }


    public List<DeptSubstationVO> recursion(DeptSubstationVO result, String orgdid) {
        List<DeptSubstationVO> deptSubstationVOList = new ArrayList<>();
        if (Objects.equals(result.getId(), orgdid)) {
            deptSubstationVOList.add(result);
            return deptSubstationVOList;

        } else {
            for (DeptSubstationVO deptSubstationVO : result.getChildren()) {

                List<DeptSubstationVO> recursion = recursion(deptSubstationVO, orgdid);
                if (recursion.size() > 0) {
                    return recursion;
                }

            }
        }
        return deptSubstationVOList;
    }

}
