package cn.sh.stc.sict.theme.hphy.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.theme.common.dto.SocketMsg;
import cn.sh.stc.sict.theme.handler.WebSocketServer;
import cn.sh.stc.sict.theme.hphy.constant.PatientConstant;
import cn.sh.stc.sict.theme.hphy.model.*;
import cn.sh.stc.sict.theme.hphy.service.*;
import cn.sh.stc.sict.theme.hphy.util.PythonUtil;
import cn.sh.stc.sict.theme.hphy.vo.*;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * @author zhangly
 * @Description
 * @Date 2020/10/9 13:56
 **/
@Slf4j
@Service
public class HphyAiCallServiceImpl implements HphyAiCallService {

    @Autowired
    private HphyPatientBaseService hphyPatientBaseService;
    @Autowired
    private HphyGuideRecordService hphyGuideRecordService;
    @Autowired
    private HphyGuideQuestionService hphyGuideQuestionService;
    @Autowired
    private HphyGuideQuestionOptionService hphyGuideQuestionOptionService;

    @Autowired
    private HphyQuestionService hphyQuestionService;
    @Autowired
    private HphyQuestionOptionService hphyQuestionOptionService;
    @Autowired
    private HphyDoctorService hphyDoctorService;

    @Value("${hphy.ai.api.uri}")
    private String apiUri;
    @Value("${hphy.ai.api.login-api}")
    private String loginApi;
    @Value("${hphy.ai.api.call-api}")
    private String callApi;
    @Value("${hphy.ai.api.cloud-form-id}")
    private String cloudFormId;
    @Value("${hphy.ai.account.user-name}")
    private String userName;
    @Value("${hphy.ai.account.user-pwd}")
    private String userPwd;
    @Value("${hphy.ai.token.expires}")
    private Long expires;
    // token 缓存 map
    private final static Map<String, Object> tokenMap = new HashMap<>(2, 1);

    @Override
    public R<?> postAiCall(Long userId, String phone) {
        String token = getToken();
        if (StrUtil.isBlank(token)) {
            return new R<>().error("获取token失败");
        }

        HphyPatientBase patient = hphyPatientBaseService.getById(userId);
        if (patient == null) {
            return new R<>().error("患者信息不存在");
        }

        JhAiCallParamDTO param = new JhAiCallParamDTO();
        param.setTaskId(ObjectId.next());
        param.setCloudFormId(cloudFormId);
//        param.setPatientName("test");
        param.setPatientName(patient.getName());
        param.setPatientPhone(phone);
        param.setPlanExecuteBeginTime(DateUtil.today());

        String resultStr = HttpRequest.post(apiUri + callApi).body(JSONUtil.toJsonStr(param)).header("Authorization", "Bearer " + token).execute().body();
//                HttpUtil.post(apiUri + callApi, JSONUtil.toJsonStr(param));
        if (!JSONUtil.isJson(resultStr)) {
            return new R<>().error("AI 呼叫失败");
        }
        JSONObject json = JSONUtil.parseObj(resultStr);
        if (json.getInt("res") != 0) {
            return new R<>().error(json.getStr("msg"));
        }

        HphyGuideRecord record = new HphyGuideRecord();
        record.setPatientId(userId);
        record.setPatientName(patient.getName());
        record.setAge(patient.getAge());
        record.setJhTaskId(param.getTaskId());
        hphyGuideRecordService.save(record);

        return new R<>().success("稍后将给您回电话");
    }

