package digital.laboratory.platform.imr.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.imr.dto.QueryApplyDTO;
import digital.laboratory.platform.imr.dto.ReviewApprovalDTO;
import digital.laboratory.platform.imr.dto.ReviewSampleDetail;
import digital.laboratory.platform.imr.entity.SampleApply;
import digital.laboratory.platform.imr.entity.SampleApplyDetailed;
import digital.laboratory.platform.imr.entity.SampleStorage;
import digital.laboratory.platform.imr.enums.ApplyStatus;
import digital.laboratory.platform.imr.feign.TransferFeignService;
import digital.laboratory.platform.imr.mapper.SampleApplyDetailedMapper;
import digital.laboratory.platform.imr.mapper.SampleStorageMapper;
import digital.laboratory.platform.imr.service.ReviewApprovalService;
import digital.laboratory.platform.imr.service.SampleApplyService;
import digital.laboratory.platform.imr.vo.SampleApplyVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

@Service
@RequiredArgsConstructor
public class ReviewApprovalServiceImpl implements ReviewApprovalService {



    private final SampleApplyService sampleApplyService;

    private final SampleApplyDetailedMapper detailedMapper;


    private final SampleApplyService sampleApprovalService;


    private final TransferFeignService transferFeignService;


    private final SampleStorageMapper sampleStorageMapper;


