package com.docus.server.report.job;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.collection.entity.TBasic;
import com.docus.server.collection.mapper.TBasicMapper;
import com.docus.server.report.client.JaxWsDynamicClient;
import com.docus.server.report.config.SdRyReportQueryConfig;
import com.docus.server.report.dto.ReportDto;
import com.docus.server.report.entity.AfJobTime;
import com.docus.server.report.entity.AfReportRecord;
import com.docus.server.report.mapper.AfJobTimeMapper;
import com.docus.server.report.mapper.AfReportRecordMapper;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.util.IdUtil;
import com.docus.server.report.util.XmlUtil;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 报告相关xxl-Job
 *
 * @author jiashi
 */
@Component
@Slf4j
public class ReportJob {
    @Resource
    private ReportService reportService;
    @Resource
    private AfReportRecordMapper afReportRecordMapper;
    @Resource
    private TBasicMapper tBasicMapper;
    @Resource
    private AfJobTimeMapper afJobTimeMapper;
    @Resource
    private IdService idService;
    @Resource
    private SdRyReportQueryConfig sdRyReportQueryConfig;

    /**
     * Lis 检验报告查询，查询入院时间前 3天的检验报告
     */
    @XxlJob("SdRyLisReportQueryJob")
    public void sdRyLisReportQueryJob() {
        // 顺德人医 Lis 检验报告查询
        final String jobType = "SdRyLisReport";
        LocalDateTime now = LocalDateTime.now();
        // 等待基础数据入库时间
        now=now.plusMinutes(-10);
        log.info("LIS检验报告报告查询 任务开始了");
        // 定义查基础数据 根据基础数据的创建时间
        AfJobTime afJobTime = getJobTimeByJobType(jobType);
        String queryBasicStartDate = afJobTime.getUpdateTime();
        String queryBasicEndDate = DateUtil.formatDateTime(now);
        // 查询基础数据定义 分页
        int offset = 0;
        int pageSize = 50;
        boolean loopCondition = true;
        try {
            do {
                List<TBasic> basicList = tBasicMapper.selectBasicListByCreateOrUpdateTime(queryBasicStartDate, queryBasicEndDate, offset, pageSize);
                if (Func.isEmpty(basicList)) {
                    break;
                }
                if (basicList.size() < pageSize) {
                    loopCondition = false;
                }
                queryLisReport(basicList);

                offset += pageSize;
            } while (loopCondition);
        } catch (Exception ex) {
            log.error("LIS检验报告报告查询 出错啦！", ex);
        }

        afJobTime.setUpdateTime(DateUtil.formatDateTime(now));
        refreshTime(afJobTime);
        log.info("LIS检验报告报告查询 任务结束了，本次查询出院时间段 {} - {}", "", "");
    }

    public void queryLisReport(List<TBasic> basicList) {
        for (TBasic tBasic : basicList) {
            List<ReportDto> reportDtoList = getLisReportList(tBasic);
            if (reportDtoList.isEmpty()) {
                log.warn("病案主键 patientId {} 未查询 LIS 检验报告！", tBasic.getPatientId());
                continue;
            }
            reportDtoList.forEach(reportDto -> {
                reportService.report(reportDto);
            });
        }
    }


    /**
     * 检查报告查询，查询入院时间前 3天的检验报告
     */
    @XxlJob("SdRyInspectReportQueryJob")
    public void sdRyInspectReportQueryJob() {
        // 顺德人医 检查报告查询
        final String jobType = "SdRyInspectReport";
        LocalDateTime now = LocalDateTime.now();
        // 等待基础数据入库时间
        now=now.plusMinutes(-10);
        log.info("检查报告报告查询 任务开始了");
        // 定义查基础数据 更新时间 开始结束
        AfJobTime afJobTime = getJobTimeByJobType(jobType);
        String queryBasicStartDate = afJobTime.getUpdateTime();
        String queryBasicEndDate = DateUtil.formatDateTime(now);
        // 查询基础数据定义 分页
        int offset = 0;
        int pageSize = 50;
        boolean loopCondition = true;
        try {
            do {
                List<TBasic> basicList = tBasicMapper.selectBasicListByCreateOrUpdateTime(queryBasicStartDate, queryBasicEndDate, offset, pageSize);
                if (Func.isEmpty(basicList)) {
                    break;
                }
                if (basicList.size() < pageSize) {
                    loopCondition = false;
                }
                queryInspectReport(basicList);
                offset += pageSize;
            } while (loopCondition);
        } catch (Exception ex) {
            log.error("检查报告报告查询 出错啦！", ex);
        }

        afJobTime.setUpdateTime(DateUtil.formatDateTime(now));
        refreshTime(afJobTime);
        log.info("检查报告报告查询 任务结束了，本次查询出院时间段 {} - {}", "", "");
    }

