package com.ywt.outpatient.rpc.provider;

import com.ywt.biz.common.util.Checker;
import com.ywt.biz.common.util.DateUtil;
import com.ywt.gapi.Result;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.medicalrecord.InspectionReport;
import com.ywt.gapi.medicalrecord.LaboratoryReport;
import com.ywt.gapi.medicalrecord.*;
import com.ywt.outpatient.core.PagedList;
import com.ywt.outpatient.domain.entity.center.*;
import com.ywt.outpatient.core.Constants;
import com.ywt.outpatient.domain.models.enums.MedicalCardStatusEnum;
import com.ywt.outpatient.domain.models.enums.MedicalRecordsTypeEnum;
import com.ywt.outpatient.service.rpc.DataService;
import com.ywt.outpatient.service.rpc.HisService;
import com.ywt.outpatient.service.rpc.MedicalRecordService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

@DubboService
public class MedicalRecordProvider extends DubboMedicalRecordServiceTriple.MedicalRecordServiceImplBase {
    private static Logger logger = LoggerFactory.getLogger(MedicalRecordProvider.class);

    @Autowired
    private MedicalRecordsRepository medicalRecordsRepository;

    @Autowired
    private LaboratoryReportRepository laboratoryReportRepository;

    @Autowired
    private InspectionReportRepository inspectionReportRepository;

    @Autowired
    private MedicalCardRepository medicalCardRepository;

    @Autowired
    private MedicalRecordService medicalRecordService;

    @Autowired
    private DataService dataService;

    @Autowired
    private MedicalModuleRepository medicalModuleRepository;

    @Autowired
    private HisService hisService;


