package com.ywt.alipaympapi.service.impl;

import com.ywt.alipaympapi.core.utils.*;
import com.ywt.alipaympapi.models.vo.MedicalCardVo;
import com.ywt.core.exception.AppMessageException;
import com.ywt.gapi.Result;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.third.taihe.*;
import com.ywt.gapi.user.GetMedicalCardListRequest;
import com.ywt.gapi.user.GetMedicalCardListResponse;
import com.ywt.gapi.user.MedicalCard;
import com.ywt.gapi.user.UserServiceGrpc;
import com.ywt.model.PageVO;
import com.ywt.model.Pagination;
import com.ywt.request.report.QueryReportDetailRequest;
import com.ywt.request.report.QueryReportListRequest;
import com.ywt.response.register.QueryDoctorListResponseData;
import com.ywt.response.report.QueryReportDetailResponseData;
import com.ywt.response.report.QueryReportListResponseData;
import com.ywt.alipaympapi.service.IsvReportService;
import com.ywt.response.report.ReportItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class IsvReportServiceImpl implements IsvReportService {

    @Autowired
    private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;

    @Autowired
    private TaiheServiceGrpc.TaiheServiceBlockingStub taiheServiceBlockingStub;

    @Override
    public QueryReportDetailResponseData queryReportDetail(QueryReportDetailRequest request) throws Exception{
        QueryReportDetailResponseData data = new QueryReportDetailResponseData();
        if (StringHelper.isNullOrWhiteSpace(request.getRecordId())) {
            throw new AppMessageException("没有检验检查报告Id");
        }

            String userIdStr = request.getUserId();
            int userId = Integer.parseInt(userIdStr);
            int hospitalId = BizUtil.getCurrentHospitalId();
            if(Checker.isNone(request.getHisPatientId())){
                throw new AppMessageException("hisPatientId不能为空");
            }
            String hisPatientId = Checker.getStringValue(request.getHisPatientId());
            MedicalCardVo card = getCard(userId, hospitalId, hisPatientId);
            String type = request.getType();
            if ("检查报告".equals(type)) {

                GetInspectionDetailRequest req = GetInspectionDetailRequest.newBuilder()
                        .setReportId(request.getRecordId())
                        .setHospitalId(hospitalId)
                        .build();
                GetInspectionDetailResponse res = taiheServiceBlockingStub.getInspectionDetail(req);
                if (res.getCode() == ResultCode.SUCCEED_VALUE) {
                    List<String> reportItem = new ArrayList<>();
                    InspectionDetail detail = res.getDetail();
                    data.setRecordId(request.getRecordId());
                    data.setUserName(Checker.getStringValue(card.getPatientName()));
                    data.setUserSex(card.getSex() == 1 ? "男": card.getSex() ==  2 ? "女": "");
                    data.setUserAge(Checker.getStringValue(card.getAge()));
                    data.setCardNum(Checker.getStringValue(card.getCardNum()));
                    data.setDepartmentName(detail.getDeptName());
                    data.setApplyDoctorName(detail.getDoctorName());
                    reportItem.add(detail.getDiagnose());
                    data.setDiagnosis(reportItem);
                    data.setConfirmDoctorName(detail.getInspectionDoctor());
                    data.setReportDate(detail.getInspectionDate());
                    data.setReportImageDesc(detail.getInspectionResult());
                    data.setHisPatientId(request.getHisPatientId());
                    return data;

                } else {
                    com.ywt.gapi.user.GetInspectionReportDetailRequest girdReq = com.ywt.gapi.user.GetInspectionReportDetailRequest.newBuilder()
                            .setReportId(request.getRecordId())
                            .setHospitalId(hospitalId)
                            .build();
                    com.ywt.gapi.user.GetInspectionReportDetailResponse girdResp = userServiceBlockingStub.getInspectionReportDetail(girdReq);
                    if (girdResp.getResult().getCode() == ResultCode.SUCCEED) {
                        List<String> reportItem = new ArrayList<>();
                        com.ywt.gapi.user.InspectionReportDetail detail = girdResp.getReport();
                        data.setRecordId(request.getRecordId());
                        data.setUserName(card.getPatientName());
                        data.setUserSex(card.getSex() == 1 ? "男": card.getSex() ==  2 ? "女": "");
                        data.setUserAge(Checker.getStringValue(card.getAge()));
                        data.setCardNum(Checker.getStringValue(card.getCardNum()));
                        data.setDepartmentName(detail.getDeptName());
                        data.setApplyDoctorName(Checker.getStringValue(detail.getAppDocName()));
                        reportItem.add(Checker.getStringValue(detail.getDiagnosis()));
                        data.setDiagnosis(reportItem);
                        data.setConfirmDoctorName(Checker.getStringValue(detail.getVerifyDocName()));
                        data.setReportDate(DateUtil.convertTimestampToDateString(detail.getExaminationDate(), "yyyy年MM月dd日 HH:mm:ss"));
                        data.setReportImageDesc(Checker.getStringValue(detail.getExamination()));
                        data.setHisPatientId(request.getHisPatientId());
                        return data;
                    }
                    throw new AppMessageException("没有此报告详情");
                }

            }
            if ("检验报告".equals(type)) {
                GetLaboratoryDetailRequest req = GetLaboratoryDetailRequest.newBuilder()
                        .setInspectionId(request.getRecordId())
                        .setHospitalId(hospitalId)
                        .build();
                GetLaboratoryDetailResponse res = taiheServiceBlockingStub.getLaboratoryDetail(req);
                if (res.getCode() == ResultCode.SUCCEED_VALUE) {
                    List<ReportItem> reportItemList = new ArrayList<>();
                    List<String> reportItem = new ArrayList<>();
                    data.setDiagnosis(reportItem);
                    data.setUserName(card.getPatientName());
                    data.setUserSex(card.getSex() == 1 ? "男": card.getSex() ==  2 ? "女": "");
                    data.setUserAge(Checker.getStringValue(card.getAge()));
                    data.setItemName(res.getTitle());
                    data.setReportDate(res.getTime());
                    data.setConfirmDoctorName(res.getDoctor());
                    data.setCardNum(Checker.getStringValue(card.getCardNum()));
                    data.setHisPatientId(request.getHisPatientId());
                    for (LaboratoryDetail detail : res.getDetailList()) {
                        ReportItem r = new ReportItem();
                        r.setItemName(detail.getItemName());
                        String flag = detail.getResultFlag() == 1 ? "HIGH" : detail.getResultFlag() == 2 ? "LOW" : "NORMAL";
                        r.setPnFlag(flag);
                        r.setReference(detail.getItemRef());
                        r.setTxtVal(detail.getTestResult());
                        r.setUnit(detail.getUnit());
                        reportItemList.add(r);
                    }
                    data.setReportItemList(reportItemList);
                    return data;
                } else {
                    com.ywt.gapi.user.GetLaboratoryReportDetailRequest glrdReq = com.ywt.gapi.user.GetLaboratoryReportDetailRequest.newBuilder()
                            .setInspectionId(request.getRecordId())
                            .setHospitalId(hospitalId)
                            .build();
                    com.ywt.gapi.user.GetLaboratoryReportDetailResponse glrdResp = userServiceBlockingStub.getLaboratoryReportDetail(glrdReq);
                    if (glrdResp.getResult().getCode() == ResultCode.SUCCEED) {
                        List<ReportItem> reportItemList = new ArrayList<>();
                        List<String> reportItem = new ArrayList<>();
                        data.setDiagnosis(reportItem);
                        data.setUserName(Checker.getStringValue(card.getPatientName()));
                        data.setUserSex(card.getSex() == 1 ? "男": card.getSex() ==  2 ? "女": "");
                        data.setUserAge(Checker.getStringValue(card.getAge()));
                        data.setItemName(res.getTitle());
                        data.setReportDate(res.getTime());
                        data.setConfirmDoctorName(res.getDoctor());
                        data.setCardNum(Checker.getStringValue(card.getCardNum()));
                        data.setRecordId(request.getRecordId());
                        data.setHisPatientId(request.getHisPatientId());
                        for (com.ywt.gapi.user.LaboratoryReportDetail detail : glrdResp.getDetailList()) {
                            ReportItem r = new ReportItem();
                            r.setItemName(Checker.getStringValue(detail.getItemName()));
                            r.setPnFlag(Checker.getStringValue(detail.getResultFlag()));
                            r.setReference(detail.getItemRef());
                            r.setTxtVal(detail.getTestResult());
                            r.setUnit(detail.getUnit());
                            reportItemList.add(r);
                        }
                        data.setReportItemList(reportItemList);
                        return data;
                    }
                    throw new AppMessageException("没有此报告");
                }
            }
        return data;
    }

    @Override
    public PageVO<QueryReportListResponseData> queryReportList(QueryReportListRequest request) throws Exception {
        List<QueryReportListResponseData> list = new ArrayList<>();
        String userIdStr = request.getUserId();
        int userId = Integer.parseInt(userIdStr);
        // 报告类型：分为"检查报告"、"检验报告"两种
        if(Checker.isNone(request.getType())){
            throw new AppMessageException("报告类型不能为空");
        }
        String type = request.getType();
        int hospitalId = BizUtil.getCurrentHospitalId();
        int pageIndex = request.getPageIndex();
        int pageSize = request.getPageSize();
        if(Checker.isNone(request.getHisPatientId())){
            throw new AppMessageException("hisPatientId不能为空");
        }
        String hisPatientId = Checker.getStringValue(request.getHisPatientId());
        int total = 0;
        int totalT = 0;
        int totalTh = 0;
            MedicalCardVo card = getCard(userId, hospitalId, hisPatientId);

            if ("检查报告".equals(type)) {
                GetInspectionListRequest getInspectionListRequest = GetInspectionListRequest.newBuilder()
                        .setPatientId(hisPatientId)
                        .setHospitalId(hospitalId)
                        .build();
                GetInspectionListResponse res = taiheServiceBlockingStub.getInspectionList(getInspectionListRequest);
                if (res.getCode() == ResultCode.SUCCEED_VALUE) {
                    total = res.getInspectionReportList().size();
                    for (InspectionReport q : res.getInspectionReportList()) {
                        QueryReportListResponseData da = new QueryReportListResponseData();
                        da.setItemName(Checker.getStringValue(q.getReportTitle()));
                        da.setRecordId(Checker.getStringValue(q.getReportId()));
                        da.setUserName(card.getPatientName());
                        da.setCardNum(card.getCardNum());
                        da.setStatus(Checker.getStringValue(""));
                        da.setDiagnosis(Checker.getStringValue(""));
                        da.setType(Checker.getStringValue(request.getType()));
                        da.setApplyDate(Checker.getStringValue(""));
                        da.setHisPatientId(hisPatientId);
                        da.setApplyDate(q.getAuditDate());
                        list.add(da);
                    }
                }
                com.ywt.gapi.user.GetInspectionReportListRequest girlReq = com.ywt.gapi.user.GetInspectionReportListRequest.newBuilder()
                        .setMedicalCardId(Checker.getIntegerValue(card.getId()))
                        .setUserId(userId)
                        .setHospitalId(hospitalId)
                        .build();
                com.ywt.gapi.user.GetInspectionReportListResponse girlResp = userServiceBlockingStub.getInspectionReportList(girlReq);
                if (girlResp.getResult().getCode() == ResultCode.SUCCEED) {
                    totalT = girlResp.getReportList().size();
                    for (com.ywt.gapi.user.InspectionReport report : girlResp.getReportList()) {
                        QueryReportListResponseData da = new QueryReportListResponseData();
                        da.setItemName(Checker.getStringValue(report.getReportTitle()));
                        da.setRecordId(Checker.getStringValue(report.getReportId()));
                        da.setUserName(card.getPatientName());
                        da.setCardNum(card.getCardNum());
                        da.setStatus(Checker.getStringValue(""));
                        da.setDiagnosis(Checker.getStringValue(""));
                        da.setType(Checker.getStringValue(request.getType()));
                        da.setApplyDate(Checker.getStringValue(""));
                        da.setHisPatientId(hisPatientId);
                        da.setApplyDate( DateUtil.convertTimestampToDateString(report.getReportDate(), "yyyy年MM月dd日"));
                        list.add(da);
                    }
                }

            }
            if ("检验报告".equals(type)) {
                GetLaboratoryListRequest req = GetLaboratoryListRequest.newBuilder()
                        .setPatientId(hisPatientId)
                        .setHospitalId(hospitalId)
                        .build();
                GetLaboratoryListResponse thRes = taiheServiceBlockingStub.getLaboratoryList(req);
                if (thRes.getCode() == ResultCode.SUCCEED_VALUE) {
                    total = thRes.getReportList().size();
                    for (LaboratoryReport q : thRes.getReportList()) {
                        QueryReportListResponseData da = new QueryReportListResponseData();
                        da.setItemName(Checker.getStringValue(q.getReportTitle()));
                        da.setDepartmentName(Checker.getStringValue(q.getDeptName()));
                        da.setRecordId(Checker.getStringValue(q.getReportId()));
                        da.setUserName(card.getPatientName());
                        da.setCardNum(card.getCardNum());
                        da.setType(Checker.getStringValue(request.getType()));
                        da.setHisPatientId(hisPatientId);
                        da.setApplyDate(q.getAuditDate());
                        list.add(da);
                    }
                }
                com.ywt.gapi.user.GetLaboratoryReportListRequest glrlReq = com.ywt.gapi.user.GetLaboratoryReportListRequest.newBuilder()
                        .setMedicalCardId(Checker.getIntegerValue(card.getId()))
                        .setUserId(userId)
                        .setHospitalId(hospitalId)
                        .build();
                com.ywt.gapi.user.GetLaboratoryReportListResponse glrlResp = userServiceBlockingStub.getLaboratoryReportList(glrlReq);
                if (glrlResp.getResult().getCode() == ResultCode.SUCCEED) {
                    totalT = glrlResp.getReportList().size();
                    for (com.ywt.gapi.user.LaboratoryReport report : glrlResp.getReportList()) {
                        QueryReportListResponseData da = new QueryReportListResponseData();
                        da.setItemName(Checker.getStringValue(report.getInspectionName()));
                        da.setDepartmentName(Checker.getStringValue(report.getDeptName()));
                        da.setRecordId(Checker.getStringValue(report.getInspectionId()));
                        da.setUserName(card.getPatientName());
                        da.setCardNum(card.getCardNum());
                        da.setType(Checker.getStringValue(request.getType()));
                        da.setHisPatientId(hisPatientId);
                        da.setApplyDate( DateUtil.convertTimestampToDateString(report.getInspectionDate(), "yyyy年MM月dd日") );
                        list.add(da);
                    }
                }

            }
        totalTh = total + totalT;
        Pagination pagination = new Pagination(pageIndex, totalTh, totalTh);
        PageVO<QueryReportListResponseData> res = new PageVO<>(pagination, list);
        return res;
    }


    /**
     * 根据 userId & hospitalId 获取用户可用就诊卡列表
     */
    public List<MedicalCard> getUserMedCardList(int userId, int hospitalId) throws AppMessageException {
        GetMedicalCardListRequest getMedicalCardListRequest = GetMedicalCardListRequest.newBuilder()
                .setHospitalId(hospitalId)
                .setUserId(userId)
                .build();
        GetMedicalCardListResponse getMedicalCardListResponse = userServiceBlockingStub.getMedicalCardList(getMedicalCardListRequest);
        Result result = getMedicalCardListResponse.getResult();
        if (result.getCode() != ResultCode.SUCCEED) throw new AppMessageException(result.getInfo());
        return getMedicalCardListResponse.getMedicalCardsList();
    }

    public MedicalCardVo getCard(int userId, int hospitalId, String hisPatientId) throws Exception {
        List<MedicalCard> list = getUserMedCardList(userId, hospitalId);
        if (Checker.isNone(list)) throw new AppMessageException("没有诊疗卡");
        for (MedicalCard card : list) {
            if (hisPatientId.equals(card.getPatientId())) {
                MedicalCardVo v = new MedicalCardVo();
                v.setId(card.getCardId());
                v.setSex(card.getSex());
                v.setHisPatientId(card.getPatientId());
                v.setPatientName(card.getPatientName());
                v.setCardNum(card.getCardNo());
                v.setAge(getAgeFromMedicalCard(card));
                return v;
            }
        }
        throw new AppMessageException("没有此报告");
    }

    private String getAgeFromMedicalCard(MedicalCard card) {
        int age = -1;
        String idNo = card.getIdNo();
        String birthday = card.getBirthday();
        if (!StringHelper.isNullOrEmpty(idNo)) {
            try {
                age = IdCardUtil.getCurrentAge(idNo);
            } catch (Exception e) {
                log.error("IsvMedicCardServiceImpl#getAgeFromMedicalCard(idNo = {}): 无法获取年龄 {}", idNo, e.getMessage(), e);
            }
        } else if (!StringHelper.isNullOrEmpty(birthday)) {
            try {
                age = IdCardUtil.getCurrentAgeByBirthday(birthday, IdCardUtil.DATE_PATTERN2);
            } catch (Exception e) {
                log.error("IsvMedicCardServiceImpl#getAgeFromMedicalCard(birthday = {}): 无法获取年龄 {}", birthday, e.getMessage(), e);
            }
        }
        // 不返回年龄为 "-1"
        if (age < 0) {
            return "";
        }
        return String.valueOf(age);
    }
}