    public void queryInspectReport(List<TBasic> basicList) {
        for (TBasic tBasic : basicList) {
            List<ReportDto> reportDtoList = getInspectReportList(tBasic);
            if (reportDtoList.isEmpty()) {
                log.warn("病案主键 patientId {} 未查询  检查报告！", tBasic.getPatientId());
                continue;
            }
            reportDtoList.forEach(reportDto -> {
                reportService.report(reportDto);
            });
        }
    }

    private List<ReportDto> getInspectReportList(TBasic tBasic) {
        // 根据基础信息查顺德报告业务系统索引，查 交叉索引
        List<String> sdRyReportPatientIds = getSdRyReportPatientIds(tBasic.getPatientId());
        if (sdRyReportPatientIds.isEmpty()) {
            log.warn("patientId：{} 未查询到检查报告患者交叉索引", tBasic.getPatientId());
            return new ArrayList<>();
        }
        List<ReportDto> reportDtoList = new ArrayList<>();
        // 根据交叉索引查询报告
        for (String sdRyReportPatientId : sdRyReportPatientIds) {
            List<ReportDto> reportDtoList2 = getInspectReportDtoListBySdRyReportPatientId(sdRyReportPatientId, tBasic);
            reportDtoList.addAll(reportDtoList2);
        }
        return reportDtoList;
    }

    private List<ReportDto> getInspectReportDtoListBySdRyReportPatientId(String sdRyReportPatientId, TBasic tBasic) {
        try {
            List<ReportDto> reportDtos = new ArrayList<>();
            int pageNum = 1;
            final int pageSize = 5;
            boolean loopCondition = true;
            do {
                String requestParam = organizationQuerySdRyInspectReportParam(sdRyReportPatientId, tBasic, pageNum, pageSize);
                String url = organizationQuerySdRyInspectReportUrl(sdRyReportQueryConfig.getReportQueryInspectUrl());
                log.info("查询检查报告请求地址：{} ,请求body参数:{}", url, requestParam);
                String respBody = this.sendPost(url, requestParam);
                log.info("查询检查报告请求成功,响应参数：{}", respBody);
                List<ReportDto> reportDtoList = parseQuerySdRyInspectReport(respBody, tBasic);
                if (reportDtoList.isEmpty()) {
                    break;
                }
                if (reportDtoList.size() < pageSize) {
                    loopCondition = false;
                }
                reportDtos.addAll(reportDtoList);
                pageNum++;
            } while (loopCondition);
            return reportDtos;
        } catch (Exception ex) {
            log.error("查询检查报告出错啦！", ex);
            return new ArrayList<>();
        }
    }