    @Override
    public R<?> callback(JhCallbackDTO callback) throws IOException, EncodeException {
        if (callback.getResult() != 0) {
            log.error("语音任务失败");
            return new R<>().success("结果已成功接收");
        }

        HphyGuideRecord record = hphyGuideRecordService.getOne(new LambdaQueryWrapper<HphyGuideRecord>().eq(HphyGuideRecord::getJhTaskId, callback.getTaskId()));

        if (StrUtil.isBlank(callback.getData())) {
            log.error("用户拒绝回答问卷");
            SocketMsg socketMsg = new SocketMsg();
            socketMsg.setType(PatientConstant.EXCEPTION_TYPE);
            socketMsg.setMsg("您未接受电话沟通，如需电话沟通，请点击“电话沟通”接听问诊电话");
            WebSocketServer.sendInfo(socketMsg, PatientConstant.HPHY + record.getPatientId());
            record.setPyResult("用户未接通问诊电话");
            return new R<>().success("结果已成功接收");
        }

        List<JhAnswerDTO> answers = JSONUtil.toList(JSONUtil.parseArray(callback.getData()), JhAnswerDTO.class);
        List<HphyGuideQuestion> questions = new ArrayList<>();
        List<HphyGuideQuestionOption> options = new ArrayList<>();

        if (record == null) {
            log.error("未找到相关任务，taskId：{}", callback.getTaskId());
            return new R<>("请确认taskId是否正确").setBizCode(100);
        }

        for (JhAnswerDTO answer : answers) {
            HphyQuestion question = hphyQuestionService.getOne(new LambdaQueryWrapper<HphyQuestion>().eq(HphyQuestion::getJhId, answer.getQuestionId()));
            if (question == null) {
                log.error("未找到相关问题，questionId：{}", answer.getQuestionId());
                return new R<>("请确认questionId是否正确").setBizCode(100);
            }
            HphyGuideQuestion guideQuestion = new HphyGuideQuestion();
            guideQuestion.setGuideId(record.getId());
            guideQuestion.setTitle(question.getTitle());
            guideQuestion.setTag(question.getTag());
            guideQuestion.setQuestionId(cn.sh.stc.sict.cloud.common.core.util.NumberUtil.isNotNullOrZero(question.getParentId()) ? question.getParentId() : question.getId());
            // guideQuestion.setQuestionId(question.getId());
            hphyGuideQuestionService.save(guideQuestion);

            questions.add(guideQuestion);

            if (CollectionUtil.isNotEmpty(answer.getOptions())) {
                JhOptionDTO option = answer.getOptions().get(0);
                if (StrUtil.isNotBlank(option.getQuestionAnswer())) {
                    String[] answerIds = option.getQuestionAnswer().split(StrUtil.COMMA);
                    for (String answerId : answerIds) {
                        HphyQuestionOption qoption = hphyQuestionOptionService.getOne(new LambdaQueryWrapper<HphyQuestionOption>().eq(HphyQuestionOption::getJhId, answerId));
                        HphyGuideQuestionOption guideOption = new HphyGuideQuestionOption();
                        guideOption.setGuideQuestionId(guideQuestion.getId());
                        if (qoption == null) {
                            guideOption.setTitle(option.getQuestionAnswer());
                        } else {
                            guideOption.setTitle(qoption.getTitle());
                            guideOption.setTag(qoption.getTag());
                        }
                        hphyGuideQuestionOptionService.save(guideOption);
                        options.add(guideOption);
                    }
                }
            }
        }

        HphyPatientBase patient = hphyPatientBaseService.getById(record.getPatientId());

        Map<Long, List<HphyGuideQuestionOption>> groupedOptions = options.stream().collect(groupingBy(HphyGuideQuestionOption::getGuideQuestionId));
        List<DiseaseAnalysisDTO> dtoList = new ArrayList<>();
        for (HphyGuideQuestion question : questions) {
            if (groupedOptions.containsKey(question.getId())) {
                for (HphyGuideQuestionOption answer : groupedOptions.get(question.getId())) {
                    DiseaseAnalysisDTO diseaseAnalysisDTO = new DiseaseAnalysisDTO();
                    diseaseAnalysisDTO.setQuestion(question.getTitle());
                    diseaseAnalysisDTO.setQuestionTag(question.getTag());
                    diseaseAnalysisDTO.setAnswer(answer.getTitle());
                    diseaseAnalysisDTO.setAnswerTag(answer.getTag());

                    dtoList.add(diseaseAnalysisDTO);
                }
            }
        }

        Map<String, List<DiseaseAnalysisDTO>> map = dtoList.stream().collect(Collectors.groupingBy(DiseaseAnalysisDTO::getQuestionTag));
        // 高血压 -> 高血压分级 -> 心血管危险程度分层
        // drug 0 1
        boolean drug = this.getDrug(map);
        // disease_level 0 1 2 3
        int diseaseLevel = this.getLevel(map);
        if (!(diseaseLevel == 0 && !drug)) {
            String riskLevel = this.getRiskLevel(patient, diseaseLevel, map);
            // 2020/10/16 吴健人-》 去掉心血管分层
            riskLevel = "";
            // 症状
            List<String> disease = new ArrayList<>();
            String tt = "高血压" + (diseaseLevel > 0 ? (diseaseLevel + "级" + riskLevel) : "");
            disease.add(tt);
            setDiseases(map, disease);

            record.setDisease(disease.toString());
            record.setRiskLevel(riskLevel);

            PythonDTO pydto = new PythonDTO(patient, disease);
            String pyResutl = PythonUtil.getDcotorMatchListForHP(JSONUtil.toJsonStr(pydto));
            record.setPyResult(pyResutl);
            hphyGuideRecordService.updateById(record);
            JSONObject obj = JSONUtil.parseObj(pyResutl);
            // indicator 0-字符串 1-json
            SocketMsg socketMsg = new SocketMsg();

            if (Constant.STRING_YES.equals(obj.getStr("indicator"))) {
                List<PythonResult> pythonList = JSON.parseArray(obj.getStr("data"), PythonResult.class);
                List<DoctorMatchVO> resultList = hphyDoctorService.getRecommendList(record, pythonList);
                pydto.setResult(resultList);
                socketMsg.setType(PatientConstant.JSON_TYPE);
            } else {
                pydto.setResult(obj.getStr("data"));
                socketMsg.setType(PatientConstant.STR_TYPE);
            }
            socketMsg.setMsg(pydto);
            WebSocketServer.sendInfo(socketMsg, PatientConstant.HPHY + record.getPatientId());
        } else {
            SocketMsg socketMsg = new SocketMsg();
            socketMsg.setType(PatientConstant.EXCEPTION_TYPE);
            socketMsg.setMsg("您的血压值在正常范围内，身体若有不适请到当地医院做详细检查以明确诊断！");
            WebSocketServer.sendInfo(socketMsg, PatientConstant.HPHY + record.getPatientId());
            log.info("血压值在正常范围内");
        }
        return new R<>("结果已成功接收").setBizCode(200);
    }