    /**
     * 获取病历详情
     */
    @Override
    public GetMedicalRecordByIdResponse getMedicalRecordById(GetMedicalRecordByIdRequest request) {
        Result.Builder resultBuilder = Result.newBuilder();
        GetMedicalRecordByIdResponse.Builder builder = GetMedicalRecordByIdResponse.newBuilder();

        try {
            MedicalRecords medicalRecord = medicalRecordsRepository.findById(request.getRecordId()).orElse(null);

            if (medicalRecord != null && !medicalRecord.getDeleted()) {
                List<LaboratoryReport> gLaboratoryList = new LinkedList<>();
                List<InspectionReport> gInspectionList = new LinkedList<>();
                List<com.ywt.outpatient.domain.entity.center.LaboratoryReport> laboratoryList = null;
                List<com.ywt.outpatient.domain.entity.center.InspectionReport> inspectionList = null;

                if (medicalRecord.getType() == MedicalRecordsTypeEnum.OutpatientService.getValue()) {
                    int hospitalId = Checker.getIntegerValue(medicalRecord.getHospitalId());
                    if (hospitalId == Constants.TAIHE_HOSPITAL_ID || hospitalId == Constants.NFYYBYFY_HOSPITAL_ID) {
                        //南方医院太和分院
                        laboratoryList = laboratoryReportRepository.getListTaihe(medicalRecord.getHisPatientId(),
                                medicalRecord.getClinicCode(), hospitalId);
                        inspectionList = inspectionReportRepository.getListTaihe(medicalRecord.getHisPatientId(),
                                medicalRecord.getClinicCode(), hospitalId);
                    } else {
                        //南方医院
                        laboratoryList = hisService.getLaboratoryReportListByHisClinicSeq(medicalRecord.getClinicCode());
                        inspectionList = hisService.getInspectionReportListByHisClinicSeq(medicalRecord.getClinicCode());
                    }
                }


                if (laboratoryList != null) {
                    for (com.ywt.outpatient.domain.entity.center.LaboratoryReport report : laboratoryList) {
                        com.ywt.gapi.medicalrecord.LaboratoryReport r = com.ywt.gapi.medicalrecord.LaboratoryReport.newBuilder()
                                .setId(report.getId())
                                .setClinicalDiagnosis(Checker.getStringValue(report.getClinicalDiagnosis()))
                                .setClinicSeq(Checker.getStringValue(report.getClinicSeq()))
                                .setInpatientId(Checker.getStringValue(report.getInpatientId()))
                                .setPatientAge(Checker.getStringValue(report.getPatientAge()))
                                .setPatientName(Checker.getStringValue(report.getPatientName()))
                                .setInspectionDate(report.getInspectionDate().getTime())
                                .setInspectionId(Checker.getStringValue(report.getInspectionId()))
                                .setInspectionName(Checker.getStringValue(report.getInspectionName()))
                                .setStatus(Checker.getIntegerValue(report.getStatus()))
                                .setSex(report.getSex())
                                .setDeptName(Checker.getStringValue(report.getDeptName()))
                                .setReportDoctorName(Checker.getStringValue(report.getReportDoctorName()))
                                .setCheckDoctorName(Checker.getStringValue(report.getCheckDoctorName()))
                                .build();
                        gLaboratoryList.add(r);
                    }
                }

                if (inspectionList != null) {
                    for (com.ywt.outpatient.domain.entity.center.InspectionReport report : inspectionList) {
                        com.ywt.gapi.medicalrecord.InspectionReport r = com.ywt.gapi.medicalrecord.InspectionReport.newBuilder()
                                .setId(report.getId())
                                .setClinicalDiagnosis(Checker.getStringValue(report.getClinicalDiagnosis()))
                                .setClinicSeq(Checker.getStringValue(report.getClinicSeq()))
                                .setInpatientId(Checker.getStringValue(report.getInpatientId()))
                                .setPatientAge(Checker.getStringValue(report.getPatientAge()))
                                .setPatientName(Checker.getStringValue(report.getPatientName()))
                                .setReportDate(report.getReportDate().getTime())
                                .setReportTitle(Checker.getStringValue(report.getReportTitle()))
                                .setStatus(Checker.getIntegerValue(report.getStatus()))
                                .setSex(report.getSex())
                                .setReportId(Checker.getStringValue(report.getReportId()))
                                .setHospitalId(Checker.getIntegerValue(report.getHospitalId()))
                                .setReportNum(Checker.getStringValue(report.getReportNum()))
                                .setReportType(Checker.getStringValue(report.getReportType()))
                                .build();
                        gInspectionList.add(r);
                    }
                }

                MedicalRecord record = MedicalRecord.newBuilder()
                        .setAdmTime(Checker.getStringValue(medicalRecord.getAdmTime()))
                        .setHospitalName(Checker.getStringValue(medicalRecord.getHospitalName()))
                        .setDoctorName(Checker.getStringValue(medicalRecord.getDoctorName()))
                        .setPatientName(Checker.getStringValue(medicalRecord.getPatientName()))
                        .setSelfReport(Checker.getStringValue(medicalRecord.getChiefComplaint()))
                        .setPhyExam(Checker.getStringValue(medicalRecord.getPhyExam()))
                        .setDiagnose(Checker.getStringValue(medicalRecord.getDiagnosis()))
                        .setSuggestion(Checker.getStringValue(medicalRecord.getSuggestion()))
                        .setAdvice(Checker.getStringValue(medicalRecord.getAdvice()))
                        .addAllLaboratoryReport(gLaboratoryList)
                        .addAllInspectionReport(gInspectionList)
                        .setHospitalId(medicalRecord.getHospitalId())
                        .build();

                resultBuilder.setCode(ResultCode.SUCCEED).setInfo("处理成功");
                builder.setResult(resultBuilder.build()).setMedicalRecord(record);
            } else {
                resultBuilder.setCode(ResultCode.PARAMETER_ERROR).setInfo("病历不存在");
                builder.setResult(resultBuilder.build());
            }
            return builder.build();
        } catch (Exception e) {
            logger.error("getMedicalRecordById(): {}", e.getMessage(), e);
            resultBuilder.setCode(ResultCode.APP_ERROR).setInfo(e.getMessage());
            return builder.build();
        }
    }