    /**
     * 一级审核员审核
     *
     * @param dto
     * @param sampleApply
     * @param dlpUser
     * @return
     */
    @Override
    @Transactional
    public SampleApplyVO firstAudit(ReviewApprovalDTO dto, SampleApply sampleApply, DLPUser dlpUser) {

        //查找对应的申请
//        SampleApply sampleApply = sampleApplyMapper.selectById(dto.getApplyId());
//        if(sampleApply == null){
//            throw new RuntimeException("当前数据不存在");
//        } else if (sampleApply.getApplyType()==1) {//外带申请
//            if(sampleApply.getApplicationStatus()!=ApplyStatus.FIRST_LEVEL){
//                throw new RuntimeException("当前数据不是待一级审核状态");
//            }
//        }
        //判断无误
        sampleApply.setFirstAuditDate(LocalDateTime.now());//时间
        sampleApply.setFirstAuditOpinion(dto.getOpinion());//意见
        sampleApply.setFirstAuditorId(dlpUser.getId());//一级审核员

        QueryWrapper<SampleApplyDetailed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", dto.getApplyId());
        List<SampleApplyDetailed> applyDetailed = detailedMapper.selectList(queryWrapper);
        ArrayList<String> idList = new ArrayList<>();
        List<ReviewSampleDetail> sampleDetails = dto.getReviewSampleDetails();

        if (dto.getStatus() == -1) {//点击不通过按钮;勾选的数据为不通过

            //循环有的
            for (ReviewSampleDetail detail : sampleDetails) {
                //传值为不通过样本
                SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                sampleApplyDetailed.setStatus(-1);
                detailedMapper.updateById(sampleApplyDetailed);
                idList.add(detail.getId());
            }
            //循环没有的
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if (!detaileds.isEmpty()) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                }
                sampleApply.setApplicationStatus(ApplyStatus.SECOND_LEVEL);
            } else {
                sampleApply.setApplicationStatus(ApplyStatus.FIRST_LEVEL_FAIL);
                for (ReviewSampleDetail detail : sampleDetails) {
                    //申请不通过的要恢复状态
                    SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                    if (sampleApply.getApplyType() == 2) {
                        transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 2);
                    } else {
                        transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 1);
                    }
                }
            }
        } else {
            //循环有的
            for (ReviewSampleDetail detail : sampleDetails) {
                //传值为通过样本
                SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                sampleApplyDetailed.setStatus(1);
                detailedMapper.updateById(sampleApplyDetailed);
                idList.add(detail.getId());
            }
            //循环没有的
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if (!detaileds.isEmpty()) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(-1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                }
            }
            sampleApply.setApplicationStatus(ApplyStatus.SECOND_LEVEL);
        }

        /*QueryWrapper<SampleApplyDetailed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id",dto.getApplyId());
        List<SampleApplyDetailed> applyDetailed = detailedMapper.selectList(queryWrapper);


        if(dto.getReviewSampleDetails().isEmpty()){
            //如果传值为空说明全部不通过
            sampleApply.setApplicationStatus(ApplyStatus.FIRST_LEVEL_FAIL);
            for (SampleApplyDetailed detailed:applyDetailed) {
                detailed.setStatus(-1);//不通过
                detailedMapper.updateById(detailed);
            }
        }else {
            //传值对应的样本状态为通过;没有的则为不通过
            sampleApply.setApplicationStatus(ApplyStatus.SECOND_LEVEL);
            ArrayList<String> idList = new ArrayList<>();

            for (ReviewSampleDetail reviewSampleDetail : dto.getReviewSampleDetails()) {
                SampleApplyDetailed detailed = detailedMapper.selectById(reviewSampleDetail.getId());
                detailed.setStatus(1);//通过
                detailedMapper.updateById(detailed);
                idList.add(reviewSampleDetail.getId());
            }
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if(detaileds!=null) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(-1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                }
            }
        }*/
        sampleApplyService.updateById(sampleApply);

        return sampleApprovalService.getDetail(dto.getApplyId());
    }

    /**
     * 二级审核
     *
     * @param dto
     * @param sampleApply
     * @param dlpUser
     * @returnge
     */
    @Override
    public SampleApplyVO secondaryAudit(ReviewApprovalDTO dto, SampleApply sampleApply, DLPUser dlpUser) {
        //查找对应的申请
//        SampleApply sampleApply = sampleApplyMapper.selectById(dto.getApplyId());
//        if(sampleApply == null){
//            throw new RuntimeException(String.format("当前数据不存在"));
//        } else if (sampleApply.getApplyType()==1) {//外带申请
//            if(sampleApply.getApplicationStatus()!=ApplyStatus.SECOND_LEVEL){
//                throw new RuntimeException(String.format("当前数据不是待二级审核状态"));
//            }
//        }
        //判断无误
        sampleApply.setSecondaryAuditDate(LocalDateTime.now());//时间
        sampleApply.setSecondaryAuditOpinion(dto.getOpinion());//意见
        sampleApply.setSecondaryAuditorId(dlpUser.getId());//二级级审核员


        QueryWrapper<SampleApplyDetailed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", dto.getApplyId());
        List<SampleApplyDetailed> applyDetailed = detailedMapper.selectList(queryWrapper);
        ArrayList<String> idList = new ArrayList<>();
        List<ReviewSampleDetail> sampleDetails = dto.getReviewSampleDetails();

        if (dto.getStatus() == -1) {//点击不通过按钮;勾选的数据为不通过

            //循环有的
            for (ReviewSampleDetail detail : sampleDetails) {
                //传值为不通过样本
                SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                sampleApplyDetailed.setStatus(-1);
                detailedMapper.updateById(sampleApplyDetailed);
                idList.add(detail.getId());
            }
            //循环没有的
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if (!detaileds.isEmpty()) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                }
                sampleApply.setApplicationStatus(ApplyStatus.PENDING_APPROVAL);
            } else {
                sampleApply.setApplicationStatus(ApplyStatus.SECOND_LEVEL_FAIL);
                for (ReviewSampleDetail detail : sampleDetails) {
                    //申请不通过的要恢复状态
                    SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                    if (sampleApply.getApplyType() == 2) {
                        transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 2);
                    } else {
                        transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 1);
                    }
                }

            }
        } else {
            //循环有的
            for (ReviewSampleDetail detail : sampleDetails) {
                //传值为通过样本
                SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                sampleApplyDetailed.setStatus(1);
                detailedMapper.updateById(sampleApplyDetailed);
                idList.add(detail.getId());
            }
            //循环没有的
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if (detaileds != null) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(-1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                }
            }
            sampleApply.setApplicationStatus(ApplyStatus.PENDING_APPROVAL);
        }
        sampleApplyService.updateById(sampleApply);
        return sampleApprovalService.getDetail(dto.getApplyId());
    }


    /**
     * 审批样本申请
     *
     * @param dto         审批信息DTO
     * @param sampleApply 样本申请信息
     * @param dlpUser     审批人用户信息
     * @return 审批后的样本申请视图对象
     * @throws RuntimeException 如果数据不存在或不是待审批状态，则抛出异常
     */
    @Override
    @Transactional
    public SampleApplyVO approval(ReviewApprovalDTO dto, SampleApply sampleApply, DLPUser dlpUser) {
        //查找对应的申请
//        SampleApply sampleApply = sampleApplyMapper.selectById(dto.getApplyId());
//        if(sampleApply == null){
//            throw new RuntimeException(String.format("当前数据不存在"));
//        }else if(sampleApply.getApplicationStatus()!=ApplyStatus.PENDING_APPROVAL){
//            throw new RuntimeException(String.format("当前数据不是待审批状态"));
//        }
        //判断无误
        sampleApply.setApprovalDate(LocalDateTime.now());//时间
        sampleApply.setApproverOpinion(dto.getOpinion());//意见
        sampleApply.setApproverId(dlpUser.getId());//审批人


        QueryWrapper<SampleApplyDetailed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", dto.getApplyId());
        List<SampleApplyDetailed> applyDetailed = detailedMapper.selectList(queryWrapper);
        ArrayList<String> idList = new ArrayList<>();
        List<ReviewSampleDetail> sampleDetails = dto.getReviewSampleDetails();

        if (dto.getStatus() == -1) {//点击不通过按钮;勾选的数据为不通过

            //循环有的
            for (ReviewSampleDetail detail : sampleDetails) {
                //传值为不通过样本
                SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                sampleApplyDetailed.setStatus(-1);
                if (sampleApply.getApplyType() == 2) {
                    transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 2);
                } else {
                    transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 1);
                }
                detailedMapper.updateById(sampleApplyDetailed);
                idList.add(detail.getId());
            }
            //循环没有的
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if (!detaileds.isEmpty()) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                    if (sampleApply.getApplyType() == 2) {//如果是销毁申请需要改变预警状态
                        UpdateWrapper<SampleStorage> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.eq("sample_id", detail.getSampleId());
                        updateWrapper.set("early_warning", 2);//销毁预警状态修改为2--通过审核审批
                        sampleStorageMapper.update(null, updateWrapper);
                        transferFeignService.updateStatus(detail.getSampleId(), 7);//样本状态为待销毁
                    } else {
                        //外带申请需要恢复状态
                        transferFeignService.updateStatus(detail.getSampleId(), 1);
                    }
                }
                sampleApply.setApplicationStatus(ApplyStatus.APPROVED);
            } else {
                sampleApply.setApplicationStatus(ApplyStatus.APPROVAL_FAILED);
            }
        } else {//点击通过按钮
            //循环有的
            for (ReviewSampleDetail detail : sampleDetails) {
                //传值为通过样本
                SampleApplyDetailed sampleApplyDetailed = detailedMapper.selectById(detail.getId());
                sampleApplyDetailed.setStatus(1);
                detailedMapper.updateById(sampleApplyDetailed);
                idList.add(detail.getId());

                if (sampleApply.getApplyType() == 2) {//如果是销毁申请需要改变预警状态
                    UpdateWrapper<SampleStorage> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("sample_id", sampleApplyDetailed.getSampleId());
                    updateWrapper.set("early_warning", 2);//销毁预警状态修改为2--通过审核审批
                    sampleStorageMapper.update(null, updateWrapper);
                    transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 7);//样本状态为待销毁
                } else {
                    //外带申请需要恢复状态
                    transferFeignService.updateStatus(sampleApplyDetailed.getSampleId(), 1);
                }
            }
            //循环没有的
            QueryWrapper<SampleApplyDetailed> not = queryWrapper.notIn("id", idList);
            List<SampleApplyDetailed> detaileds = detailedMapper.selectList(not);
            if (!detaileds.isEmpty()) {
                for (SampleApplyDetailed detail : detaileds) {
                    detail.setStatus(-1);//没有传值的为不通过
                    detailedMapper.updateById(detail);
                    if (sampleApply.getApplyType() == 2) {
                        transferFeignService.updateStatus(detail.getSampleId(), 2);
                    } else {
                        transferFeignService.updateStatus(detail.getSampleId(), 1);
                    }
                }
            }
            sampleApply.setApplicationStatus(ApplyStatus.APPROVED);
        }
        sampleApplyService.updateById(sampleApply);
        return sampleApprovalService.getDetail(dto.getApplyId());
    }

    /**
     * 获取审核分页列表
     *
     * 根据查询参数和当前用户的权限，返回对应的审核分页列表。
     *
     * @param dto     查询申请DTO对象，包含分页和查询条件参数
     * @param dlpUser 当前用户信息，用于判断权限
     * @return        审核分页列表对象，包含查询结果和分页信息
     */
    @Override
    public IPage<SampleApplyVO> auditPage(QueryApplyDTO dto, DLPUser dlpUser) {
        Page<SampleApply> page = new Page<>(dto.getCurrent(), dto.getSize());
        QueryWrapper<SampleApply> queryWrapper = new QueryWrapper<>();

        Set<String> permissions = dlpUser.getPermissions();//判断权限
        /** 20241219 因为当一个用户同时拥有三个权限时，查询条件会发生冲突
         *  目前想通过一个list 收集要查询的状态，最后in查询
         */
        List<Integer> statusList = new ArrayList<>();
        List<Integer> geStatusList = new ArrayList<>();
        List<Integer> leStatusList = new ArrayList<>();
        Boolean isApproved = false;
        //System.out.println(permissions);
        for (String permission : permissions) {
            switch (permission) {
                case "imr_sample_apply_first_audit":
                    handleFirstAudit(dto, statusList, geStatusList, leStatusList);
                    break;
                case "imr_sample_apply_secondary_audit":
                    handleSecondaryAudit(dto, statusList, geStatusList, leStatusList);
                    break;
                case "imr_sample_apply_approval":
                    handleApproval(dto, statusList, geStatusList, leStatusList);
                    isApproved = true;
                    break;
                default:
                    // 其他权限的处理，如果有需要
                    break;
            }
        }
        if (dto.getStatus() != null) {
            switch (dto.getStatus()) {
                case 0:
                    queryWrapper.le("application_status", Collections.min(leStatusList))
                            .or()
                            .ge("application_status", Collections.max(geStatusList));
                    break;
                case 1:
                    queryWrapper.ge("application_status", Collections.max(geStatusList));
                    break;
                case 2:
                    queryWrapper.le("application_status", Collections.min(leStatusList));
                    break;
            }

        }
        queryWrapper.in(CollUtil.isNotEmpty(statusList), "application_status", statusList)
                .eq(!isApproved, "apply_type", 1) // 没有审批权限则只查询外出申请的
                .between(dto.getBeginDate() != null && dto.getFinishDate() != null, "application_date", dto.getBeginDate(), dto.getFinishDate())
                .orderByDesc("application_date");
        IPage<SampleApplyVO> applyVOPage = sampleApplyService.getApplyPage(
                page,
                queryWrapper
        );
        return applyVOPage;
    }

    /**
     * 处理审批状态的逻辑
     *
     * @param dto          查询申请DTO对象，包含状态查询参数
     * @param statusList   待审批状态的列表，用于构造查询条件
     * @param geStatus     大于等于状态的列表，用于构造查询条件
     * @param leStatus     小于等于状态的列表，用于构造查询条件
     */
    private void handleApproval(QueryApplyDTO dto, List<Integer> statusList, List<Integer> geStatus, List<Integer> leStatus) {
        if(dto.getStatus()==null){
            statusList.add(ApplyStatus.PENDING_APPROVAL.getStatus());
        }else {
            if(dto.getStatus()==0){
                leStatus.add(ApplyStatus.APPROVAL_FAILED.getStatus());
                geStatus.add(ApplyStatus.APPROVED.getStatus());
            }else {
                //通过status==1/不通过status==-1
                if(dto.getStatus()==1){
                    geStatus.add(ApplyStatus.APPROVED.getStatus());
                }
                if(dto.getStatus()==-1){
                    leStatus.add(ApplyStatus.APPROVAL_FAILED.getStatus());
                }
            }
        }
    }

    /**
     * 处理二级审核的逻辑
     *
     * @param dto         查询申请DTO对象，包含状态查询参数
     * @param statusList  待二级审核状态的列表，用于构造查询条件
     * @param geStatus    大于等于状态的列表，用于构造查询条件
     * @param leStatus    小于等于状态的列表，用于构造查询条件
     *
     * 此方法用于处理二级审核员的查询逻辑。如果dto中的状态为null，则表示查询所有待二级审核的申请。
     * 如果dto中的状态为0，则表示查询所有二级审核状态的申请，包括通过和未通过的情况。
     * 如果dto中的状态为1，则表示查询所有已通过二级审核的申请。
     * 如果dto中的状态为-1，则表示查询所有未通过二级审核的申请。
     * 注意：二级审核员不应处理销毁申请。
     */
    private void handleSecondaryAudit(QueryApplyDTO dto, List<Integer> statusList, List<Integer> geStatus, List<Integer> leStatus) {
        //二级审核员(不应该有销毁申请)
        if(dto.getStatus()==null){
            statusList.add(ApplyStatus.SECOND_LEVEL.getStatus());
        }else {
            if(dto.getStatus()==0){
                //返回全部
                leStatus.add(ApplyStatus.SECOND_LEVEL_FAIL.getStatus());
                geStatus.add(ApplyStatus.PENDING_APPROVAL.getStatus());
            }else {
                //通过status==1/不通过status==-1
                if(dto.getStatus()==1){
                    geStatus.add(ApplyStatus.PENDING_APPROVAL.getStatus());
                }
                if(dto.getStatus()==-1){
                    leStatus.add(ApplyStatus.SECOND_LEVEL_FAIL.getStatus());
                }
            }
        }
    }

    /**
     * 处理一级审核的逻辑
     *
     * @param dto         查询申请DTO对象，包含状态查询参数
     * @param statusList  待一级审核状态的列表，用于构造查询条件
     * @param geStatus    大于等于状态的列表，用于构造查询条件
     * @param leStatus    小于等于状态的列表，用于构造查询条件
     *
     * 如果dto中的状态为null，则表示查询所有待一级审核的申请（不包含销毁申请）。
     * 如果dto中的状态不为null，则表示查询特定状态的申请：
     * - 如果状态为0，表示查询所有一级审核状态的申请，包括通过和未通过的情况。
     * - 如果状态为1，表示查询所有已通过一级审核的申请。
     * - 如果状态为-1，表示查询所有未通过一级审核的申请。
     */
    private void handleFirstAudit(QueryApplyDTO dto, List<Integer> statusList, List<Integer> geStatus, List<Integer> leStatus) {
        if(dto.getStatus() == null){//审核初页面(不应该有销毁申请)
            statusList.add(ApplyStatus.FIRST_LEVEL.getStatus());
        }else {//点击通过页面时
            if(dto.getStatus()==0){
                //返回全部
                leStatus.add(ApplyStatus.FIRST_LEVEL_FAIL.getStatus());
                geStatus.add(ApplyStatus.SECOND_LEVEL.getStatus());
            } else {
                //通过status==1/不通过status==-1
                if(dto.getStatus()==1){
                    geStatus.add(ApplyStatus.SECOND_LEVEL.getStatus());
                }
                if(dto.getStatus()==-1){
                    leStatus.add(ApplyStatus.FIRST_LEVEL_FAIL.getStatus());
                }
            }
        }
    }

}