    private void setDiseases(Map<String, List<DiseaseAnalysisDTO>> map, List<String> disease) {

        List<DiseaseAnalysisDTO> hearts = getList(map, PatientConstant.HEART);
        List<DiseaseAnalysisDTO> brains = getList(map, PatientConstant.BRAIN);
        DiseaseAnalysisDTO eye = getDTO(map, PatientConstant.EYE);
        List<DiseaseAnalysisDTO> vessels = getList(map, PatientConstant.VESSEL);
        List<DiseaseAnalysisDTO> kidneys = getList(map, PatientConstant.KIDNEY);
        DiseaseAnalysisDTO other = getDTO(map, PatientConstant.OTHER);
        DiseaseAnalysisDTO diabetes = getDTO(map, PatientConstant.DIABETES);

        if (CollectionUtil.isNotEmpty(hearts)) {
            for (DiseaseAnalysisDTO heart : hearts) {
                if (!PatientConstant.NO.equals(heart.getAnswerTag())) {
                    disease.add(heart.getAnswer());
                }
            }
        }
        if (CollectionUtil.isNotEmpty(brains)) {
            for (DiseaseAnalysisDTO brain : brains) {
                if (!PatientConstant.NO.equals(brain.getAnswerTag())) {
                    disease.add(brain.getAnswer());
                }
            }
        }
        if (eye != null && PatientConstant.YES.equals(eye.getAnswerTag())) {
            disease.add("视网膜渗出");
            disease.add("视网膜出血");
        }
        if (CollectionUtil.isNotEmpty(vessels)) {
            for (DiseaseAnalysisDTO vessel : vessels) {
                if (!PatientConstant.NO.equals(vessel.getAnswerTag())) {
                    disease.add(vessel.getAnswer());
                }
            }
        }
        if (CollectionUtil.isNotEmpty(kidneys)) {
            for (DiseaseAnalysisDTO kidney : kidneys) {
                if (!PatientConstant.NO.equals(kidney.getAnswerTag())) {
                    disease.add(kidney.getAnswer());
                }
            }
        }
        if (diabetes != null && PatientConstant.YES.equals(diabetes.getAnswerTag())) {
            disease.add("糖尿病");
        }
        if (other != null && PatientConstant.OTHER.equals(other.getAnswerTag())) {
            disease.add(other.getAnswer());
        }
    }

