package com.diagbot.facade;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diagbot.dto.BehospitalAnalysisDTO;
import com.diagbot.dto.BehospitalCodeDetail;
import com.diagbot.dto.BehospitalCodeInfo;
import com.diagbot.dto.DeptBaseDTO;
import com.diagbot.dto.EntryDefectImprove;
import com.diagbot.dto.EntryDefectImproveInner;
import com.diagbot.dto.GetEntryDefectImproveDTO;
import com.diagbot.dto.GetEntryInfoDTO;
import com.diagbot.dto.GetQcClickDTO;
import com.diagbot.dto.GetQcClickInnerPageDTO;
import com.diagbot.dto.QcResultDetailInfo;
import com.diagbot.entity.BehospitalInfo;
import com.diagbot.entity.MedClickInfo;
import com.diagbot.entity.MedQcresultClick;
import com.diagbot.entity.QcresultDetail;
import com.diagbot.entity.QcresultInfo;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.service.MedQcresultClickService;
import com.diagbot.service.impl.MedClickInfoServiceImpl;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.DateUtil;
import com.diagbot.util.ExcelUtils;
import com.diagbot.util.ListUtil;
import com.diagbot.util.StringUtil;
import com.diagbot.util.SysUserUtils;
import com.diagbot.vo.BasDeptInfoVO;
import com.diagbot.vo.GetEntryDefectImproveInnerVO;
import com.diagbot.vo.GetEntryDefectImproveVO;
import com.diagbot.vo.GetQcClickInnerPageVO;
import com.diagbot.vo.GetQcClickVO;
import com.diagbot.vo.MedClickInfoVO;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @Description:数据分析
 * @Author: cy
 * @time: 2021/11/16 18:28
 */
@Component
public class DataAnalysisFacade {
    @Autowired
    @Qualifier("medClickInfoServiceImpl")
    private MedClickInfoServiceImpl medClickInfoService;

    @Autowired
    private QcresultInfoFacade qcresultInfoFacade;

    @Autowired
    private QcresultDetailFacade qcresultDetailFacade;

    @Autowired
    private MedQcresultClickService medQcresultClickService;

    @Autowired
    private BehospitalInfoFacade behospitalInfoFacade;

