package com.ywt.outpatient.service.rpc;

import com.ywt.biz.common.util.Checker;
import com.ywt.biz.common.util.DateUtil;
import com.ywt.biz.common.util.StringHelper;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.nfyy.*;
import com.ywt.gapi.nfyy.GetPatientInfoResponse;
import com.ywt.gapi.nfyy.InspectionReport;
import com.ywt.gapi.nfyy.LaboratoryReport;
import com.ywt.gapi.nfyy.PatientInfo;
import com.ywt.gapi.third.taihe.GetScheduleListRequest;
import com.ywt.gapi.third.taihe.GetScheduleListResponse;
import com.ywt.gapi.third.taihe.*;
import com.ywt.outpatient.core.SqlHelper;
import com.ywt.outpatient.core.utils.BizUtil;
import com.ywt.outpatient.domain.entity.center.*;
import com.ywt.outpatient.domain.entity.center.Registration;
import com.ywt.outpatient.core.Constants;
import com.ywt.outpatient.domain.models.enums.MedicalRecordsTypeEnum;
import com.ywt.outpatient.service.rpc.common.NfyyProvider;
import com.ywt.outpatient.service.common.TaiheProvider;
import com.ywt.outpatient.service.rpc.common.WxProvider;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 数据逻辑类
 */
@Service
public class DataService {
    private static Logger logger = LoggerFactory.getLogger(DataService.class);

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private TmpCardRepository tmpCardRepository;

    @Autowired
    private MedicalCardRepository medicalCardRepository;

    @Autowired
    private NfyyProvider nfyyProvider;

    @Autowired
    private InspectionReportRepository inspectionReportRepository;

    @Autowired
    private InspectionDetailRepository inspectionDetailRepository;

    @Autowired
    private LaboratoryReportRepository laboratoryReportRepository;

    @Autowired
    private LaboratoryDetailRepository laboratoryDetailRepository;


    @DubboReference
    private NfyyService nfyyServiceBlockingStub;

    @Autowired
    private RegistrationRepository registrationRepository;

    @Autowired
    private OutpatientServiceMedicalRecordRepository outpatientServiceMedicalRecordRepository;

    @Autowired
    private SqlHelper sqlHelper;

    @DubboReference
    private TaiheService taiheServiceBlockingStub;

    @Autowired
    private WxProvider wxProvider;

    @Autowired
    private TaiheProvider taiheProvider;

    @Autowired
    private MedicalRecordsRepository medicalRecordsRepository;

    @Autowired
    private OutpatientOrderRepository outpatientOrderRepository;

    @Autowired
    private BizConfigurer bizConfigurer;

    @Autowired
    private DepartmentRepository departmentRepository;

//    @Autowired
//    private AccountRepository accountRepository;
//
//    @Autowired
//    private AccountDetailRepository accountDetailRepository;
//
//    public void tt(){
//        List<Account> accounts = accountRepository.findAll();
//        for(Account a : accounts){
//            if(a.getUserId() == null){
//                continue;
//            }
//            String sql = String.format("select sum(amount) from account_detail where user_id = %d;", a.getUserId());
//            Integer t = jdbcTemplate.queryForObject(sql, null, Integer.class);
//
//            if(t != null) {
//                a.setBalance(t);
//                accountRepository.save(a);
//            }
//        }
//    }

    /**
     * 根据诊疗卡同步挂号记录
     *
     * @param minId
     * @param maxId
     */
    public void syncHisRegistration(int minId, int maxId) {
        List<MedicalCard> lst = medicalCardRepository.getMedicalCardList(minId, maxId);

        if (lst == null || lst.size() == 0) {
            logger.info("syncHisRegistration({}, {}): 诊疗卡列表为空。", minId, maxId);
            return;
        }

        GetRegisteredRecordListRequest req;
        GetRegisteredRecordListResponse res;
        Registration registration;

        for (MedicalCard card : lst) {
            try {
                req = GetRegisteredRecordListRequest.newBuilder()
                        .setStartDate("2000-01-01")
                        .setEndDate("2018-05-23")
                        .setPatientId(card.getHisPatientId())
                        .build();
                res = nfyyServiceBlockingStub.getRegisteredRecordList(req);

                if (res.getCode() == 0) {
                    for (RegisteredRecord record : res.getRecordList()) {
                        if (registrationRepository.count(record.getRegId(), card.getId()) > 0) {
                            continue;
                        }

                        registration = new Registration();
                        registration.setUserId(card.getUserId());
                        registration.setRegId(record.getRegId());
                        registration.setRegDate(record.getRegDate());
                        registration.setStatus(record.getStatus());
                        registration.setPatientId(record.getPatientId());
                        registration.setPatientName(record.getPatName());
                        registration.setAdmitDate(record.getAdmitDate());
                        registration.setHospitalName(record.getHospitalName());
                        registration.setDepartmentCode(record.getDepartmentCode());
                        registration.setDepartment(record.getDepartment());
                        registration.setDoctorCode(record.getDoctorCode());
                        registration.setDoctor(record.getDoctor());
                        registration.setDoctorTitle(record.getDoctorTitle());
                        registration.setRegFee(record.getRegFee());
                        registration.setSeqCode(record.getSeqCode());
                        registration.setAdmitAddress(record.getAdmitAddress());
                        registration.setSessionName(record.getSessionName());
                        registration.setAdmitRange(record.getAdmitRange());
                        registration.setServiceName(record.getServiceName());
                        registration.setInsuRegInfo(record.getInsuRegInfo());
                        registration.setReturnFlag(record.getReturnFlag());
                        registration.setStartTime(record.getStartime());
                        registration.setEndTime(record.getEndtime());
                        registration.setTransactionId(record.getTransactionId());
                        registration.setCreateTime(new Date());
                        registration.setMedicalCardId(card.getId());

                        registrationRepository.save(registration);
                    }

                    logger.info("syncHisRegistration(), card_id: {}, {}", card.getId(), res.getMsg());
                } else {
                    logger.info("syncHisRegistration(), card_id: {}, his_patient_id: {}, {}",
                            card.getId(), card.getHisPatientId(), res.getMsg());
                }
            } catch (Exception e) {
                logger.error("syncHisRegistration(), card_id: {}, his_patient_id: {}, {}",
                        card.getId(), card.getHisPatientId(), e.getMessage(), e);

                try {
                    Thread.sleep(15 * 60 * 1000L);
                } catch (InterruptedException ex) {
                    logger.error(" Thread Sleep(): {}", ex.getMessage(), ex);
                }
            }
        }

        logger.info("syncHisRegistration({}, {}): END", minId, maxId);
    }