    /**
     * 是否吃药
     * // diab 0 1
     *
     * @param map
     * @return
     */
    private boolean getDrug(Map<String, List<DiseaseAnalysisDTO>> map) {
        boolean result = false;
        if (map.containsKey(PatientConstant.QUESTION_DRUG)) {
            result = Constant.STRING_YES.equals(getStrFromTag(map, PatientConstant.QUESTION_DRUG));
        }
        return result;
    }

    /**
     * 计算高血压分层
     * // risk_level 低危 中危 高危 极高危
     * // risk_cal 计算心血管危险程度
     *
     * @param map
     * @return
     */
    private Integer getLevel(Map<String, List<DiseaseAnalysisDTO>> map) {
        Integer level = 0;
        // disease_cal  计算取较大值作为高血压分级
        int sbp = getInt(map, PatientConstant.SBP);
        int dbp = getInt(map, PatientConstant.DBP);
        if (sbp > 0 && dbp > 0) {
            if (
                    ((sbp >= 140 && sbp <= 159) && (dbp <= 89)) ||
                            ((sbp >= 140 && sbp <= 159) && (dbp >= 90 && dbp <= 99)) ||
                            ((sbp <= 139) && (dbp >= 90 && dbp <= 99))
            ) {
                level = PatientConstant.DISEASE_1;
            } else if (
                    ((sbp >= 160 && sbp <= 179) && (dbp <= 89)) ||
                            ((sbp >= 160 && sbp <= 179) && (dbp >= 90 && dbp <= 99)) ||
                            ((sbp >= 160 && sbp <= 179) && (dbp >= 100 && dbp <= 109)) ||
                            ((sbp <= 139) && (dbp >= 100 && dbp <= 109)) ||
                            ((sbp >= 140 && sbp <= 159) && (dbp >= 100 && dbp <= 109))
            ) {
                level = PatientConstant.DISEASE_2;
            } else if (
                    ((sbp >= 180) && (dbp <= 89)) ||
                            ((sbp >= 180) && (dbp >= 90 && dbp <= 99)) ||
                            ((sbp >= 180) && (dbp >= 100 && dbp <= 109)) ||
                            ((sbp >= 180) && (dbp >= 110)) ||
                            ((sbp <= 139) && (dbp >= 110)) ||
                            ((sbp >= 140 && sbp <= 159) && (dbp >= 110)) ||
                            ((sbp >= 160 && sbp <= 179) && (dbp >= 110))
            ) {
                level = PatientConstant.DISEASE_3;
            }
        } else {
            String sbpStr = getStrFromTag(map, PatientConstant.SBP_RANGE);
            String dbpStr = getStrFromTag(map, PatientConstant.DBP_RANGE);

            if (
                    (PatientConstant.PRESS_RANGE_2.equals(sbpStr) && PatientConstant.PRESS_RANGE_5.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_2.equals(sbpStr) && PatientConstant.PRESS_RANGE_6.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_1.equals(sbpStr) && PatientConstant.PRESS_RANGE_6.equals(dbpStr))
            ) {
                level = PatientConstant.DISEASE_1;
            } else if (
                    (PatientConstant.PRESS_RANGE_3.equals(sbpStr) && PatientConstant.PRESS_RANGE_5.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_3.equals(sbpStr) && PatientConstant.PRESS_RANGE_6.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_3.equals(sbpStr) && PatientConstant.PRESS_RANGE_7.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_1.equals(sbpStr) && PatientConstant.PRESS_RANGE_7.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_2.equals(sbpStr) && PatientConstant.PRESS_RANGE_7.equals(dbpStr))
            ) {
                level = PatientConstant.DISEASE_2;
            } else if (
                    (PatientConstant.PRESS_RANGE_4.equals(sbpStr) && PatientConstant.PRESS_RANGE_5.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_4.equals(sbpStr) && PatientConstant.PRESS_RANGE_6.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_4.equals(sbpStr) && PatientConstant.PRESS_RANGE_7.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_4.equals(sbpStr) && PatientConstant.PRESS_RANGE_8.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_1.equals(sbpStr) && PatientConstant.PRESS_RANGE_8.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_2.equals(sbpStr) && PatientConstant.PRESS_RANGE_8.equals(dbpStr)) ||
                            (PatientConstant.PRESS_RANGE_3.equals(sbpStr) && PatientConstant.PRESS_RANGE_8.equals(dbpStr))
            ) {
                level = PatientConstant.DISEASE_3;
            }
        }

        return level;
    }