    /**
     * 获取门诊病历列表
     */
    @Override
    public GetOutpatientRecordListResponse getOutpatientRecordList(GetOutpatientRecordListRequest request) {
        Result.Builder resultBuilder = Result.newBuilder();
        GetOutpatientRecordListResponse.Builder builder = GetOutpatientRecordListResponse.newBuilder();

        try {
            MedicalCard card = medicalCardRepository.findById(request.getMedicalCardId()).orElse(null);

            if (card == null
                    || card.getStatus() != MedicalCardStatusEnum.NORMAL.getValue()
                    || card.getUserId() != request.getUserId()) {
                resultBuilder.setCode(ResultCode.APP_ERROR).setInfo("门诊病历不存在");
                builder.setResult(resultBuilder.build());
            } else {
                com.ywt.gapi.medicalrecord.MedicalRecord record;
                List<com.ywt.gapi.medicalrecord.MedicalRecord> lst = new LinkedList<>();
                PagedList<MedicalRecords> pagedList = medicalRecordService.getOutpatientRecordListNew(request.getPageIndex(),
                        request.getPageSize(), card.getHisPatientId(), Checker.getIntegerValue(card.getHospitalId()));

                if (pagedList.getItems() != null && pagedList.getItems().size() > 0) {
                    for (MedicalRecords medicalRecord : pagedList.getItems()) {
                        record = MedicalRecord.newBuilder()
                                .setRecordId(medicalRecord.getId())
                                .setAdmTime(Checker.getStringValue(medicalRecord.getAdmTime()))
                                .setHospitalName(Checker.getStringValue(medicalRecord.getHospitalName()))
                                .setDoctorName(Checker.getStringValue(medicalRecord.getDoctorName()))
                                .setPatientName(Checker.getStringValue(medicalRecord.getPatientName()))
                                .setSelfReport(Checker.getStringValue(medicalRecord.getChiefComplaint()))
                                .setPhyExam(Checker.getStringValue(medicalRecord.getPhyExam()))
                                .setDiagnose(Checker.getStringValue(medicalRecord.getDiagnosis()))
                                .setSuggestion(Checker.getStringValue(medicalRecord.getSuggestion()))
                                .setAdvice(Checker.getStringValue(medicalRecord.getAdvice()))
                                .setClinicCode(Checker.getStringValue(medicalRecord.getClinicCode()))
                                .build();
                        lst.add(record);
                    }
                }

                resultBuilder.setCode(ResultCode.SUCCEED);
                builder.setResult(resultBuilder.build()).addAllMedicalRecord(lst);
            }
            return builder.build();
        } catch (Exception e) {
            logger.error("getOutpatientRecordList(): {}", e.getMessage(), e);
            resultBuilder.setCode(ResultCode.APP_ERROR).setInfo(e.getMessage());
            builder.setResult(resultBuilder.build());
        }
        return builder.build();
    }

    /**
     * 同步检验检查结果
     */
    @Override
    public Result syncReport(SyncReportRequest request) {
        Result.Builder builder = Result.newBuilder();

        try {
            MedicalCard medicalCard = medicalCardRepository.findById(request.getMedicalCardId()).orElse(null);

            if (medicalCard == null || medicalCard.getStatus() != MedicalCardStatusEnum.NORMAL.getValue()) {
                builder.setCode(ResultCode.APP_ERROR).setInfo("诊疗卡不存在");
                return builder.build();
            }

            Calendar calendar = Calendar.getInstance();
            String endDate = DateUtil.convertToString(calendar.getTime(), "yyyy-MM-dd");
            Long startDateLong = request.getStartDate();
            String startDate = startDateLong == 0 ? "" : DateUtil.convertTimestampToDateString(startDateLong, "yyyy-MM-dd");
            int hospitalId = Checker.getIntegerValue(medicalCard.getHospitalId());
            if (hospitalId == Constants.TAIHE_HOSPITAL_ID || hospitalId == Constants.NFYYBYFY_HOSPITAL_ID) {
                //太和医院诊疗卡
                dataService.syncTaiheReport(medicalCard.getHisPatientId(), medicalCard.getCardNo(), startDate, endDate, hospitalId);
            } else {
                //南方医院诊疗卡
                dataService.syncNfyyReport(medicalCard.getHisPatientId(), startDate, endDate);
            }

            builder.setCode(ResultCode.SUCCEED).setInfo("同步成功");
            return builder.build();
        } catch (Exception e) {
            logger.error("syncReport({}): {}", request.getMedicalCardId(), e.getMessage(), e);
            builder.setCode(ResultCode.APP_ERROR).setInfo(e.getMessage());
            return builder.build();
        }
    }