    /**
     * 根据挂号记录同步病历
     *
     * @param minId
     * @param maxId
     */
    public void syncHisMedicalRecord(int minId, int maxId) {
        List<Registration> registrations = registrationRepository.getRegistrationList(minId, maxId);

        if (registrations == null || registrations.size() == 0) {
            logger.info("syncHisMedicalRecord({}, {}): 挂号记录列表为空。", minId, maxId);
            return;
        }

        GetMedicalCaseDetailRequest req;
        GetMedicalCaseDetailResponse res;

        MedCase medCase;
        MedCasePatInfo medCasePatInfo;
        MedRecordDetail medRecordDetail;

        OutpatientServiceMedicalRecord outpatientServiceMedicalRecord;

        for (Registration reg : registrations) {
            try {
                if (outpatientServiceMedicalRecordRepository.count(reg.getRegId(), reg.getMedicalCardId()) > 0) {
                    continue;
                }

                req = GetMedicalCaseDetailRequest.newBuilder()
                        .setClinicSeq(Checker.parseInt(reg.getRegId()))
                        .build();
                res = nfyyServiceBlockingStub.getMedicalCaseDetail(req);

                if (res.getCode() == 0) {
                    medCase = res.getData();
                    medCasePatInfo = medCase.getPatient();
                    medRecordDetail = medCase.getDetail();

                    outpatientServiceMedicalRecord = new OutpatientServiceMedicalRecord();
                    outpatientServiceMedicalRecord.setUserId(reg.getUserId());
                    outpatientServiceMedicalRecord.setMedicalCardId(reg.getMedicalCardId());
                    outpatientServiceMedicalRecord.setMedicalRecordId(medCase.getId());
                    outpatientServiceMedicalRecord.setTitle(medCase.getTitle());
                    outpatientServiceMedicalRecord.setEffectiveTime(medCase.getEffectiveTime());
                    outpatientServiceMedicalRecord.setAuthor(medCase.getAuthor());
                    outpatientServiceMedicalRecord.setDoctorId(medCase.getDoctorId());
                    outpatientServiceMedicalRecord.setCustodian(medCase.getCustodian());
                    outpatientServiceMedicalRecord.setCreateTime(new Date());
                    outpatientServiceMedicalRecord.setRegId(reg.getRegId());

                    if (medCasePatInfo != null) {
                        outpatientServiceMedicalRecord.setMedicareNo(medCasePatInfo.getMedicareNo());
                        outpatientServiceMedicalRecord.setAdmvisitNo(medCasePatInfo.getAdmvisitNo());
                        outpatientServiceMedicalRecord.setHealthCardNo(medCasePatInfo.getHealthCardNo());
                        outpatientServiceMedicalRecord.setAddr(medCasePatInfo.getAddr());
                        outpatientServiceMedicalRecord.setName(medCasePatInfo.getName());
                        outpatientServiceMedicalRecord.setTelecom(medCasePatInfo.getTelecom());
                        outpatientServiceMedicalRecord.setAdministrativeGender(medCasePatInfo.getAdministrativeGender());
                        outpatientServiceMedicalRecord.setEthnicGroup(medCasePatInfo.getEthnicGroup());
                        outpatientServiceMedicalRecord.setAge(medCasePatInfo.getAge());
                    }

                    if (medRecordDetail != null) {
                        outpatientServiceMedicalRecord.setDepId(medRecordDetail.getDepId());
                        outpatientServiceMedicalRecord.setDepName(medRecordDetail.getDepName());
                        outpatientServiceMedicalRecord.setPatId(medRecordDetail.getPatId());
                        outpatientServiceMedicalRecord.setFeeType(medRecordDetail.getFeeType());
                        outpatientServiceMedicalRecord.setFeeTypeName(medRecordDetail.getFeeTypeName());
                        outpatientServiceMedicalRecord.setAdmData(medRecordDetail.getAdmData());
                        outpatientServiceMedicalRecord.setClinicCount(medRecordDetail.getClinicCount());
                        outpatientServiceMedicalRecord.setSelfReport(medRecordDetail.getSelfReport());
                        outpatientServiceMedicalRecord.setPhyExam(medRecordDetail.getPhyExam());
                        outpatientServiceMedicalRecord.setDocAdvice(medRecordDetail.getDocAdvice());
                        outpatientServiceMedicalRecord.setSuggestion(medRecordDetail.getSuggesion());
                        outpatientServiceMedicalRecord.setDiagnose(medRecordDetail.getDiagnose());
                    }

                    outpatientServiceMedicalRecordRepository.save(outpatientServiceMedicalRecord);

                    logger.info("syncHisMedicalRecord({})SUCCEED: {}", reg.getId(), res.getMsg());
                } else {
                    logger.info("syncHisMedicalRecord({})FAILED: {}", reg.getId(), res.getMsg());
                }
            } catch (Exception e) {
                logger.error("syncHisMedicalRecord({}): {}", reg.getId(), e.getMessage(), e);

                try {
                    Thread.sleep(15 * 60 * 1000L);
                } catch (InterruptedException ex) {
                    logger.error(" Thread Sleep(): {}", ex.getMessage(), ex);
                }
            }
        }

        logger.info("syncHisRegistration({}, {}): END", minId, maxId);
    }

    /**
     * 根据挂号记录同步检查报告
     *
     * @param minId
     * @param maxId
     */
    public void syncHisInspection(int minId, int maxId) {
        List<Registration> registrations = registrationRepository.getRegistrationList(minId, maxId);

        if (registrations == null || registrations.size() == 0) {
            logger.info("syncHisInspection({}, {}): 挂号记录列表为空。", minId, maxId);
            return;
        }

        GetInspectionReportListRequest req;
        GetInspectionReportListResponse res;

        for (Registration reg : registrations) {
            try {
                req = GetInspectionReportListRequest.newBuilder()
                        .setClinicSeq(reg.getRegId())
                        .build();
                res = nfyyServiceBlockingStub.getInspectionReportList(req);

                if (res.getCode() == 0) {
                    for (com.ywt.gapi.nfyy.InspectionReport report : res.getInspectionReportList()) {
                        syncInspectionReport(reg.getPatientId(), reg.getUserId(), report);
                    }

                    logger.info("syncHisInspection(regId: {})SUCCEED", reg.getId());
                } else {
                    logger.info("syncHisInspection(regId: {})FAILED: {}", reg.getId(), res.getMsg());
                }
            } catch (Exception e) {
                logger.error("syncHisInspection({}): {}");
            }
        }

        logger.info("syncHisInspection({}, {}): END", minId, maxId);
    }