    /**
     * 心血管危险程度分层
     *
     * @param map
     * @return
     */
    private String getRiskLevel(HphyPatientBase patient, Integer level, Map<String, List<DiseaseAnalysisDTO>> map) {
        String result = "";
        int dangerCount = getDangerCount(patient, map);

        boolean hasDisease = hasDisease(map);
        boolean hasDiabetes = hasDiabetes(map);
        if (hasDisease) {
            result = PatientConstant.RISK_LEVEL_3;
        } else if (PatientConstant.DISEASE_1.equals(level)) {
            if (dangerCount == 0 && !hasDiabetes) {
                result = PatientConstant.RISK_LEVEL_0;
            } else if (dangerCount <= 2) {
                result = PatientConstant.RISK_LEVEL_1;
            } else if (dangerCount >= 3 || hasDiabetes) {
                result = PatientConstant.RISK_LEVEL_2;
            }
        } else if (PatientConstant.DISEASE_2.equals(level)) {
            if (dangerCount <= 2 || hasDiabetes) {
                result = PatientConstant.RISK_LEVEL_1;
            } else if (dangerCount >= 3 || hasDiabetes) {
                result = PatientConstant.RISK_LEVEL_2;
            }
        } else if (PatientConstant.DISEASE_3.equals(level)) {
            if (dangerCount == 0) {
                result = PatientConstant.RISK_LEVEL_2;
            } else if (hasDiabetes) {
                result = PatientConstant.RISK_LEVEL_3;
            }
        }

        return result;
    }

    private int getDangerCount(HphyPatientBase patient, Map<String, List<DiseaseAnalysisDTO>> map) {
        int dangerCount = 0;

        int heightInt = getInt(map, PatientConstant.HEIGHT);
        int weightInt = getInt(map, PatientConstant.WEIGHT);

        if ((PatientConstant.MALE.equals(patient.getGender()) && NumberUtil.isInteger(patient.getAge()) && Integer.parseInt(patient.getAge()) > 55) ||
                (PatientConstant.FEMALE.equals(patient.getGender()) && NumberUtil.isInteger(patient.getAge()) && Integer.parseInt(patient.getAge()) > 65)) {
            dangerCount = dangerCount + 1;
        }
        if (heightInt > 0 && weightInt > 0) {
            double height = ((double) heightInt) / 100D;
            if (((double) weightInt) / (height * height) > 28) {
                dangerCount = dangerCount + 1;
            }
        }
        if (PatientConstant.YES.equals(getStrFromTag(map, PatientConstant.SMOKING))) {
            dangerCount = dangerCount + 1;
        }
        if (PatientConstant.NO.equals(getStrFromTag(map, PatientConstant.SPORT))) {
            dangerCount = dangerCount + 1;
        }
        if (PatientConstant.NO.equals(getStrFromTag(map, PatientConstant.BLOOD_FAT))) {
            dangerCount = dangerCount + 1;
        }
        if (PatientConstant.YES.equals(getStrFromTag(map, PatientConstant.ANGIOCARPY))) {
            if (PatientConstant.YES.equals(getStrFromTag(map, PatientConstant.AGE))) {
                if (getInt(map, PatientConstant.AGE) >= 50) {
                    dangerCount = dangerCount + 1;
                }
            }
        }
        return dangerCount;
    }