    private String organizationQuerySdRyInspectReportUrl(String reportQueryLisUrl) {
        return reportQueryLisUrl + "/query?uuid=" + IdUtil.standardUUID() +
                "&action=" + sdRyReportQueryConfig.getReportQueryInspectAction() +
                "&accessKey=" + sdRyReportQueryConfig.getReportQueryInspectAccessKey()
                + "&creationTime=" + Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);

    }

    private String organizationQuerySdRyInspectReportParam(String sdRyReportPatientId, TBasic tBasic, int pageNum, int pageSize) {
        boolean isPage = true;
        String orgCode = "4560886379";
        Date admissDate = tBasic.getAdmissDate();
        if (admissDate == null) {
            throw new BaseException("patientId：" + tBasic.getPatientId() + "的入院时间为空");
        }
        Instant instant = admissDate.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate admissLocalDate = instant.atZone(zoneId).toLocalDate();
        LocalDate endTimeLocalDate = admissLocalDate.plusDays(1);
        LocalDate startTimeLocalDate = admissLocalDate.plusDays(-3);
        String startTime = startTimeLocalDate + " 00:00:00";
        String endTime = endTimeLocalDate + " 00:00:00";

        HashMap<Object, Object> map = new HashMap<>(7);
        map.put("isPage", isPage);
        map.put("pageNo", pageNum);
        map.put("pageSize", pageSize);
        map.put("OrgCode", orgCode);
        map.put("StartTime", startTime);
        map.put("EndTime", endTime);
        map.put("PatientId", sdRyReportPatientId);
        map.put("PatentTypeCode", "1");
        return Func.toJson(map);
    }

    private List<ReportDto> parseQuerySdRyInspectReport(String respBody, TBasic tBasic) {
        JSONObject jsonObject = Func.readJson(respBody, JSONObject.class);
        Object resultCode = jsonObject.get("ResultCode");
        String successCode = "0";
        if (!successCode.equals(String.valueOf(resultCode))) {
            return new ArrayList<>();
        }
        try {
            Object data = jsonObject.get("data");
            String dataJsonStr = Func.toJson(data);
            // 是否是json object ，因为返回的如果是 [] ，则不会识别为jsonObject
            List<ReportDto> reportDtoList = new ArrayList<>();
            if (Func.isJsonObject(dataJsonStr)) {
                JSONObject dataJsonObject = Func.readJson(dataJsonStr, JSONObject.class);
                Object result = dataJsonObject.get("result");
                String resultJsonStr = Func.toJson(result);
                List<JSONObject> reportObjectList = Func.parseJsonArray(resultJsonStr, JSONObject.class);
                if (Func.isNotEmpty(reportObjectList)) {
                    for (JSONObject reportObject : reportObjectList) {
                        // 检查报告号
                        String examReportSn = String.valueOf(reportObject.get("EXAM_REPORT_SN"));
                        // 申请单号
                        String requestSn = String.valueOf(reportObject.get("REQUEST_SN"));
                        // pdf地址
                        String pdfUrl = String.valueOf(reportObject.get("FILE_PATH"));
                        // 报告名称
                        String reportName = String.valueOf(reportObject.get("REPORT_NAME"));
                        // 系统修改
                        String updateBy = String.valueOf(reportObject.get("UPDATEBY"));

                        ReportDto reportDto = new ReportDto();
                        reportDto.setAdmisstimes(tBasic.getAdmissTimes());
                        reportDto.setInpatientNo(tBasic.getInpatientNo());
                        // 确定报告唯一 报告单号+申请单号
                        reportDto.setSerialnum(examReportSn + requestSn);
                        reportDto.setFileTitle(reportName);
                        reportDto.setDownUrl(pdfUrl);
                        reportDto.setAssortId(sdRyReportQueryConfig.getReportQueryInspectAssortId());
                        reportDto.setSysFlag(updateBy);
                        reportDto.setFileSource("1");
                        reportDto.setFilestoragetype("1");
                        reportDtoList.add(reportDto);
                    }
                }
            }
            return reportDtoList;
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            return new ArrayList<>();
        }
    }

    private String sendPost(String url, String body) {
        HttpRequest post = HttpUtil.createPost(url);
        post.timeout(60 * 1000);
        post.header("Content-Type", "application/json; charset=utf-8");
        post.body(body);
        HttpResponse response = post.execute();
        return response.body();
    }

    /**
     * 查询job需要的开始时间
     *
     * @param jobType job类型
     * @return job需要的开始时间，未查到 默认 1801-01-01 00:00:00
     */
    private AfJobTime getJobTimeByJobType(String jobType) {
        AfJobTime afJobTime = afJobTimeMapper.getAfJobTimeByJobType(jobType);
        // 定义查基础数据 入院时间 开始结束
        String startTime = "1801-01-01 00:00:00";
        if (afJobTime == null) {
            afJobTime = new AfJobTime();
            afJobTime.setJobType(jobType);
            afJobTime.setUpdateTime(startTime);
        }
        if (Func.isBlank(afJobTime.getUpdateTime())) {
            afJobTime.setUpdateTime(startTime);
        }
        return afJobTime;
    }


    private List<ReportDto> getLisReportList(TBasic tBasic) {
        // 根据基础信息查顺德报告业务系统索引，查 交叉索引
        List<String> sdRyReportPatientIds = getSdRyReportPatientIds(tBasic.getPatientId());
        if (sdRyReportPatientIds.isEmpty()) {
            log.warn("patientId：{} 未查询到Lis检验报告患者交叉索引", tBasic.getPatientId());
            return new ArrayList<>();
        }
        List<ReportDto> reportDtoList = new ArrayList<>();
        // 根据交叉索引查询报告
        for (String sdRyReportPatientId : sdRyReportPatientIds) {
            List<ReportDto> reportDtoList2 = getLisReportDtoListBySdRyReportPatientId(sdRyReportPatientId, tBasic);
            reportDtoList.addAll(reportDtoList2);
        }
        return reportDtoList;
    }

    private List<ReportDto> getLisReportDtoListBySdRyReportPatientId(String sdRyReportPatientId, TBasic tBasic) {
        try {
            List<ReportDto> reportDtos = new ArrayList<>();
            int pageNum = 1;
            final int pageSize = 5;
            boolean loopCondition = true;
            do {
                String requestParam = organizationQuerySdRyLisReportParam(sdRyReportPatientId, tBasic, pageNum, pageSize);
                String url = organizationQuerySdRyLisReportUrl(sdRyReportQueryConfig.getReportQueryLisUrl());
                log.info("查询Lis报告请求地址：{} ,请求body参数:{}", url, requestParam);
                HttpRequest post = HttpUtil.createPost(url);
                post.timeout(60 * 1000);
                post.header("Content-Type", "application/json; charset=utf-8");
                post.body(requestParam);
                HttpResponse response = post.execute();
                String respBody = response.body();
                log.info("查询Lis报告请求成功,响应参数：{}", respBody);
                List<ReportDto> reportDtoList = parseQuerySdRyLisReport(respBody, tBasic);
                if (reportDtoList.isEmpty()) {
                    break;
                }
                if (reportDtoList.size() < pageSize) {
                    loopCondition = false;
                }
                reportDtos.addAll(reportDtoList);
                pageNum++;
            } while (loopCondition);
            return reportDtos;
        } catch (Exception ex) {
            log.error("查询Lis报告出错啦！", ex);
            return new ArrayList<>();
        }
    }

    private List<ReportDto> parseQuerySdRyLisReport(String respBody, TBasic tBasic) {
        JSONObject jsonObject = Func.readJson(respBody, JSONObject.class);
        Object resultCode = jsonObject.get("ResultCode");
        String successCode = "0";
        if (!successCode.equals(String.valueOf(resultCode))) {
            return new ArrayList<>();
        }
        try {
            Object data = jsonObject.get("data");
            String dataJsonStr = Func.toJson(data);
            // 是否是json object ，因为返回的如果是 [] ，则不会识别为jsonObject
            List<ReportDto> reportDtoList = new ArrayList<>();
            if (Func.isJsonObject(dataJsonStr)) {
                JSONObject dataJsonObject = Func.readJson(dataJsonStr, JSONObject.class);
                Object result = dataJsonObject.get("result");
                String resultJsonStr = Func.toJson(result);
                List<JSONObject> reportObjectList = Func.parseJsonArray(resultJsonStr, JSONObject.class);
                if (Func.isNotEmpty(reportObjectList)) {
                    for (JSONObject reportObject : reportObjectList) {
                        // 检验报告号
                        String labReportSn = String.valueOf(reportObject.get("LAB_REPORT_SN"));
                        // 申请单号
                        String requestSn = String.valueOf(reportObject.get("REQUEST_SN"));
                        // pdf地址
                        String pdfUrl = String.valueOf(reportObject.get("PDF_URL"));
                        // 报告名称
                        String reportTypeName = String.valueOf(reportObject.get("REPORT_TYPE_NAME"));
                        // 系统修改
                        String updateBy = String.valueOf(reportObject.get("UPDATEBY"));

                        ReportDto reportDto = new ReportDto();
                        reportDto.setAdmisstimes(tBasic.getAdmissTimes());
                        reportDto.setInpatientNo(tBasic.getInpatientNo());
                        // 确定报告唯一 报告单号+申请单号
                        reportDto.setSerialnum(labReportSn + requestSn);
                        reportDto.setFileTitle(reportTypeName);
                        reportDto.setDownUrl(pdfUrl);
                        reportDto.setAssortId(sdRyReportQueryConfig.getReportQueryLisAssortId());
                        reportDto.setSysFlag(updateBy);
                        reportDto.setFileSource("1");
                        reportDto.setFilestoragetype("1");
                        reportDtoList.add(reportDto);
                    }
                }
            }
            return reportDtoList;
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            return new ArrayList<>();
        }
    }

    private String organizationQuerySdRyLisReportUrl(String reportQueryLisUrl) {
        return reportQueryLisUrl + "/query?uuid=" + IdUtil.standardUUID() +
                "&action=" + sdRyReportQueryConfig.getReportQueryLisAction() +
                "&accessKey=" + sdRyReportQueryConfig.getReportQueryLisAccessKey()
                + "&creationTime=" + Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);

    }

    private String organizationQuerySdRyLisReportParam(String sdRyReportPatientId, TBasic tBasic, int pageNum, int pageSize) {
        boolean isPage = true;
        String orgCode = "4560886379";
        Date admissDate = tBasic.getAdmissDate();
        if (admissDate == null) {
            throw new BaseException("patientId：" + tBasic.getPatientId() + "的入院时间为空");
        }
        Instant instant = admissDate.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate admissLocalDate = instant.atZone(zoneId).toLocalDate();
        LocalDate endTimeLocalDate = admissLocalDate.plusDays(1);
        LocalDate startTimeLocalDate = admissLocalDate.plusDays(-3);
        String startTime = startTimeLocalDate + " 00:00:00";
        String endTime = endTimeLocalDate + " 00:00:00";

        HashMap<Object, Object> map = new HashMap<>(7);
        map.put("isPage", isPage);
        map.put("pageNo", pageNum);
        map.put("pageSize", pageSize);
        map.put("OrgCode", orgCode);
        map.put("StartTime", startTime);
        map.put("EndTime", endTime);
        map.put("PatientId", sdRyReportPatientId);
        map.put("PatentTypeCode", "1");
        return Func.toJson(map);
    }

    /**
     * 根据归档病案主键查询报告交叉索引
     *
     * @param patientId 归档病案主键
     * @return 报告交叉索引
     */
    private List<String> getSdRyReportPatientIds(String patientId) {
        String sDryIndex = tBasicMapper.getSdRyIndexByPatientId(patientId);
        if (Func.isBlank(sDryIndex)) {
            log.warn("patientId:{} 未关联到第三方索引", patientId);
            return new ArrayList<>();
        }
        String param = organizationQuerySdRyReportIndexParam(sDryIndex);
        String[] params={"HIP1179",param};
        String namespaceUri = sdRyReportQueryConfig.getQueryReportIndexWsdlNamespaceUri();
        String wsdlAddr = sdRyReportQueryConfig.getQueryReportIndexWsdlAddr();
        String operationName = sdRyReportQueryConfig.getQueryReportIndexWsdlOperationName();
        String result = JaxWsDynamicClient.send(wsdlAddr, namespaceUri, operationName, params);
        log.info("查询顺德人医患者交叉索引数据，返回值：{}", result);
        if (result == null) {
            return new ArrayList<>();
        }
        return parseQuerySdRyReportIndex(result);
    }

    /**
     * 组织顺德人医查询交叉索引的请求参数
     *
     * @param sDryIndex 顺德人医关联索引
     * @return 顺德人医查询交叉索引的请求参数
     */
    private String organizationQuerySdRyReportIndexParam(String sDryIndex) {
        sDryIndex = sDryIndex.toLowerCase()
                .replace("m", "")
                .replace("z", "");
        String receiver = "Orion-001";
        String sender = "PaperlessManagementMRIS-001";
        String now = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);

        return "<PRPA_HIP1179 xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xmlns=\"urn:hl7-org:v3\" xsi:schemaLocation=\"urn:hl7-org:v3 ../multicacheschemas/PRPA_IN201306UV02.xsd\">\n" +
                "\t<id root=\"2.16.156.10011.0\" extension=\"" + IdUtil.standardUUID() + "\"/>\n" +
                "\t<creationTime value=\"" + now + "\"/>\n" +
                "\t<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"PRPA_IHIP1179\"/>\n" +
                "\t<processingCode code=\"P\"/>\n" +
                "\t<processingModeCode/>\n" +
                "\t<acceptAckCode code=\"AL\"/>\n" +
                "\t<receiver typeCode=\"RCV\">\n" +
                "\t\t<telecom/>\n" +
                "\t\t<device classCode=\"DEV\" determinerCode=\"INSTANCE\">\n" +
                "\t\t\t<id>\n" +
                "\t\t\t\t<item root=\"2.16.156.10011.0.1.1\" extension=\"" + receiver + "\"/>\n" +
                "\t\t\t</id>\n" +
                "\t\t</device>\n" +
                "\t</receiver>\n" +
                "\t<sender typeCode=\"SND\">\n" +
                "\t\t<telecom/>\n" +
                "\t\t<device classCode=\"DEV\" determinerCode=\"INSTANCE\">\n" +
                "\t\t\t<id>\n" +
                "\t\t\t\t<item root=\"2.16.156.10011.0.1.2\" extension=\"" + sender + "\"/>\n" +
                "\t\t\t</id>\n" +
                "\t\t</device>\n" +
                "\t</sender>\n" +
                "\t<controlActProcess classCode=\"CACT\" moodCode=\"EVN\">\n" +
                "\t\t<code code=\"empiIndexQuery\">\n" +
                "\t\t\t<displayName value=\"交叉索引查询\"/>\n" +
                "\t\t</code>\n" +
                "\t\t<queryByParameter>\n" +
                "\t\t\t<!-- 查询条件：type：类型 value：值 -->\n" +
                "\t\t\t<!--type 1:患者id 2:身份证 3::电子健康码-->\n" +
                "\t\t\t<queryParam type=\"1\" value=\"" + sDryIndex + "\"/>\n" +
                "\t\t\t<!--1:门诊 3:住院-->\n" +
                "\t\t\t<visitType type=\"1\"/>\n" +
                "\t\t</queryByParameter>\n" +
                "\t</controlActProcess>\n" +
                "</PRPA_HIP1179>\n";
    }


    private static List<String> parseQuerySdRyReportIndex(String result) {
        try {
            XmlUtil xmlUtil = XmlUtil.of(result);
            NodeList nodeList = xmlUtil.getNodeList("/PRPA_HIP1179/controlActProcess/subject/empiIndex/patientIds/patientId");
            int nodeListLength = nodeList.getLength();
            ArrayList<String> patientIds = new ArrayList<>();
            if (nodeListLength > 0) {
                for (int i = 0; i < nodeListLength; i++) {
                    Node node = nodeList.item(i);
                    String patientId = node.getTextContent();
                    if (Func.isNotBlank(patientId)) {
                        patientIds.add(patientId);
                    }
                }
            }
            return patientIds;
        } catch (Exception ex) {
            log.error("顺德人医解析患者交叉索引失败。", ex);
            return new ArrayList<>();
        }
    }


    private void refreshTime(AfJobTime afJobTime) {
        if (afJobTime.getId() == null) {
            afJobTime.setId(idService.getDateSeq());
            afJobTimeMapper.insert(afJobTime);
            return;
        }
        afJobTimeMapper.updateById(afJobTime);
    }


    /**
     * 补偿异常的报告
     */
    @XxlJob("MakeupExceptionReportJob")
    public void makeupExceptionReport() {
        log.info("补偿异常的报告 任务开始了");
        int makeupSize = 0;
        final int pageSize = 1000;
        int page = 1;
        boolean loopCondition = true;
        try {
            do {

                List<AfReportRecord> reportRecords = afReportRecordMapper.getStartStateReportRecord(page, pageSize);
                if (reportRecords == null || reportRecords.size() < pageSize) {
                    // 结束循环
                    loopCondition = false;
                }
                if (reportRecords != null) {
                    updateReportRecordPatientId(reportRecords);
                    List<Long> taskIds = reportRecords.stream().map(AfReportRecord::getTaskId).collect(Collectors.toList());
                    reportService.makeupReportByTaskIds(taskIds);
                }
                page++;
            } while (loopCondition);
        } catch (Exception ex) {
            log.error("补偿异常的报告出错啦！" + ex.getMessage(), ex);
        }
        log.info("补偿异常的报告 任务结束了,本次补偿报告 {} 条", makeupSize);
    }

    private void updateReportRecordPatientId(List<AfReportRecord> reportRecords) {
        if (reportRecords == null || reportRecords.isEmpty()) {
            return;
        }
        for (AfReportRecord reportRecord : reportRecords) {
            if (Func.isNotBlank(reportRecord.getPatientId())) {
                continue;
            }
            try {
                // 如果出现多条出错的情况，还是得保存收到的信息，人工干预处理
                String patientId = tBasicMapper.getPatientIdByInpatientNoAndAdminssTimes(reportRecord.getInpatientNo(), reportRecord.getAdmissTimes());
                if (Func.isNotBlank(patientId)) {
                    afReportRecordMapper.updateReportRecordPatientId(patientId, reportRecord.getTaskId());
                }
            } catch (Exception ex) {
                log.error("查询病案主键出错了", ex);
            }
        }
    }
}