    public void syncMedicalCard() {
        //导入诊疗卡数据
        Random random = new Random();
        String sql = "select id, patientId, mobile, newUserId, cardId from hz_customercard where `cardId` not in (select card_no from medical_card) and newUserId is not null and cardId is not null and cardId != '' order by newUserId;";
        sql = "select id, patientId, mobile, newUserId, cardId from hz_customercard where patientId not in (select his_patient_id from medical_card);";
        List<TmpCard> lst;// = tmpCardRepository.findAll(new Sort("newUserId"));
//            tmpCardRepository.
        lst = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TmpCard.class));

        for (TmpCard card : lst) {
            if (card.getNewUserId() == null) {
                continue;
            }

            MedicalCard medicalCard = medicalCardRepository.getCard(card.getNewUserId(), card.getPatientId());
//            MedicalCard medicalCard = medicalCardRepository.getCard(card.getNewUserId(), card.getPatientId(), card.getCardId());

            if (medicalCard != null) {
                continue;
            }

            try {
                GetPatientInfoResponse getPatientInfoResponse = nfyyProvider.getPatientInfo("", card.getPatientId(), "", "");

                if (getPatientInfoResponse != null && getPatientInfoResponse.getCode() == ResultCode.SUCCEED.getNumber()) {
                    //读取患者信息成功
                    PatientInfo patientInfo = getPatientInfoResponse.getPatientInfo();

                    medicalCard = new MedicalCard();
                    medicalCard.setUserId(card.getNewUserId());
                    medicalCard.setHospitalId(1);
                    medicalCard.setCardNo(patientInfo.getCardNo());
                    medicalCard.setCardType(patientInfo.getCardType());
                    medicalCard.setPatientName(patientInfo.getPatientName());
                    medicalCard.setMobile(patientInfo.getMobile());
                    medicalCard.setHisPatientId(patientInfo.getPatientId());
                    medicalCard.setPatientType(patientInfo.getPatientType());
                    medicalCard.setSex(patientInfo.getSex());
                    medicalCard.setBirthday(patientInfo.getBirthday());
                    medicalCard.setAddress(patientInfo.getAddress());
                    medicalCard.setTelephoneNo(patientInfo.getTelephoneNo());
                    medicalCard.setDocumentId(patientInfo.getDocumentId());
                    medicalCard.setBalance((int) (patientInfo.getBalance() * 100d));
                    medicalCard.setIdTypeCode(patientInfo.getIdTypeCode());
                    medicalCard.setIdTypeDesc(patientInfo.getIdTypeDesc());
                    medicalCard.setIdNo(patientInfo.getIdNo());
                    medicalCard.setInsureCardNo(patientInfo.getInsureCardNo());
                    medicalCard.setAccInfo(patientInfo.getAccInfo());

                    userService.saveMedicalCard(medicalCard);
                    logger.info("SUCCEED: newUserId-{}, patientId-{}, cardNo-{} ", card.getNewUserId(), card.getPatientId(), card.getCardId());
                } else {
                    logger.info("FAILED: newUserId-{}, patientId-{}, cardNo-{}: {}",
                            card.getNewUserId(), card.getPatientId(), card.getCardId(), getPatientInfoResponse.getMsg());
                }
            } catch (Exception e) {
                logger.error("参数：newUserId-{}, patientId-{}, 错误信息：{}", card.getNewUserId(), card.getPatientId(), e.getMessage(), e);
            }

            try {
                Thread.sleep(random.nextInt(5) * 1000L);
//                System.out.wait(random.nextInt(10) * 3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据就诊卡号同步检验检查结果
     */
    public void syncReport() {
        List<MedicalCard> lst;  // = new LinkedList<>();
        Random random = new Random();
//        MedicalCard card = medicalCardRepository.getMedicalCard(89080, "03203298");
//        MedicalCard card = medicalCardRepository.findOne(99593);

//        if (card != null) {
//            lst.add(card);
//        }

//        card = medicalCardRepository.findOne(99488);
//
//        if (card != null) {
//            lst.add(card);
//        }

        lst = medicalCardRepository.getMedicalCardList(23753, 30000);
        GetRegisteredRecordListRequest req = null;
        GetRegisteredRecordListResponse res;
        GetInspectionReportListRequest getInspectionReportListRequest;
        GetInspectionReportListResponse getInspectionReportListResponse;
        com.ywt.outpatient.domain.entity.center.InspectionReport inspectionReport;
        GetLaboratoryReportListRequest getLaboratoryReportListRequest;
        GetLaboratoryReportListResponse getLaboratoryReportListResponse;
        com.ywt.outpatient.domain.entity.center.LaboratoryReport laboratoryReport;

        for (MedicalCard medicalCard : lst) {
            try {
                Thread.sleep(random.nextInt(5) * 1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            try {
                req = GetRegisteredRecordListRequest.newBuilder()
                        .setStartDate("2000-01-01")
                        .setEndDate(DateUtil.convertToString(new Date(), "yyyy-MM-dd"))
                        .setPatientId(medicalCard.getHisPatientId())
                        .build();
                res = nfyyServiceBlockingStub.getRegisteredRecordList(req);

                if (res.getCode() == 0) {
                    for (RegisteredRecord record : res.getRecordList()) {
                        getInspectionReportListRequest = GetInspectionReportListRequest.newBuilder()
                                .setClinicSeq(record.getRegId())
                                .build();
                        getInspectionReportListResponse = nfyyServiceBlockingStub.getInspectionReportList(getInspectionReportListRequest);

                        if (getInspectionReportListResponse.getCode() == 0) {
                            for (com.ywt.gapi.nfyy.InspectionReport report : getInspectionReportListResponse.getInspectionReportList()) {
                                inspectionReport = inspectionReportRepository.getByReportId(report.getReportId());

                                if (inspectionReport == null) {
                                    inspectionReport = new com.ywt.outpatient.domain.entity.center.InspectionReport();
                                    inspectionReport.setId(idGenerator.genInspectionReportId());
                                    inspectionReport.setCreateTime(new Date());
                                    inspectionReport.setDeleted(false);
                                    inspectionReport.setUserId(medicalCard.getUserId());
                                    inspectionReport.setReportId(report.getReportId());
                                    inspectionReport.setReportTitle(report.getReportTitle());
                                    inspectionReport.setStatus(report.getStatus());
                                    inspectionReport.setPatientName(report.getPatientName());
                                    inspectionReport.setPatientAge(report.getPatientAge());
                                    inspectionReport.setSex(report.getSex());
                                    inspectionReport.setClinicalDiagnosis(report.getClinicalDiagnosis());
                                    inspectionReport.setClinicSeq(report.getClinicSeq());
                                    inspectionReport.setInpatientId(report.getInpatientId());
                                    inspectionReport.setHisPatientId(record.getPatientId());

                                    if (report.getReportDate().length() == 10) {
                                        inspectionReport.setReportDate(DateUtil.stringToDate(report.getReportDate(), "yyyy-MM-dd"));
                                    } else {
                                        inspectionReport.setReportDate(DateUtil.stringToDate(report.getReportDate()));
                                    }

                                    inspectionReportRepository.save(inspectionReport);

                                    syncInspectionReportDetail(report.getReportId(), medicalCard.getUserId(), inspectionReport.getId());
                                }
                            }
                        }

                        getLaboratoryReportListRequest = GetLaboratoryReportListRequest.newBuilder()
                                .setClinicSeq(record.getRegId())
                                .build();
                        getLaboratoryReportListResponse = nfyyServiceBlockingStub.getLaboratoryReportList(getLaboratoryReportListRequest);

                        if (getLaboratoryReportListResponse.getCode() == 0) {
                            for (com.ywt.gapi.nfyy.LaboratoryReport report : getLaboratoryReportListResponse.getReportList()) {
                                int count = laboratoryReportRepository.count(report.getInspectionId(), medicalCard.getUserId());
//
                                if (count > 0) {
                                    continue;
                                }

                                laboratoryReport = new com.ywt.outpatient.domain.entity.center.LaboratoryReport();
                                laboratoryReport.setId(idGenerator.genLaboratoryReportId());
                                laboratoryReport.setCreateTime(new Date());
                                laboratoryReport.setDeleted(false);
                                laboratoryReport.setUserId(medicalCard.getUserId());
                                laboratoryReport.setInspectionId(report.getInspectionId());
                                laboratoryReport.setInspectionName(report.getInspectionName());
                                laboratoryReport.setInspectionDate(DateUtil.stringToDate(report.getInspectionDate()));
                                laboratoryReport.setStatus(report.getStatus());
                                laboratoryReport.setPatientName(report.getPatientName());
                                laboratoryReport.setPatientAge(report.getPatientAge());
                                laboratoryReport.setSex(report.getGender());
                                laboratoryReport.setDeptName(report.getDeptName());
                                laboratoryReport.setClinicalDiagnosis(report.getClinicalDiagnosis());
                                laboratoryReport.setCheckDoctorName(report.getCheckDoctorName());
                                laboratoryReport.setReportDoctorName(report.getReportDoctorName());
                                laboratoryReport.setClinicSeq(report.getClinicSeq());
                                laboratoryReport.setInpatientId(report.getInpatientId());
                                laboratoryReport.setHisPatientId(record.getPatientId());

                                laboratoryReportRepository.save(laboratoryReport);

                                syncLaboratoryReportDetail(report.getInspectionId(), medicalCard.getUserId(), laboratoryReport.getId());
                            }
                        }
                    }

                    logger.info("MedicalCardID: " + medicalCard.getId());
                }
            } catch (Exception e) {
                logger.error("syncReport({}): {}", medicalCard.getId(), e.getMessage(), e);
            }
        }

        logger.info("END");
    }

    public void syncLaboratoryReportDetail(String inspectionId, int userId, int reportId) {
        int count = laboratoryDetailRepository.count(inspectionId);

        if (count > 0) {
            logger.info(reportId + " exist");
            return;
        }

        GetLaboratoryReportDetailRequest req = GetLaboratoryReportDetailRequest.newBuilder()
                .setInspectionId(inspectionId)
                .build();
        GetLaboratoryReportDetailResponse res = nfyyServiceBlockingStub.getLaboratoryReportDetail(req);

        if (res.getCode() == 0) {
            for (LaboratoryReportDetail detail : res.getDetailList()) {
                com.ywt.outpatient.domain.entity.center.LaboratoryDetail laboratoryDetail = new com.ywt.outpatient.domain.entity.center.LaboratoryDetail();
                laboratoryDetail.setId(idGenerator.genLaboratoryDetailId());
                laboratoryDetail.setCreateTime(new Date());
                laboratoryDetail.setDeleted(false);
                laboratoryDetail.setUserId(userId);
                laboratoryDetail.setInspectionId(inspectionId);
                laboratoryDetail.setLaboratoryReportId(reportId);
                laboratoryDetail.setItemId(detail.getItemId());
                laboratoryDetail.setItemName(detail.getItemName());
                laboratoryDetail.setOrderNo(detail.getOrderNo());
                laboratoryDetail.setTestResult(detail.getTestResult());
                laboratoryDetail.setUnit(detail.getUnit());
                laboratoryDetail.setItemRef(detail.getItemRef());
                laboratoryDetail.setTestDate(DateUtil.stringToDate(detail.getTestDate()));
                laboratoryDetail.setTestEngName(detail.getTestEngName());
                laboratoryDetail.setSpecimType(detail.getSpecimType());
                laboratoryDetail.setResultFlag(detail.getResultFlag());

                laboratoryDetailRepository.save(laboratoryDetail);
            }
        }

        logger.info(reportId + "");
    }

    public void syncInspectionReport(String hisPatientId, int userId, com.ywt.gapi.nfyy.InspectionReport report) {
        try {
            int count = inspectionReportRepository.count(report.getReportId(), userId);

            if (count > 0) {
                return;
            }

            com.ywt.outpatient.domain.entity.center.InspectionReport inspectionReport = new com.ywt.outpatient.domain.entity.center.InspectionReport();
            inspectionReport.setId(idGenerator.genInspectionReportId());
            inspectionReport.setCreateTime(new Date());
            inspectionReport.setDeleted(false);
            inspectionReport.setUserId(userId);
            inspectionReport.setReportId(report.getReportId());
            inspectionReport.setReportTitle(report.getReportTitle());
            inspectionReport.setStatus(report.getStatus());
            inspectionReport.setPatientName(report.getPatientName());
            inspectionReport.setPatientAge(report.getPatientAge());
            inspectionReport.setSex(report.getSex());
            inspectionReport.setClinicalDiagnosis(report.getClinicalDiagnosis());
            inspectionReport.setClinicSeq(report.getClinicSeq());
            inspectionReport.setInpatientId(report.getInpatientId());
            inspectionReport.setHisPatientId(hisPatientId);

            if (report.getReportDate().length() == 10) {
                inspectionReport.setReportDate(DateUtil.stringToDate(report.getReportDate(), "yyyy-MM-dd"));
            } else {
                inspectionReport.setReportDate(DateUtil.stringToDate(report.getReportDate()));
            }

            inspectionReportRepository.save(inspectionReport);

            //同步详情
            syncInspectionReportDetail(report.getReportId(), userId, inspectionReport.getId());
        } catch (Exception e) {
            logger.error("syncInspectionReport({}): {}", report.getReportId(), e.getMessage(), e);
        }
    }

    public void syncInspectionReportDetail(String reportId, int userId, int inspectionReportId) {
        try {
            int count = inspectionDetailRepository.getDetailCount(reportId, userId);

            if (count > 0) {
                return;
            }

            GetInspectionReportDetailRequest req = GetInspectionReportDetailRequest.newBuilder()
                    .setReportId(reportId)
                    .build();
            GetInspectionReportDetailResponse res = nfyyServiceBlockingStub.getInspectionReportDetail(req);

            if (res.getCode() == 0) {
                com.ywt.outpatient.domain.entity.center.InspectionDetail inspectionDetail;

                for (InspectionReportDetail detail : res.getDetailList()) {
                    inspectionDetail = new com.ywt.outpatient.domain.entity.center.InspectionDetail();
                    inspectionDetail.setId(idGenerator.genInspectionDetailId());
                    inspectionDetail.setCreateTime(new Date());
                    inspectionDetail.setDeleted(false);
                    inspectionDetail.setUserId(userId);
                    inspectionDetail.setInspectionReportId(inspectionReportId);
                    inspectionDetail.setReportId(reportId);
                    inspectionDetail.setDeptName(detail.getDeptName());
                    inspectionDetail.setReportDoctorName(detail.getReportDoctorName());
                    inspectionDetail.setCheckParts(detail.getCheckParts());
                    inspectionDetail.setExamination(detail.getExamination());
                    inspectionDetail.setDiagnosis(detail.getDiagnosis());
                    inspectionDetail.setCheckDoctorName(detail.getCheckDoctorName());
                    inspectionDetail.setExaminationDate(DateUtil.stringToDate(detail.getExaminationDate()));
                    inspectionDetail.setVerifyDate(DateUtil.stringToDate(detail.getVerifyDate()));
                    inspectionDetail.setAppDocName(detail.getAppDocName());
                    inspectionDetail.setVerifyDocName(detail.getVerifyDocName());

                    inspectionDetailRepository.save(inspectionDetail);
                }

                logger.info("syncInspectionReportDetail()SUCCEED: {}", res.getMsg());
            } else {
                logger.info("syncInspectionReportDetail({}, {}, {})FAILED: {}", reportId, userId, inspectionReportId, res.getMsg());
            }
        } catch (Exception e) {
            logger.error("syncInspectionReportDetail({}, {}, {}): {}", reportId, userId, inspectionReportId, e.getMessage(), e);
        }
    }

    /*==========================================================================================================*/

    /**
     * 同步南方医院检验检查报告
     *
     * @param hisPatientId
     * @param endDate
     */
    public void syncNfyyReport(String hisPatientId, String startDate, String endDate) {
        GetRegisteredRecordListResponse res = nfyyProvider.getRegisteredRecordList(hisPatientId, startDate, endDate);

        if (res.getCode() == ResultCode.SUCCEED_VALUE) {
            for (RegisteredRecord record : res.getRecordList()) {
                syncNfyyInspectionReport(record.getPatientId(), record.getRegId());
                syncNfyyLaboratoryReport(record.getPatientId(), record.getRegId());
            }
        }
    }

    /**
     * 同步南方医院检查报告
     *
     * @param hisPatientId
     * @param clinicCode
     */
    public void syncNfyyInspectionReport(String hisPatientId, String clinicCode) {
        GetInspectionReportListResponse res = nfyyProvider.getInspectionReportList(clinicCode);

        if (res.getCode() != ResultCode.SUCCEED_VALUE) {
            return;
        }

        int reportCount;
        int detailCount;
        com.ywt.outpatient.domain.entity.center.InspectionReport inspectionReport;
        com.ywt.outpatient.domain.entity.center.InspectionDetail inspectionDetail;
        GetInspectionReportDetailResponse detailResponse;

        for (InspectionReport report : res.getInspectionReportList()) {
            if (report.getStatus() != 1) {
                //未审核的检查报告不入库
                continue;
            }

            reportCount = inspectionReportRepository.getCountNfyy(hisPatientId, report.getReportId());
            if (reportCount > 0) {
                continue;
            }

            inspectionReport = new com.ywt.outpatient.domain.entity.center.InspectionReport();
            inspectionReport.setId(idGenerator.genInspectionReportId());
            inspectionReport.setCreateTime(new Date());
            inspectionReport.setDeleted(false);
            inspectionReport.setUserId(0);
            inspectionReport.setReportId(report.getReportId());
            inspectionReport.setReportTitle(report.getReportTitle());
            inspectionReport.setStatus(1);
            inspectionReport.setPatientName(report.getPatientName());
            inspectionReport.setPatientAge(report.getPatientAge());
            inspectionReport.setSex(report.getSex());
            inspectionReport.setClinicalDiagnosis(report.getClinicalDiagnosis());
            inspectionReport.setClinicSeq(report.getClinicSeq());
            inspectionReport.setInpatientId(report.getInpatientId());
            inspectionReport.setHisPatientId(hisPatientId);
            inspectionReport.setHospitalId(Constants.NFYY_HOSPITAL_ID);

            if (report.getReportDate().length() == 19) {
                inspectionReport.setReportDate(DateUtil.stringToDate(report.getReportDate()));
            } else {
                inspectionReport.setReportDate(DateUtil.stringToDate(report.getReportDate(), "yyyy-MM-dd"));
            }

            inspectionReportRepository.save(inspectionReport);

            detailCount = inspectionDetailRepository.getCountNfyy(report.getReportId(), hisPatientId);
            if (detailCount > 0) {
                continue;
            }

            detailResponse = nfyyProvider.getInspectionReportDetail(report.getReportId());

            if (detailResponse.getCode() != ResultCode.SUCCEED_VALUE) {
                continue;
            }

            for (InspectionReportDetail detail : detailResponse.getDetailList()) {
                inspectionDetail = new com.ywt.outpatient.domain.entity.center.InspectionDetail();
                inspectionDetail.setId(idGenerator.genInspectionDetailId());
                inspectionDetail.setCreateTime(new Date());
                inspectionDetail.setDeleted(false);
                inspectionDetail.setUserId(0);
                inspectionDetail.setInspectionReportId(inspectionReport.getId());
                inspectionDetail.setReportId(report.getReportId());
                inspectionDetail.setDeptName(detail.getDeptName());
                inspectionDetail.setReportDoctorName(detail.getReportDoctorName());
                inspectionDetail.setCheckParts(detail.getCheckParts());
                inspectionDetail.setExamination(detail.getExamination());
                inspectionDetail.setDiagnosis(detail.getDiagnosis());
                inspectionDetail.setCheckDoctorName(detail.getCheckDoctorName());
                inspectionDetail.setExaminationDate(DateUtil.stringToDate(detail.getExaminationDate()));
                inspectionDetail.setVerifyDate(DateUtil.stringToDate(detail.getVerifyDate()));
                inspectionDetail.setAppDocName(detail.getAppDocName());
                inspectionDetail.setVerifyDocName(detail.getVerifyDocName());
                inspectionDetail.setHospitalId(Constants.NFYY_HOSPITAL_ID);
                inspectionDetail.setHisPatientId(hisPatientId);

                inspectionDetailRepository.save(inspectionDetail);
            }
        }
    }

    /**
     * 同步南方医院检验报告
     *
     * @param hisPatientId
     * @param clinicCode
     */
    public void syncNfyyLaboratoryReport(String hisPatientId, String clinicCode) {
        GetLaboratoryReportListResponse res = nfyyProvider.getLaboratoryReportList(clinicCode);

        if (res.getCode() != ResultCode.SUCCEED_VALUE) {
            return;
        }

        int reportCount;
        int detailCount;
        com.ywt.outpatient.domain.entity.center.LaboratoryReport laboratoryReport;
        com.ywt.outpatient.domain.entity.center.LaboratoryDetail laboratoryDetail;
        GetLaboratoryReportDetailResponse detailResponse;

        for (LaboratoryReport report : res.getReportList()) {
            reportCount = laboratoryReportRepository.getCountNfyy(hisPatientId, report.getInspectionId());

            if (reportCount > 0) {
                continue;
            }

            laboratoryReport = new com.ywt.outpatient.domain.entity.center.LaboratoryReport();
            laboratoryReport.setId(idGenerator.genLaboratoryReportId());
            laboratoryReport.setCreateTime(new Date());
            laboratoryReport.setDeleted(false);
            laboratoryReport.setUserId(0);
            laboratoryReport.setInspectionId(report.getInspectionId());
            laboratoryReport.setInspectionName(report.getInspectionName());
            laboratoryReport.setInspectionDate(DateUtil.stringToDate(report.getInspectionDate()));
            laboratoryReport.setStatus(report.getStatus());
            laboratoryReport.setPatientName(report.getPatientName());
            laboratoryReport.setPatientAge(report.getPatientAge());
            laboratoryReport.setSex(report.getGender());
            laboratoryReport.setDeptName(report.getDeptName());
            laboratoryReport.setClinicalDiagnosis(report.getClinicalDiagnosis());
            laboratoryReport.setCheckDoctorName(report.getCheckDoctorName());
            laboratoryReport.setReportDoctorName(report.getReportDoctorName());
            laboratoryReport.setClinicSeq(report.getClinicSeq());
            laboratoryReport.setInpatientId(report.getInpatientId());
            laboratoryReport.setHisPatientId(hisPatientId);
            laboratoryReport.setHospitalId(Constants.NFYY_HOSPITAL_ID);

            laboratoryReportRepository.save(laboratoryReport);

            detailCount = laboratoryDetailRepository.getCount(hisPatientId, laboratoryReport.getInspectionId(), Constants.NFYY_HOSPITAL_ID);

            if (detailCount > 0) {
                continue;
            }

            detailResponse = nfyyProvider.getLaboratoryReportDetail(report.getInspectionId());
            if (detailResponse.getCode() == 0) {
                for (LaboratoryReportDetail detail : detailResponse.getDetailList()) {
                    laboratoryDetail = new com.ywt.outpatient.domain.entity.center.LaboratoryDetail();
                    laboratoryDetail.setId(idGenerator.genLaboratoryDetailId());
                    laboratoryDetail.setCreateTime(new Date());
                    laboratoryDetail.setDeleted(false);
                    laboratoryDetail.setUserId(0);
                    laboratoryDetail.setInspectionId(report.getInspectionId());
                    laboratoryDetail.setLaboratoryReportId(laboratoryReport.getId());
                    laboratoryDetail.setItemId(detail.getItemId());
                    laboratoryDetail.setItemName(detail.getItemName());
                    laboratoryDetail.setOrderNo(detail.getOrderNo());
                    laboratoryDetail.setTestResult(detail.getTestResult());
                    laboratoryDetail.setUnit(detail.getUnit());
                    laboratoryDetail.setItemRef(detail.getItemRef());
                    laboratoryDetail.setTestDate(DateUtil.stringToDate(detail.getTestDate()));
                    laboratoryDetail.setTestEngName(detail.getTestEngName());
                    laboratoryDetail.setSpecimType(detail.getSpecimType());
                    laboratoryDetail.setResultFlag(detail.getResultFlag());
                    laboratoryDetail.setHisPatientId(hisPatientId);
                    laboratoryDetail.setHospitalId(Constants.NFYY_HOSPITAL_ID);

                    laboratoryDetailRepository.save(laboratoryDetail);
                }
            }

        }
    }


    /**
     * 同步太和医院检验检查结果
     *
     * @param hisPatientId
     * @param cardNo
     * @param endDate
     */
    public void syncTaiheReport(String hisPatientId, String cardNo, String startDate, String endDate, int hospitalId) {
        final boolean notify = false;
        GetRegistrationListResponse res = taiheProvider.getRegistrationList(hisPatientId, cardNo, startDate, endDate, hospitalId);

        if (res.getCode() == ResultCode.SUCCEED_VALUE) {
            for (com.ywt.gapi.third.taihe.Registration registration : res.getRegistrationList()) {
                syncTaiheInspectionReport(hisPatientId, registration.getRegistrationId(), notify, hospitalId);
                syncTaiheLaboratoryReport(hisPatientId, registration.getRegistrationId(), notify, hospitalId);
            }
        }
    }

    /**
     * 同步太和医院检查结果
     *
     * @param hisPatientId
     * @param clinicCode
     * @param notify
     */
    public void syncTaiheInspectionReport(String hisPatientId, String clinicCode, boolean notify, Integer hospitalId) {
        try {
            // 默认太和医院，兼容旧的接口
            int hid = Checker.getIntegerValue(hospitalId) > 0 ? hospitalId : Constants.TAIHE_HOSPITAL_ID;
            GetInspectionListRequest req = GetInspectionListRequest.newBuilder()
                    .setRegistrationId(clinicCode)
                    .setPatientId(hisPatientId)
                    .setHospitalId(hid)
                    .build();
            GetInspectionListResponse res = taiheServiceBlockingStub.getInspectionList(req);

            if (res.getCode() != ResultCode.SUCCEED_VALUE) {
                return;
            }

            int reportCount = 0;
            int detailCount = 0;
            com.ywt.outpatient.domain.entity.center.InspectionReport inspectionReport = null;
            GetInspectionDetailRequest detailRequest = null;
            GetInspectionDetailResponse detailResponse = null;
            com.ywt.outpatient.domain.entity.center.InspectionDetail inspectionDetail;

            for (com.ywt.gapi.third.taihe.InspectionReport report : res.getInspectionReportList()) {
                if ("1899-12-30 00:00:00".equals(report.getAuditDate())) {
                    //未审核的检查报告不入库
                    continue;
                }

                reportCount = inspectionReportRepository.getCountTaihe(hisPatientId, report.getReportId(), hid);
                if (reportCount > 0) {
                    logger.info("hisPatientId: {}, clinicCode: {}, taihe inspection report already exist.", hisPatientId, clinicCode);
                    continue;
                }

                inspectionReport = new com.ywt.outpatient.domain.entity.center.InspectionReport();
                inspectionReport.setId(idGenerator.genInspectionReportId());
                inspectionReport.setCreateTime(new Date());
                inspectionReport.setDeleted(false);
                inspectionReport.setUserId(0);
                inspectionReport.setReportId(report.getReportId());
                inspectionReport.setReportTitle(report.getReportTitle());
                inspectionReport.setStatus(1);
                inspectionReport.setPatientName(report.getPatientName());
                inspectionReport.setPatientAge(String.valueOf(report.getPatientAge()));
                inspectionReport.setSex(report.getPatientSex());
                inspectionReport.setClinicalDiagnosis(report.getDiagnose());
                inspectionReport.setClinicSeq(clinicCode);
                inspectionReport.setInpatientId("");
                inspectionReport.setHisPatientId(hisPatientId);
                inspectionReport.setHospitalId(hid);
                inspectionReport.setReportDate(DateUtil.stringToDate(report.getAuditDate()));
                inspectionReport.setReportType(report.getReportType());
                inspectionReport.setReportNum(report.getReportNum());

                inspectionReportRepository.save(inspectionReport);

                detailCount = inspectionDetailRepository.getCountTaihe(report.getReportId(), hisPatientId, hid);
                if (detailCount > 0) {
                    continue;
                }

                detailRequest = GetInspectionDetailRequest.newBuilder()
                        .setReportId(inspectionReport.getReportId())
                        .setHospitalId(hid)
                        .build();
                detailResponse = taiheServiceBlockingStub.getInspectionDetail(detailRequest);

                if (res.getCode() == 0) {
                    com.ywt.gapi.third.taihe.InspectionDetail detail = detailResponse.getDetail();

                    inspectionDetail = new com.ywt.outpatient.domain.entity.center.InspectionDetail();
                    inspectionDetail.setId(idGenerator.genInspectionDetailId());
                    inspectionDetail.setCreateTime(new Date());
                    inspectionDetail.setDeleted(false);
                    inspectionDetail.setUserId(0);
                    inspectionDetail.setInspectionReportId(inspectionReport.getId());
                    inspectionDetail.setReportId(inspectionReport.getReportId());
                    inspectionDetail.setDeptName(detail.getDeptName());
                    inspectionDetail.setReportDoctorName(detail.getDoctorName());
                    inspectionDetail.setCheckParts(detail.getInspectionPart());
                    inspectionDetail.setExamination(detail.getInspectionResult());
                    inspectionDetail.setDiagnosis(detail.getDiagnose());
                    inspectionDetail.setCheckDoctorName(detail.getInspectionDoctor());
                    inspectionDetail.setExaminationDate(DateUtil.stringToDate(detail.getInspectionDate()));
                    inspectionDetail.setVerifyDate(DateUtil.stringToDate(detail.getAuditDate()));
                    inspectionDetail.setAppDocName(detail.getSubmitDoctor());
                    inspectionDetail.setVerifyDocName(detail.getAuditor());

                    inspectionDetailRepository.save(inspectionDetail);
                }

                if (notify) {
                    //生成检查报告提醒
                    List<MedicalCard> lst = medicalCardRepository.getMedicalCardListByPatientId(hid, hisPatientId);
                    if (lst != null && lst.size() > 0) {
                        String reportDate = inspectionReport.getReportDate() == null ? "" : DateUtil.convertToString(inspectionReport.getReportDate());
                        for (MedicalCard medicalCard : lst) {
                            String url = String.format("%s/nfthwe/checkResult/checkDetail/%s?medicalCardId=%d&reportNum=%s&reportDate=%s&reportType=%s&hid=%d&mode=pic",
                                    bizConfigurer.getYwtHttpsMsiteDomain(), inspectionReport.getReportId(), Checker.getIntegerValue(medicalCard.getId()),
                                    Checker.getStringValue(inspectionReport.getReportNum()), reportDate,
                                    Checker.getStringValue(inspectionReport.getReportType()), hid);
                            String miniProgram = String.format("th/checkResult?reportId=%s&cardId=%d&reportNum=%s&reportDate=%s&reportType=%s&hospitalId=%d",
                                    inspectionReport.getReportId(), Checker.getIntegerValue(medicalCard.getId()),
                                    Checker.getStringValue(inspectionReport.getReportNum()), reportDate,
                                    Checker.getStringValue(inspectionReport.getReportType()), hid);
                            wxProvider.notifyInspectionTaihe(
                                    medicalCard.getUserId(), medicalCard.getPatientName(), inspectionReport.getReportTitle(),
                                    inspectionReport.getReportDate(), url, hid, miniProgram);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("syncTaiheInspectionReport({}, {}): {}", hisPatientId, clinicCode, e.getMessage(), e);
        }
    }

    /**
     * 同步太和医院检验结果
     *
     * @param hisPatientId
     * @param clinicCode
     */
    public void syncTaiheLaboratoryReport(String hisPatientId, String clinicCode, boolean notify, Integer hospitalId) {
        try {
            // 默认太和医院，兼容旧的接口
            int hid = Checker.getIntegerValue(hospitalId) > 0 ? hospitalId : Constants.TAIHE_HOSPITAL_ID;
            GetLaboratoryListRequest req = GetLaboratoryListRequest.newBuilder()
                    .setRegistrationId(clinicCode)
                    .setPatientId(hisPatientId)
                    .setHospitalId(hid)
                    .build();
            GetLaboratoryListResponse res = taiheServiceBlockingStub.getLaboratoryList(req);

            com.ywt.outpatient.domain.entity.center.LaboratoryReport laboratoryReport = null;
            GetLaboratoryDetailRequest detailRequest = null;
            GetLaboratoryDetailResponse detailResponse = null;
            com.ywt.outpatient.domain.entity.center.LaboratoryDetail laboratoryDetail;
            String pattern;
            int reportCount = 0;
            int detailCount = 0;

            for (com.ywt.gapi.third.taihe.LaboratoryReport report : res.getReportList()) {
                reportCount = laboratoryReportRepository.getCountTaihe(hisPatientId, report.getReportId(), hid);

                if (reportCount > 0) {
                    logger.info("hisPatientId: {}, reportId: {}, taihe laboratory report already exist.", hisPatientId, report.getReportId());
                    continue;
                }

                if (report.getAuditDate().length() == 19) {
                    pattern = "yyyy-MM-dd HH:mm:ss";
                } else {
                    pattern = "yyyy-MM-dd";
                }

                laboratoryReport = new com.ywt.outpatient.domain.entity.center.LaboratoryReport();
                laboratoryReport.setId(idGenerator.genLaboratoryReportId());
                laboratoryReport.setCreateTime(new Date());
                laboratoryReport.setDeleted(false);
                laboratoryReport.setUserId(0);
                laboratoryReport.setInspectionId(report.getReportId());
                laboratoryReport.setInspectionName(report.getReportTitle());
                laboratoryReport.setInspectionDate(DateUtil.stringToDate(report.getAuditDate(), pattern));
                laboratoryReport.setStatus(report.getStatus());
                laboratoryReport.setPatientName(report.getPatientName());
                laboratoryReport.setPatientAge(report.getPatientAge() + "");
                laboratoryReport.setSex(report.getPatientSex());
                laboratoryReport.setDeptName(report.getDeptName());
                laboratoryReport.setClinicalDiagnosis(report.getDiagnose());
                laboratoryReport.setCheckDoctorName(report.getAuditor());
                laboratoryReport.setReportDoctorName(report.getReportDoctor());
                laboratoryReport.setClinicSeq(report.getRegistrationId());
                laboratoryReport.setInpatientId("");
                laboratoryReport.setHisPatientId(hisPatientId);
                laboratoryReport.setHospitalId(hid);

                laboratoryReportRepository.save(laboratoryReport);

                detailCount = laboratoryDetailRepository.getCount(hisPatientId, laboratoryReport.getInspectionId(), hid);

                if (detailCount > 0) {
                    continue;
                }

                detailRequest = GetLaboratoryDetailRequest.newBuilder()
                        .setInspectionId(laboratoryReport.getInspectionId())
                        .setHospitalId(hid)
                        .build();
                detailResponse = taiheServiceBlockingStub.getLaboratoryDetail(detailRequest);

                if (detailResponse.getCode() == 0) {
                    for (com.ywt.gapi.third.taihe.LaboratoryDetail detail : detailResponse.getDetailList()) {
                        laboratoryDetail = new com.ywt.outpatient.domain.entity.center.LaboratoryDetail();
                        laboratoryDetail.setId(idGenerator.genLaboratoryDetailId());
                        laboratoryDetail.setCreateTime(new Date());
                        laboratoryDetail.setDeleted(false);
                        laboratoryDetail.setUserId(0);
                        laboratoryDetail.setInspectionId(laboratoryReport.getInspectionId());
                        laboratoryDetail.setLaboratoryReportId(laboratoryReport.getId());
                        laboratoryDetail.setItemId(detail.getItemId());
                        laboratoryDetail.setItemName(detail.getItemName());
                        laboratoryDetail.setOrderNo(detail.getOrderNo() + "");
                        laboratoryDetail.setTestResult(detail.getTestResult());
                        laboratoryDetail.setUnit(detail.getUnit());
                        laboratoryDetail.setItemRef(detail.getItemRef());
                        laboratoryDetail.setTestDate(DateUtil.stringToDate(detail.getTestDate()));
                        laboratoryDetail.setTestEngName(detail.getTestEngName());
                        laboratoryDetail.setSpecimType(detail.getSpecimType());
                        laboratoryDetail.setResultFlag(detail.getResultFlag() == 1 ? "H" : detail.getResultFlag() == 2 ? "L" : "");
                        laboratoryDetail.setHospitalId(hid);
                        laboratoryDetail.setHisPatientId(hisPatientId);

                        laboratoryDetailRepository.save(laboratoryDetail);
                    }
                }

                if (notify) {
                    //生成检验报告提醒
                    List<MedicalCard> lst = medicalCardRepository.getMedicalCardListByPatientId(hid, hisPatientId);
                    if (lst != null && lst.size() > 0) {
                        String url = String.format("%s/nfthwe/checkResult/detail/%s?hid=%d",
                                bizConfigurer.getYwtHttpsMsiteDomain(), laboratoryReport.getInspectionId(), hid);
                        String miniProgram = String.format("th/checkTestResult?inspectionId=%s&hospitalId=%d",
                                laboratoryReport.getInspectionId(), hid);
                        for (MedicalCard medicalCard : lst) {
                            wxProvider.notifyInspectionTaihe(
                                    medicalCard.getUserId(), medicalCard.getPatientName(), laboratoryReport.getInspectionName(),
                                    laboratoryReport.getInspectionDate(), url, hid, miniProgram);
                        }
                    }
                }
            }

        } catch (Exception e) {
            logger.error("syncTaiheLaboratoryReport({}, {}): {}", hisPatientId, clinicCode, e.getMessage(), e);
        }
    }

    public void syncTaiheReport(int minId, int maxId) {
        List<OutpatientOrder> outpatientOrderList = outpatientOrderRepository.getList(minId, maxId);

        if (outpatientOrderList == null || outpatientOrderList.size() == 0) {
            logger.info("outpatientOrderList is null or empty.");
            return;
        }

        final boolean notify = false;

        for (OutpatientOrder outpatientOrder : outpatientOrderList) {
            syncTaiheInspectionReport(outpatientOrder.getHisPatientId(), outpatientOrder.getHisClinicCode(), notify,
                    outpatientOrder.getHospitalId());
            syncTaiheLaboratoryReport(outpatientOrder.getHisPatientId(), outpatientOrder.getHisClinicCode(), notify,
                    outpatientOrder.getHospitalId());
        }
    }

    public void syncTaiheMedicalRecord(int minId, int maxId) {
        List<OutpatientOrder> outpatientOrderList = outpatientOrderRepository.getList(minId, maxId);

        if (outpatientOrderList == null || outpatientOrderList.size() == 0) {
            logger.info("outpatientOrderList is null or empty.");
            return;
        }

        for (OutpatientOrder outpatientOrder : outpatientOrderList) {
            try {
                syncTaiheMedicalRecord(outpatientOrder.getHisPatientId(), Checker.parseInt(outpatientOrder.getHisClinicCode()), 0, outpatientOrder);
            } catch (Exception e) {
                logger.error("syncTaiheMedicalRecord(): {}", e.getMessage(), e);
            }
        }
    }

    public void syncTaiheMedicalRecord(String hisPatientId, int registrationId, int userId, OutpatientOrder outpatientOrder) {
        int hospitalId = Checker.getIntegerValue(outpatientOrder.getHospitalId());
        int hid = hospitalId > 0 ? hospitalId : Constants.TAIHE_HOSPITAL_ID;
        String clinicCode = String.valueOf(registrationId);
        int count = medicalRecordsRepository.getTaiheOutpatientCount(hisPatientId, clinicCode, hid);

        if (count > 0) {
            logger.info("hisPatientId: {}, registrationId: {}, medical record already exist.",
                    hisPatientId, registrationId);
            return;
        }

        GetMedicalRecordResponse res = taiheProvider.getMedicalRecord(hisPatientId, registrationId, hid);
        if (res.getCode() != ResultCode.SUCCEED_VALUE) {
            logger.info("hisPatientId: {}, registrationId: {}, medical record: {}",
                    hisPatientId, registrationId, res.getMsg());
            return;
        }

        MedicalRecord hisRecord = res.getMedicalRecord();
        MedicalRecord.PatInfo patInfo = hisRecord.getPatInfo();

        MedicalRecords medicalRecord = new MedicalRecords();
        medicalRecord.setId(idGenerator.genMedicalRecordsId());
        medicalRecord.setUserId(userId);
        medicalRecord.setDoctorId(0);
        medicalRecord.setType(MedicalRecordsTypeEnum.OutpatientService.getValue());
        medicalRecord.setCreateTime(new Date());
        medicalRecord.setDeleted(false);
        medicalRecord.setClinicCode(clinicCode);
        medicalRecord.setHospitalId(hid);
        medicalRecord.setHospitalName(BizUtil.getHospitalNameByIdSimply(hid));
        medicalRecord.setMedicalCardId(0);
        medicalRecord.setDoctorTitle("");

        if (StringHelper.isNullOrWhiteSpace(patInfo.getPatName())) {
            medicalRecord.setPatientName(outpatientOrder.getPatientName());
            medicalRecord.setSex(outpatientOrder.getPatientSex());
            medicalRecord.setAge((outpatientOrder.getPatientAge() > 0 ? outpatientOrder.getPatientAge() : 0));
            medicalRecord.setMobile(patInfo.getPhoneNumber());

        } else {

            if (patInfo != null) {
                medicalRecord.setPatientName(patInfo.getPatName());
                medicalRecord.setSex(patInfo.getSex());
                medicalRecord.setAge(patInfo.getAge());
                medicalRecord.setMobile(patInfo.getPhoneNumber());

                //地址、民族
            }
        }


        medicalRecord.setAdvice(hisRecord.getDoctorAdvice());
        medicalRecord.setDeptName(hisRecord.getDeptName());
        medicalRecord.setDoctorName(hisRecord.getDoctorName());
        medicalRecord.setDiagnosis(hisRecord.getDiagnose());
        medicalRecord.setAdmTime(hisRecord.getCheckInTime());
        medicalRecord.setChiefComplaint(hisRecord.getChiefComplaint());
        medicalRecord.setPhyExam(hisRecord.getPhysicalExam());
        medicalRecord.setSuggestion(hisRecord.getSuggestion());
        medicalRecord.setHisPatientId(hisPatientId);

        medicalRecordsRepository.save(medicalRecord);

        logger.info("hisPatientId: {}, registrationId: {}, SUCCEED.",
                hisPatientId, registrationId);
    }



    public void syncScheduleForShowDept(Department department) {


        //每个科室都要查询8天的数据，如果查询到数据就标识科室有出诊，跳出，查询下一个科室
        try {
            Calendar calendar = Calendar.getInstance();
            Calendar currentCalendar = Calendar.getInstance();
            String strCurrentDate = DateUtil.formatDate(currentCalendar.getTime(), "yyyy-MM-dd");

            for (int offset = 0; offset < 8; offset++) {
                if (offset > 0) {
                    calendar.add(Calendar.DATE, 1);
                }

                String strDate = DateUtil.formatDate(calendar.getTime(), "yyyy-MM-dd"); //日期

                GetScheduleListRequest req = GetScheduleListRequest.newBuilder()
                        .setDeptCode(department.getCode())
                        .setServiceDate(strDate)
                        .setDoctorCode("")
                        .setHospitalId(department.getHospitalId())
                        .build();

                GetScheduleListResponse res = taiheServiceBlockingStub.getScheduleList(req);

                if(res.getSchedulesList().size()>0) {
                    department.setDeleted(false);
                    departmentRepository.save(department);
                    break;
                }
                else
                {
                    department.setDeleted(true);
                    departmentRepository.save(department);
                }

            }


        } catch (Exception e) {
            logger.error("syncScheduleForShowDept(){}", e.getMessage());
        }
    }
}