    private boolean hasDisease(Map<String, List<DiseaseAnalysisDTO>> map) {
        String heart = getStrFromTag(map, PatientConstant.HEART);
        String brain = getStrFromTag(map, PatientConstant.BRAIN);
        String eye = getStrFromTag(map, PatientConstant.EYE);
        String vessel = getStrFromTag(map, PatientConstant.VESSEL);
        String kidney = getStrFromTag(map, PatientConstant.KIDNEY);
        String other = getStrFromTag(map, PatientConstant.OTHER);

        return !PatientConstant.NO.equals(heart) ||
                !PatientConstant.NO.equals(brain) ||
                PatientConstant.YES.equals(eye) ||
                !PatientConstant.NO.equals(vessel) ||
                !PatientConstant.NO.equals(kidney) ||
                "1".equals(other) ||
                "2".equals(other);
    }

    private boolean hasDiabetes(Map<String, List<DiseaseAnalysisDTO>> map) {
        String diabetes = getStrFromTag(map, PatientConstant.DIABETES);
        return PatientConstant.YES.equals(diabetes);
    }

    private String getToken() {
        String result = null;
        String token = MapUtil.getStr(tokenMap, "token");
        long expiresIn = MapUtil.getLong(tokenMap, "expires_in") == null ? 0L : MapUtil.getLong(tokenMap, "expires_in");
        long current = System.currentTimeMillis();
        if (StrUtil.isBlank(token) || current - expiresIn > expires) {
            log.error("token uri =============> {}", apiUri + loginApi);
            String tokenStr = HttpUtil.post(apiUri + loginApi, "{\"userName\":\"" + userName + "\",\"userPwd\":\"" + userPwd + "\"}");
            JSONObject tokenJson = JSONUtil.parseObj(tokenStr);
            if (tokenJson.getInt("res") == 0) {
                result = tokenJson.getByPath("data.token", String.class);
                if (StrUtil.isNotBlank(result)) {
                    tokenMap.put("token", result);
                    tokenMap.put("expires_in", System.currentTimeMillis());
                }
            }
        } else {
            result = token;
        }
        return result;
    }

    private Integer getInt(Map<String, List<DiseaseAnalysisDTO>> map, String key) {
        if (!map.containsKey(key)) {
            return 0;
        }
        DiseaseAnalysisDTO disease = map.get(key).get(0);
        if (StrUtil.isBlank(disease.getAnswer()) || !NumberUtil.isInteger(disease.getAnswer())) {
            return 0;
        }
        return Integer.parseInt(disease.getAnswer());
    }

    private String getStrFromTag(Map<String, List<DiseaseAnalysisDTO>> map, String key) {
        if (!map.containsKey(key)) {
            return "";
        }
        DiseaseAnalysisDTO disease = map.get(key).get(0);
        if (disease == null || StrUtil.isBlank(disease.getAnswerTag())) {
            return "";
        }
        return disease.getAnswerTag();
    }

    private DiseaseAnalysisDTO getDTO(Map<String, List<DiseaseAnalysisDTO>> map, String key) {
        if (!map.containsKey(key)) {
            return null;
        }
        return map.get(key).get(0);
    }

    private List<DiseaseAnalysisDTO> getList(Map<String, List<DiseaseAnalysisDTO>> map, String key) {
        if (!map.containsKey(key)) {
            return null;
        }
        return map.get(key);
    }
}