    //获取门诊病历列表
    @Override
    public GetOutpatientRecordListByHisPatientIdResponse getOutpatientRecordListByHisPatientId(GetOutpatientRecordListByHisPatientIdRequest request) {
        try {
            com.ywt.gapi.medicalrecord.MedicalRecord record;
            List<com.ywt.gapi.medicalrecord.MedicalRecord> lst = new LinkedList<>();
            PagedList<MedicalRecords> pagedList = medicalRecordService.getOutpatientRecordList(
                    request.getPageIndex(), request.getPageSize(), request.getHisPatientId());

            if (pagedList.getItems() != null && pagedList.getItems().size() > 0) {
                for (MedicalRecords medicalRecord : pagedList.getItems()) {
                    record = MedicalRecord.newBuilder()
                            .setRecordId(medicalRecord.getId())
                            .setAdmTime(Checker.getStringValue(medicalRecord.getAdmTime()))
                            .setHospitalName(Checker.getStringValue(medicalRecord.getHospitalName()))
                            .setDoctorName(Checker.getStringValue(medicalRecord.getDoctorName()))
                            .setPatientName(Checker.getStringValue(medicalRecord.getPatientName()))
                            .setSelfReport(Checker.getStringValue(medicalRecord.getChiefComplaint()))
                            .setPhyExam(Checker.getStringValue(medicalRecord.getPhyExam()))
                            .setDiagnose(Checker.getStringValue(medicalRecord.getDiagnosis()))
                            .setSuggestion(Checker.getStringValue(medicalRecord.getSuggestion()))
                            .setAdvice(Checker.getStringValue(medicalRecord.getAdvice()))
                            .setCreateTime(medicalRecord.getCreateTime().getTime())
                            .build();
                    lst.add(record);
                }
            }

            GetOutpatientRecordListByHisPatientIdResponse response = GetOutpatientRecordListByHisPatientIdResponse.newBuilder()
                    .setCode(ResultCode.SUCCEED_VALUE)
                    .addAllMedicalRecord(lst)
                    .build();
            return response;
        } catch (Exception e) {
            logger.error("getOutpatientRecordListByHisPatientId({}): {}",
                    request.getHisPatientId(), request.getPageIndex(), request.getPageSize(), e.getMessage(), e);
            return  GetOutpatientRecordListByHisPatientIdResponse.newBuilder()
                    .setCode(ResultCode.APP_ERROR_VALUE)
                    .setMsg(e.getMessage())
                    .build();
        }
    }

    //删除病历模板
    @Override
    public DeleteMedicalRecordTemplateResponse deleteMedicalRecordTemplate(DeleteMedicalRecordTemplateRequest request) {
        DeleteMedicalRecordTemplateResponse.Builder builder = DeleteMedicalRecordTemplateResponse.newBuilder();
        try {
            int count = medicalModuleRepository.deleteByIdEqualsAndDoctorIdEquals(request.getId(), request.getDoctorId());
            if (count > 0) {
                builder.setCode(ResultCode.SUCCEED_VALUE);
            } else {
                builder.setCode(ResultCode.APP_ERROR_VALUE).setMsg("模板不存在或暂不能删除");
            }
            return builder.build();
        } catch (Exception e) {
            logger.error("deleteMedicalRecordTemplate({}): {}", request, e.getMessage(), e);
            return builder.setCode(ResultCode.APP_ERROR_VALUE).setMsg(e.getMessage()).build();
        }
    }

}