    /**
     * @Description:医生质控信息次数
     * @Param: [medClickInfoVO]
     * @return: void
     * @Author: cy
     * @Date: 2021/11/10
     */
    public Boolean addMedClickInfo(MedClickInfoVO medClickInfoVO) {
        BehospitalInfo behospitalInfo = behospitalInfoFacade.lambdaQuery()
                .eq(BehospitalInfo::getHospitalId, medClickInfoVO.getHospitalId())
                .eq(BehospitalInfo::getBehospitalCode, medClickInfoVO.getBehospitalCode())
                .ne(BehospitalInfo::getQcTypeId, "0")
                .eq(BehospitalInfo::getIsDeleted, IsDeleteEnum.N.getKey())
                .one();
        if(null == behospitalInfo){
            throw new CommonException(CommonErrorCode.FAIL, "该病历不符合要求");
        }

        MedClickInfo medClickInfo = new MedClickInfo();
        BeanUtil.copyProperties(medClickInfoVO, medClickInfo);
        QcresultInfo qcresultInfo = qcresultInfoFacade.lambdaQuery()
                .eq(QcresultInfo::getHospitalId, medClickInfoVO.getHospitalId())
                .eq(QcresultInfo::getBehospitalCode, medClickInfoVO.getBehospitalCode())
                .eq(QcresultInfo::getIsDeleted, IsDeleteEnum.N.getKey())
                .select(QcresultInfo::getId).one();
        if (null == qcresultInfo || null == qcresultInfo.getId()
        ) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "内部参数异常");
        }
        medClickInfo.setQcresultInfoId(qcresultInfo.getId());
        medClickInfo.setGmtCreate(new Date());
        medClickInfoService.save(medClickInfo);

        List<QcresultDetail> list = qcresultDetailFacade.lambdaQuery()
                .eq(QcresultDetail::getHospitalId, medClickInfoVO.getHospitalId())
                .eq(QcresultDetail::getBehospitalCode, medClickInfoVO.getBehospitalCode())
                .eq(QcresultDetail::getQcresultInfoId, qcresultInfo.getId())
                .eq(QcresultDetail::getIsDeleted, IsDeleteEnum.N.getKey()).list();
        if (ListUtil.isNotEmpty(list)) {
            StringBuilder sbFir = new StringBuilder();
            for (QcresultDetail qcresultDetail : list) {
                if (1 == qcresultDetail.getGradeType()) {
                    if (null != qcresultDetail.getCasesEntryId() && 0L != qcresultDetail.getCasesEntryId()) {
                        sbFir.append(qcresultDetail.getCasesEntryId() + "、");
                    }
                }
            }
            if (sbFir.length() > 0) {
                sbFir = sbFir.deleteCharAt(sbFir.length() - 1);
            }
            MedQcresultClick medQcresultClick = new MedQcresultClick();
            medQcresultClick.setHospitalId(medClickInfoVO.getHospitalId());
            medQcresultClick.setBehospitalCode(medClickInfoVO.getBehospitalCode());
            medQcresultClick.setDeptId(behospitalInfo.getBehDeptId());
            medQcresultClick.setDeptName(behospitalInfo.getBehDeptName());
            medQcresultClick.setQcresultInfoId(qcresultInfo.getId());
            medQcresultClick.setCasesEntryIds(sbFir.toString());
            medQcresultClick.setGmtCreate(new Date());
            medQcresultClickService.save(medQcresultClick);
        }
        return true;
    }

    public List<DeptBaseDTO> getQcClickDeptList(BasDeptInfoVO basDeptInfoVO) {
        long hospitalId = Long.parseLong(SysUserUtils.getCurrentHospitalID());
        List<DeptBaseDTO> deptDTO = new ArrayList<>();
        List<MedClickInfo> deptList = medClickInfoService.lambdaQuery()
                .eq(MedClickInfo::getHospitalId, hospitalId)
                .eq(MedClickInfo::getIsDeleted, IsDeleteEnum.N.getKey())
                .like(MedClickInfo::getDeptName, basDeptInfoVO.getInputStr())
                .select(MedClickInfo::getDeptId, MedClickInfo::getDeptName)
                .groupBy(MedClickInfo::getDeptId)
                .groupBy(MedClickInfo::getDeptName)
                .list();
        if (ListUtil.isNotEmpty(deptList)) {
            for (MedClickInfo kfc : deptList) {
                if (null == kfc) {
                    return deptDTO;
                }
                DeptBaseDTO deptBaseDTO = new DeptBaseDTO();
                deptBaseDTO.setDeptId(kfc.getDeptId());
                deptBaseDTO.setDeptName(kfc.getDeptName());
                deptDTO.add(deptBaseDTO);
            }
        }
        return deptDTO;
    }

    public List<GetQcClickDTO> getQcClick(GetQcClickVO getQcClickVO) {
        clickPageSet(getQcClickVO);
        List<GetQcClickDTO> records = medClickInfoService.getBaseMapper().getQcClick(getQcClickVO);
        //没有科室过滤时增加全院数据
        if (StringUtil.isBlank(getQcClickVO.getDeptName()) || getQcClickVO.getDeptName().equals("全院")) {
            GetQcClickDTO item = getGlobleTitle(records);
            if (item != null) {
                records.add(0, item);
            }
        }
        return records;
    }


    public void getQcClickByExport(HttpServletResponse response, GetQcClickVO getQcClickVO) {
        List<GetQcClickDTO> records = getQcClick(getQcClickVO);
        String fileName = "临床质控使用统计.xls";
        ExcelUtils.exportExcel(records, null, "sheet1", GetQcClickDTO.class, fileName, response, 12.8f);
    }

    public IPage<GetQcClickInnerPageDTO> getQcClickInnerPage(GetQcClickInnerPageVO getQcClickInnerPageVO) {
        clickInnerPageSet(getQcClickInnerPageVO);
        IPage<GetQcClickInnerPageDTO> records = medClickInfoService.getBaseMapper().getQcClickInnerPage(getQcClickInnerPageVO);
        return records;
    }

    public void getQcClickInnerPageByExport(HttpServletResponse response, GetQcClickInnerPageVO getQcClickInnerPageVO) {
        getQcClickInnerPageVO.setCurrent(1L);
        getQcClickInnerPageVO.setSize(Long.MAX_VALUE);
        getQcClickInnerPageVO.setSearchCount(false);
        IPage<GetQcClickInnerPageDTO> page = getQcClickInnerPage(getQcClickInnerPageVO);
        String fileName = "临床质控使用统计内页.xls";
        ExcelUtils.exportExcel(page.getRecords(), null, "sheet1", GetQcClickInnerPageDTO.class, fileName, response, 12.8f);
    }

    public IPage<GetEntryDefectImproveDTO> getEntryDefectImprove(GetEntryDefectImproveVO getEntryDefectImproveVO) {
        int current = (int) getEntryDefectImproveVO.getCurrent();
        int size = (int) getEntryDefectImproveVO.getSize();
        IPage<GetEntryDefectImproveDTO> page = new Page<>();
        entryDefectSet(getEntryDefectImproveVO);
        DecimalFormat df = new DecimalFormat("#.00");
        List<GetEntryDefectImproveDTO> getEntryDefectImproveDTO = new ArrayList<>();
        //获取标准缺陷信息
        List<GetEntryInfoDTO> entryInfo = medClickInfoService.getBaseMapper().getEntryInfo();
        //查询基础数据源
        List<EntryDefectImprove> records = medClickInfoService.getBaseMapper().getEntryDefectImprove(getEntryDefectImproveVO);
        //遍历科室
        for (EntryDefectImprove entryDefectImprove : records) {
            Map<String, Long> totalMap = new HashMap<>();
            Map<String, Long> improveleMap = new HashMap<>();
            List<BehospitalCodeInfo> behospitalCodeInfoList = entryDefectImprove.getBehospitalCodeInfos();
            //多份病历多次质控评分得到质控缺陷总量、待改善总量
            unitProcessing(behospitalCodeInfoList, totalMap, improveleMap);
            //按照全院维度进行数据封装
            for (Map.Entry<String, Long> stringLongEntry : totalMap.entrySet()) {
                //封装DTO
                GetEntryDefectImproveDTO getEntryDefectImprove = new GetEntryDefectImproveDTO();
                getEntryDefectImprove.setDeptId(entryDefectImprove.getDeptId());
                getEntryDefectImprove.setDeptName(entryDefectImprove.getDeptName());
                getEntryDefectImprove.setEntryId(stringLongEntry.getKey());
                getEntryInfo(entryInfo, stringLongEntry, getEntryDefectImprove);
                getEntryDefectImprove.setTotalNum(stringLongEntry.getValue());
                if (improveleMap.containsKey(stringLongEntry.getKey())) {
                    getEntryDefectImprove.setImproveleNum(improveleMap.get(stringLongEntry.getKey()));
                }
                getEntryDefectImprove.setHandleNum(getEntryDefectImprove.getTotalNum() - getEntryDefectImprove.getImproveleNum());
                double handleRatio = 0d;
                if(getEntryDefectImprove.getTotalNum()!=0 && getEntryDefectImprove.getHandleNum()!=0){
                    handleRatio = getEntryDefectImprove.getHandleNum().doubleValue()*100/getEntryDefectImprove.getTotalNum().doubleValue();
                    String handleStr = df.format(handleRatio)+"%";
                    getEntryDefectImprove.setHandleStr(handleStr);
                }
                getEntryDefectImproveDTO.add(getEntryDefectImprove);
            }
        }
        //(部分模糊查询在此)
            if (ListUtil.isNotEmpty(getEntryDefectImproveDTO)) {
                if (StringUtils.isNotBlank(getEntryDefectImproveVO.getCasesName()) || StringUtils.isNotBlank(getEntryDefectImproveVO.getEntryName())) {
                getEntryDefectImproveQuery(getEntryDefectImproveVO, getEntryDefectImproveDTO);
            }
        }


        //导出操作
        if (getEntryDefectImproveVO.getExportType() == 1L) {
            size = getEntryDefectImproveDTO.size();
        }
        page.setSize(size);
        page.setTotal(getEntryDefectImproveDTO.size());
        page.setCurrent(current);
        //排序操作
        if (ListUtil.isNotEmpty(getEntryDefectImproveDTO)) {
            getEntryDefectImproveDTO =  sortEntryDefectList( getEntryDefectImproveDTO ,getEntryDefectImproveVO);
        }
        //分页操作
        List<GetEntryDefectImproveDTO> getEntryDefectImproveDTOS = page(getEntryDefectImproveDTO, size, current);
        page.setRecords(getEntryDefectImproveDTOS);
        return page;
    }

    /**
     * @Description: 缺陷信息封装
     * @Param: [entryInfo, stringLongEntry, getEntryDefectImprove]
     * @return: com.diagbot.dto.GetEntryDefectImproveDTO
     * @Author: cy
     * @Date: 2021/12/3
     */
    public GetEntryDefectImproveDTO getEntryInfo(List<GetEntryInfoDTO> entryInfo, Map.Entry<String, Long> stringLongEntry,
                                                 GetEntryDefectImproveDTO getEntryDefectImprove) {
        entryInfo.parallelStream().filter(kfc -> kfc.getEntryId().equals(stringLongEntry.getKey())).forEach(
                obj -> {
                    getEntryDefectImprove.setCasesId(obj.getCasesId());
                    getEntryDefectImprove.setCasesName(obj.getCasesName());
                    getEntryDefectImprove.setEntryName(obj.getEntryName());
                }
        );
        return getEntryDefectImprove;
    }

    /**
     * @Description: 多份病历多次质控评分得到质控缺陷总量、待改善总量
     * @Param: [behospitalCodeInfoList, totalMap, improveleMap]
     * @return: void
     * @Author: cy
     * @Date: 2021/12/3
     */
    public static void unitProcessing(List<BehospitalCodeInfo> behospitalCodeInfoList, Map<String, Long> totalMap,
                                      Map<String, Long> improveleMap) {
        for (BehospitalCodeInfo behospitalCodeInfo : behospitalCodeInfoList) {
            //病历下
            List<QcResultDetailInfo> qcResultDetailInfos = behospitalCodeInfo.getQcResultDetailInfos();
                //获取多病历多质控质控缺陷总量
                totalMap = getEntryTotalMap(qcResultDetailInfos, totalMap);
                if (MapUtils.isNotEmpty(totalMap)) {
                    //获取多病历多质控质控缺陷待改善总量
                    QcResultDetailInfo qcResultDetailInfo = qcResultDetailInfos.get(qcResultDetailInfos.size() - 1);
                    improveleMap = getEntryImproveleMap(qcResultDetailInfo, improveleMap);
                }
        }
    }


    public void getEntryDefectImproveQuery(GetEntryDefectImproveVO getEntryDefectImproveVO, List<GetEntryDefectImproveDTO> getEntryDefectImproveDTO) {
        Iterator<GetEntryDefectImproveDTO> iterator = getEntryDefectImproveDTO.iterator();
        while (iterator.hasNext()) {
            boolean mark = true;
            GetEntryDefectImproveDTO kfc = iterator.next();
            if (StringUtils.isNotBlank(getEntryDefectImproveVO.getCasesName()) &&
                    !kfc.getCasesName().contains(getEntryDefectImproveVO.getCasesName())) {
                iterator.remove();
                mark = false;
            }
            if (mark && StringUtils.isNotBlank(getEntryDefectImproveVO.getEntryName()) &&
                    !kfc.getEntryName().contains(getEntryDefectImproveVO.getEntryName())) {
                iterator.remove();
            }
        }
    }

    /**
     * @Description:分页数据
     * @Param: [dataList, pageSize, currentPage]
     * @return: java.util.List<java.lang.String>
     * @Author: cy
     * @Date: 2021/12/2
     */
    public static <T> List<T> page(List<T> retRecords, int pageSize, int currentPage) {
        List<T> currentPageList = new ArrayList<>();
        if (retRecords != null && retRecords.size() > 0) {
            int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0);
            for (int i = 0; i < pageSize && i < retRecords.size() - currIdx; i++) {
                T data = retRecords.get(currIdx + i);
                currentPageList.add(data);
            }
        }
        return currentPageList;
    }

    public  List<BehospitalAnalysisDTO>  getEntryDefectImproveInnerDTOS( List<BehospitalAnalysisDTO> behospitalInfoDTOList ,GetEntryDefectImproveInnerVO
            getEntryDefectImproveInnerVO) {
        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getAsc())){
            if("behDeptName".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehDeptName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("behDoctorName".equals(getEntryDefectImproveInnerVO.getAsc()) || "doctorName".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getDoctorName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("name".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("fileCode".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getFileCode, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("behospitalCode".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalCode, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("age".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getAge, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("behospitalDate".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalDate, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
            }
            if("leaveHospitalDate".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLeaveHospitalDate, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
            }
            if("scoreRes".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getScoreRes, Comparator.nullsLast(Double::compareTo))).collect(Collectors.toList());
            }
            if("level".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLevel, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
            }
            if("gradeTime".equals(getEntryDefectImproveInnerVO.getAsc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getGradeTime, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
            }
        }

        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getDesc())){
            if("behDeptName".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehDeptName, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("behDoctorName".equals(getEntryDefectImproveInnerVO.getDesc()) || "doctorName".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getDoctorName, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("name".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getName, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("fileCode".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getFileCode, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("behospitalCode".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalCode, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("age".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getAge, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("behospitalDate".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getBehospitalDate, Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("leaveHospitalDate".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLeaveHospitalDate, Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("scoreRes".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getScoreRes, Comparator.nullsLast(Double::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("level".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getLevel, Comparator.nullsLast(String::compareTo)).reversed()).collect(Collectors.toList());
            }
            if("gradeTime".equals(getEntryDefectImproveInnerVO.getDesc())){
                behospitalInfoDTOList = behospitalInfoDTOList.stream().sorted(Comparator.comparing(BehospitalAnalysisDTO::getGradeTime, Comparator.nullsLast(Date::compareTo)).reversed()).collect(Collectors.toList());
            }
        }
        return behospitalInfoDTOList;
    }
    public  List<GetEntryDefectImproveDTO>  sortEntryDefectList( List<GetEntryDefectImproveDTO> getEntryDefectImproveDTOS ,GetEntryDefectImproveVO getEntryDefectImproveVO) {
        if(StringUtils.isNotBlank(getEntryDefectImproveVO.getAsc())){
            if("totalNum".equals(getEntryDefectImproveVO.getAsc())){
                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getTotalNum)).collect(Collectors.toList());

            }
            if("handleNum".equals(getEntryDefectImproveVO.getAsc())){
                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getHandleNum)).collect(Collectors.toList());

            }
            if("improveleNum".equals(getEntryDefectImproveVO.getAsc())){
                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getImproveleNum)).collect(Collectors.toList());
            }
        }

        if(StringUtils.isNotBlank(getEntryDefectImproveVO.getDesc())){
            if("totalNum".equals(getEntryDefectImproveVO.getDesc())){
                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getTotalNum).reversed()).collect(Collectors.toList());

            }
            if("handleNum".equals(getEntryDefectImproveVO.getDesc())){
                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getHandleNum).reversed()).collect(Collectors.toList());

            }
            if("improveleNum".equals(getEntryDefectImproveVO.getDesc())){
                getEntryDefectImproveDTOS = getEntryDefectImproveDTOS.stream().sorted(Comparator.comparing(GetEntryDefectImproveDTO::getImproveleNum).reversed()).collect(Collectors.toList());
            }
        }
        return getEntryDefectImproveDTOS;
    }

    public static Map getEntryTotalMap(List<QcResultDetailInfo> qcResultDetailInfos, Map<String, Long> totalMap) {
        Set<String> totalSet = new HashSet<String>();
        for (QcResultDetailInfo qcResultDetailInfo : qcResultDetailInfos) {
                //质控下获取科室下总缺陷
                String casesEntryIds = qcResultDetailInfo.getCasesEntryIds();
                totalSet = getSetEntry(casesEntryIds, totalSet);
        }
        if (null == totalSet && totalSet.size() == 0) {
            return totalMap;
        }
        totalMap = getSetEntryCount(totalMap, totalSet);
        return totalMap;
    }

    public static Map getEntryImproveleMap(QcResultDetailInfo qcResultDetailInfo, Map<String, Long> improveMap) {
        Set<String> improveleSet = new HashSet<String>();
        String casesEntryIds = qcResultDetailInfo.getCasesEntryIds();
        improveleSet = getSetEntry(casesEntryIds, improveleSet);
        improveMap = getSetEntryCount(improveMap, improveleSet);
        return improveMap;
    }

    public static Set getSetEntry(String casesEntryIds, Set set) {
        if (StringUtils.isNotBlank(casesEntryIds) && !"0".equals(casesEntryIds)) {
            if (casesEntryIds.contains("、")) {
                String[] split = casesEntryIds.split("、");
                for (String id : split) {
                    set.add(id);
                }
            } else {
                set.add(casesEntryIds);
            }
        }
        return set;
    }

    public static Map getSetEntryCount(Map<String, Long> map, Set<String> sets) {
        if (null != sets && sets.size() > 0) {
        for (String set : sets) {
            if (map.containsKey(set)) {
                long count = map.get(set) + 1l;
                map.put(set, count);
            } else {
                map.put(set, 1L);
                }
            }
        }
        return map;
    }

    public void getEntryDefectImproveByExport(HttpServletResponse response, GetEntryDefectImproveVO
            getEntryDefectImproveVO) {
        getEntryDefectImproveVO.setExportType(1L);
        getEntryDefectImproveVO.setCurrent(1L);
        getEntryDefectImproveVO.setSize(Long.MAX_VALUE);
        getEntryDefectImproveVO.setSearchCount(false);
        IPage<GetEntryDefectImproveDTO> page = getEntryDefectImprove(getEntryDefectImproveVO);
        String fileName = "条目缺陷改善统计.xls";
        ExcelUtils.exportExcel(page.getRecords(), null, "sheet1", GetEntryDefectImproveDTO.class, fileName, response, 12.8f);
    }


    public IPage<BehospitalAnalysisDTO> getEntryDefectImproveInner(GetEntryDefectImproveInnerVO
                                                                       getEntryDefectImproveInnerVO) {
        int current = (int) getEntryDefectImproveInnerVO.getCurrent();
        int size = (int) getEntryDefectImproveInnerVO.getSize();
        IPage<BehospitalAnalysisDTO> page = new Page<>();
        List<BehospitalAnalysisDTO> behospitalInfoDTOS = new ArrayList<>();
        entryDefectInnerSet(getEntryDefectImproveInnerVO);
        // List<GetEntryInfoDTO> entryInfo = medClickInfoService.getBaseMapper().getEntryInfo();
        List<EntryDefectImproveInner> records = medClickInfoService.getBaseMapper().getEntryDefectImproveInner(getEntryDefectImproveInnerVO);
        if (ListUtil.isNotEmpty(records) && records.size() == 1) {
            EntryDefectImproveInner entryDefectImproveInner = records.get(0);
            List<BehospitalCodeDetail> behospitalCodeDetails = entryDefectImproveInner.getBehospitalCodeInfos();
            for (BehospitalCodeDetail behospitalCodeDetail : behospitalCodeDetails) {
                List<QcResultDetailInfo> qcResultDetailInfos = behospitalCodeDetail.getQcResultDetailInfos();
                Set<String> totalSet = new HashSet<String>();
                Set<String> improveleSet = new HashSet<String>();
                for (QcResultDetailInfo qcResultDetailInfo : qcResultDetailInfos) {
                    String casesEntryIds = qcResultDetailInfo.getCasesEntryIds();
                    totalSet = getSetEntry(casesEntryIds, totalSet);
                }
                QcResultDetailInfo qcResultDetailInfo = qcResultDetailInfos.get(qcResultDetailInfos.size() - 1);
                if (null != qcResultDetailInfo && StringUtils.isNotBlank(qcResultDetailInfo.getCasesEntryIds())) {
                    improveleSet = getSetEntry(qcResultDetailInfo.getCasesEntryIds(), improveleSet);
                }
                if ("0".equals(getEntryDefectImproveInnerVO.getTypeMark()) && totalSet.contains(getEntryDefectImproveInnerVO.getEntryId())) {
                    behospitalInfoDTOS = getBehospitalInfoDTO(entryDefectImproveInner, behospitalCodeDetail, behospitalInfoDTOS);
                }
                if ("1".equals(getEntryDefectImproveInnerVO.getTypeMark()) && totalSet.contains(getEntryDefectImproveInnerVO.getEntryId())
                        && !improveleSet.contains(getEntryDefectImproveInnerVO.getEntryId())) {
                    behospitalInfoDTOS = getBehospitalInfoDTO(entryDefectImproveInner, behospitalCodeDetail, behospitalInfoDTOS);
                }
                if ("2".equals(getEntryDefectImproveInnerVO.getTypeMark()) && totalSet.contains(getEntryDefectImproveInnerVO.getEntryId())
                        && improveleSet.contains(getEntryDefectImproveInnerVO.getEntryId())) {
                    behospitalInfoDTOS = getBehospitalInfoDTO(entryDefectImproveInner, behospitalCodeDetail, behospitalInfoDTOS);
                }
            }
        }
        //导出操作
        if (getEntryDefectImproveInnerVO.getExportType() == 1L) {
            size = behospitalInfoDTOS.size();
        }
        page.setSize(size);
        page.setTotal(behospitalInfoDTOS.size());
        page.setCurrent(current);
        //排序操作
        if (ListUtil.isNotEmpty(behospitalInfoDTOS)) {
            behospitalInfoDTOS =  getEntryDefectImproveInnerDTOS( behospitalInfoDTOS ,getEntryDefectImproveInnerVO);
        }
        //分页操作
        List<BehospitalAnalysisDTO> behospitalInfoDTOList = page(behospitalInfoDTOS, size, current);
        page.setRecords(behospitalInfoDTOList);
        return page;
    }

    /**
     * @Description: 数据封装
     * @Param: [entryDefectImproveInner, behospitalCodeDetail, qcResultDetailInfo, behospitalInfoDTOS]
     * @return: java.util.List<com.diagbot.dto.BehospitalInfoDTO>
     * @Author: cy
     * @Date: 2021/12/3
     */
    public List<BehospitalAnalysisDTO> getBehospitalInfoDTO(EntryDefectImproveInner entryDefectImproveInner, BehospitalCodeDetail behospitalCodeDetail,
                                                        List<BehospitalAnalysisDTO> behospitalInfoDTOS) {
        BehospitalAnalysisDTO behospitalInfoDTO = new BehospitalAnalysisDTO();
        behospitalInfoDTO.setLevel(behospitalCodeDetail.getLevel());
        behospitalInfoDTO.setScoreRes(behospitalCodeDetail.getScoreRes());
        behospitalInfoDTO.setFileCode(behospitalCodeDetail.getFileCode());
        behospitalInfoDTO.setBehospitalCode(behospitalCodeDetail.getBehospitalCode());
        behospitalInfoDTO.setName(behospitalCodeDetail.getName());
        behospitalInfoDTO.setAge(behospitalCodeDetail.getAge());
        behospitalInfoDTO.setBehospitalDate(behospitalCodeDetail.getBehospitalDate());
        behospitalInfoDTO.setLeaveHospitalDate(behospitalCodeDetail.getLeaveHospitalDate());
        behospitalInfoDTO.setDoctorName(behospitalCodeDetail.getDoctorName());
        behospitalInfoDTO.setBehDoctorName(behospitalCodeDetail.getDoctorName());
        behospitalInfoDTO.setBehDeptName(entryDefectImproveInner.getBehDeptName());
        behospitalInfoDTO.setGradeTime(behospitalCodeDetail.getGradeTime());
        behospitalInfoDTO.setIsDaytime(behospitalCodeDetail.getIsDaytime());
        behospitalInfoDTOS.add(behospitalInfoDTO);
        return behospitalInfoDTOS;
    }

    public void getDefectImproveInnerByExport(HttpServletResponse response, GetEntryDefectImproveInnerVO
            getEntryDefectImproveInnerVO) {
        getEntryDefectImproveInnerVO.setExportType(1L);
        getEntryDefectImproveInnerVO.setCurrent(1L);
        getEntryDefectImproveInnerVO.setSize(Long.MAX_VALUE);
        getEntryDefectImproveInnerVO.setSearchCount(false);
        String fileName = "条目缺陷改善统计病历列表.xls";
        IPage<BehospitalAnalysisDTO> page = this.getEntryDefectImproveInner(getEntryDefectImproveInnerVO);
        ExcelUtils.exportExcelUser(page.getRecords(), null, "sheet1", BehospitalAnalysisDTO.class, fileName, response);
    }

    /**
     * 增加全院记录
     *
     * @param records
     * @return
     */
    public GetQcClickDTO getGlobleTitle(List<GetQcClickDTO> records) {
        GetQcClickDTO item = new GetQcClickDTO();
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        //缺陷总数
        Integer singleMode = records
                .stream()
                .map(GetQcClickDTO::getSingleModeNum)
                .reduce(0, Integer::sum);
        if (singleMode == null) {
            singleMode = 0;
        }
        Integer totalMode = records
                .stream()
                .map(GetQcClickDTO::getTotalModeNum)
                .reduce(0, Integer::sum);
        if (totalMode == null) {
            totalMode = 0;
        }
        item.setDeptName("全院");
        item.setSingleModeNum(singleMode);
        item.setTotalModeNum(totalMode);
        return item;
    }

    private void clickPageSet(GetQcClickVO getQcClickVO) {
        if(StringUtils.isNotBlank(getQcClickVO.getDeptName())){
            getQcClickVO.setDeptName(transferredMeaning(getQcClickVO.getDeptName()));
        }
        //入参验证
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = simpleDateFormat.parse(getQcClickVO.getStartDate());
            endDate = simpleDateFormat.parse(getQcClickVO.getEndDate());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (DateUtil.after(startDate, endDate)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间！");
        }
        getQcClickVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
    }

    private void clickInnerPageSet(GetQcClickInnerPageVO getQcClickInnerPageVO) {
        if(StringUtils.isNotBlank(getQcClickInnerPageVO.getDoctorId())){
            getQcClickInnerPageVO.setDoctorId(transferredMeaning(getQcClickInnerPageVO.getDoctorId()));
        }
        if(StringUtils.isNotBlank(getQcClickInnerPageVO.getDoctorName())){
            getQcClickInnerPageVO.setDoctorName(transferredMeaning(getQcClickInnerPageVO.getDoctorName()));
        }
        //入参验证
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = simpleDateFormat.parse(getQcClickInnerPageVO.getStartDate());
            endDate = simpleDateFormat.parse(getQcClickInnerPageVO.getEndDate());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (DateUtil.after(startDate, endDate)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间！");
        }
        getQcClickInnerPageVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
    }

   public String transferredMeaning(String tranStr){
          if( tranStr.contains("%")){
              tranStr = tranStr.replace("%", "\\%");
          }
           if( tranStr.contains("_")){
              tranStr = tranStr.replace("_","\\_");
           }
       return tranStr;
    };
    private void entryDefectSet(GetEntryDefectImproveVO getEntryDefectImproveVO) {
        if(StringUtils.isNotBlank(getEntryDefectImproveVO.getDeptName())){
            getEntryDefectImproveVO.setDeptName(transferredMeaning(getEntryDefectImproveVO.getDeptName()));
        }
        getEntryDefectImproveVO.setCurrent(1L);
        getEntryDefectImproveVO.setSize(Long.MAX_VALUE);
        //入参验证
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = simpleDateFormat.parse(getEntryDefectImproveVO.getStartDate());
            endDate = simpleDateFormat.parse(getEntryDefectImproveVO.getEndDate());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (DateUtil.after(startDate, endDate)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间！");
        }
        getEntryDefectImproveVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
    }

    private void entryDefectInnerSet(GetEntryDefectImproveInnerVO getEntryDefectImproveInnerVO) {
        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getPatName())){
            getEntryDefectImproveInnerVO.setPatName(transferredMeaning(getEntryDefectImproveInnerVO.getPatName()));
        }
        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getDoctorId())){
            getEntryDefectImproveInnerVO.setDoctorId(transferredMeaning(getEntryDefectImproveInnerVO.getDoctorId()));
        }
        if(StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getDoctorName())){
            getEntryDefectImproveInnerVO.setDoctorName(transferredMeaning(getEntryDefectImproveInnerVO.getDoctorName()));
        }
        getEntryDefectImproveInnerVO.setCurrent(1L);
        getEntryDefectImproveInnerVO.setSize(Long.MAX_VALUE);
        //入参验证
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getStartDate());
            endDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getEndDate());

        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (DateUtil.after(startDate, endDate)) {
            throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "开始时间必须小于结束时间！");
        }
        if (StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getChTimeStart())
                && StringUtils.isNotBlank(getEntryDefectImproveInnerVO.getChTimeEnd())
        ) {
            Date chTimeStartDate = null;
            Date chTimeEndDate = null;
            try {
                chTimeStartDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getChTimeStart());
                chTimeEndDate = simpleDateFormat.parse(getEntryDefectImproveInnerVO.getChTimeStart());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if (DateUtil.after(chTimeStartDate, chTimeEndDate)) {
                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "病历核查开始时间必须小于结束时间！");
            }
        }
        getEntryDefectImproveInnerVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
    }
}
