package com.diagbot.facade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diagbot.client.AIServiceClient;
import com.diagbot.client.bean.FeatureRate;
import com.diagbot.client.bean.Response;
import com.diagbot.client.bean.ResponseData;
import com.diagbot.client.bean.SearchData;
import com.diagbot.dto.PushDTO;
import com.diagbot.dto.PushKYJDTO;
import com.diagbot.dto.QuestionDTO;
import com.diagbot.entity.DeptInfo;
import com.diagbot.entity.DeptVital;
import com.diagbot.entity.QuestionInfo;
import com.diagbot.entity.VitalOrder;
import com.diagbot.enums.InputModeEnum;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.enums.QuantitativeTypeEnum;
import com.diagbot.enums.QuestionTypeEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.util.EntityUtil;
import com.diagbot.util.StringUtil;
import com.diagbot.vo.LisKYJVO;
import com.diagbot.vo.PushKYJVO;
import com.diagbot.vo.PushVO;
import com.diagbot.vo.QuestionVO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Description:
 * @Author:zhaops
 * @time: 2018/11/20 11:18
 */
@Component
public class PushFacade {
    @Autowired
    private AIServiceClient aiServiceClient;
    @Autowired
    private QuestionFacade questionFacade;
    @Autowired
    private DeptInfoFacade deptInfoFacade;
    @Autowired
    private DeptVitalFacade deptVitalFacade;
    @Autowired
    private VitalOrderFacade vitalOrderFacade;
    @Autowired
    private TreatmentFacade treatmentFacade;

    /**
     * 推理接口
     *
     * @param pushVO
     * @return
     */
    public ResponseData pushAI(PushVO pushVO) {
        SearchData searchData = new SearchData();
        searchData.setAge(pushVO.getAge());
        searchData.setSymptom(pushVO.getSymptom());
        searchData.setVital(pushVO.getVital());
        searchData.setLisArr(pushVO.getLis());

        searchData.setPacs(pushVO.getPacs());
        searchData.setPast(pushVO.getPast());
        searchData.setOther(pushVO.getOther());
        searchData.setDiag(pushVO.getDiag());
        switch (pushVO.getSex()) {
            case 1:
                searchData.setSex("M");
                break;
            case 2:
                searchData.setSex("F");
                break;
            default:
                searchData.setSex("A");
                break;
        }

        searchData.setFeatureType(pushVO.getFeatureType());
        searchData.setSysCode("1");
        searchData.setLength(10);

        Response<ResponseData> res = aiServiceClient.bayesPageData(searchData);
        return res.getData();
    }

    /**
     * 推理接口
     *
     * @param pushVO
     * @return
     */
    public PushDTO pushInner(PushVO pushVO, Integer mode) {
        PushDTO pushDTO = new PushDTO();
        ResponseData data = pushAI(pushVO);

        String featureType = pushVO.getFeatureType();
        String[] featureTypes = featureType.split(",|，");
        Set<String> featureTypeSet = new HashSet(Arrays.asList(featureTypes));

        List<FeatureRate> symptom = data.getSymptom();
        List<FeatureRate> dis = data.getDis();
        List<FeatureRate> pacs = data.getPacs();
        List<FeatureRate> labs = data.getLabs();
        Map<String, String> treat = data.getTreat();

        Map<String, Object> symptomMap = list2Map(symptom);
        Map<String, Object> disMap = list2Map(dis);
        Map<String, Object> labMap = list2Map(labs);
        Map<String, Object> pacsMap = list2Map(pacs);

        if (featureTypeSet.contains(String.valueOf(QuestionTypeEnum.Lis.getKey()))) {
            List<QuestionDTO> labDTO = getTagListByMap(labMap, pushVO, QuestionTypeEnum.Lis.getKey());
            pushDTO.setLab(labDTO);
        }
        if (featureTypeSet.contains(String.valueOf(QuestionTypeEnum.Pacs.getKey()))) {
            List<QuestionDTO> pacsDTO = getTagListByMap(pacsMap, pushVO, QuestionTypeEnum.Pacs.getKey());
            pushDTO.setPacs(pacsDTO);
        }
        //诊断 返回tagName+标签
        if (featureTypeSet.contains(String.valueOf(QuestionTypeEnum.Disease.getKey()))) {
            List<QuestionDTO> disDTO = getTagListByMap(disMap, pushVO, QuestionTypeEnum.Disease.getKey());
            Map<String, List<QuestionDTO>> disMapDTO = new LinkedHashMap<>();
            //当前返回诊断都按疑似诊断处理，待大数据提供诊断分类
            disMapDTO.put("疑似诊断：", disDTO);
            pushDTO.setDis(disMapDTO);
        }
        //症状(主诉 type=1;现病史 type=2) 返回 tagName+填写单
        if (featureTypeSet.contains(String.valueOf(QuestionTypeEnum.Symptom.getKey()))) {
            //文本模式不推症状，仅结构化模式推症状
            if (mode.equals(InputModeEnum.Structured.getKey())) {
                List<QuestionDTO> symptomDTO = getTagListByMap(symptomMap, pushVO, QuestionTypeEnum.Symptom.getKey());
                pushDTO.setSymptom(symptomDTO);
            }
        }
        //查体 返回模板
        if (featureTypeSet.contains(String.valueOf(QuestionTypeEnum.Vital.getKey()))) {
            //没有推送信息时，默认取全科模板
            String deptName = "全科";
            if (dis != null && dis.size() > 0) {
                deptName = dis.get(0).getExtraProperty();
            }
            List<QuestionDTO> vitalDTO = getVitalModule(deptName, pushVO);
            pushDTO.setVital(vitalDTO);

        }
        //治疗方案
        if (featureTypeSet.contains(String.valueOf(QuestionTypeEnum.Drug.getKey()))) {
            if (pushVO.getDiseaseId() == null) {
                throw new CommonException(CommonErrorCode.PARAM_ERROR, "请输入诊断id");
            }
            Map<String, Object> treatmentMap = treatmentFacade.getTreatment(treat, pushVO.getDiseaseId());
            pushDTO.setTreat(treatmentMap);
        }
        return pushDTO;
    }


    /**
     * 获取返回结果标签
     *
     * @param map
     * @param pushVO
     * @param type
     * @return
     */
    public List<QuestionDTO> getTagListByMap(Map<String, Object> map, PushVO pushVO, Integer type) {
        List<QuestionDTO> questionDTOList = Lists.newLinkedList();
        QueryWrapper<QuestionInfo> questionInfoQueryWrapper = new QueryWrapper();
        questionInfoQueryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey()).
                in("tag_name", map.keySet()).
                eq("type", type);
        List<QuestionInfo> questionInfoList = questionFacade.list(questionInfoQueryWrapper);
        Map<String, QuestionInfo> questionMap = EntityUtil.makeEntityMap(questionInfoList, "tagName");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            QuestionDTO questionDTO = new QuestionDTO();
            if (questionMap.get(entry.getKey()) != null) {
                QuestionVO questionVO = new QuestionVO();
                questionVO.setAge(pushVO.getAge());
                questionVO.setSexType(pushVO.getSex());
                questionVO.setId(questionMap.get(entry.getKey()).getId());
                questionDTO = questionFacade.getById(questionVO);
                if (questionDTO == null || (!questionDTO.getSubType().equals(0))) {
                    questionDTO = new QuestionDTO();
                    questionDTO.setTagName(entry.getKey());
                    questionDTO.setName(entry.getKey());
                }

            } else {
                questionDTO.setTagName(entry.getKey());
                questionDTO.setName(entry.getKey());
            }
            questionDTOList.add(questionDTO);
        }
        return questionDTOList;
    }

    /**
     * 推理接口-快易检
     *
     * @param pushKYJVO
     * @return
     */
    public PushKYJDTO pushKYJ(PushKYJVO pushKYJVO) {
        PushVO pushVO = new PushVO();
        pushVO.setAge(pushKYJVO.getAge());
        pushVO.setSex(pushKYJVO.getSex());

        //参数预处理
        /*String lis = "";
        List<String> lisResultList = Lists.newArrayList();
        for (LisKYJVO lisKYJVO : pushKYJVO.getLisResultList()) {
            lisKYJVO = resultCalculation(lisKYJVO);
            lisResultList.addAll(getLisInputs(lisKYJVO));
        }
        lis = String.join(",", lisResultList);
        pushVO.setLis(lis);*/

        //化验结果
        pushVO.setLis(pushKYJVO.getLisResultList());

        ResponseData responseData = pushAI(pushVO);
        PushKYJDTO pushKYJDTO = new PushKYJDTO();
        pushKYJDTO.setLabs(responseData.getLabs());
        pushKYJDTO.setDis(responseData.getDis());
        return pushKYJDTO;
    }

    /**
     * 将list 转换成 map
     *
     * @param list
     * @return
     */
    public Map<String, Object> list2Map(List<FeatureRate> list) {
        Map<String, Object> map = new LinkedHashMap<>();
        for (FeatureRate featureRate : list) {
            map.put(featureRate.getFeatureName(), null);
        }
        return map;
    }


    /**
     * 快易检结果预处理
     *
     * @param lisKYJVO
     * @return
     */
    public LisKYJVO resultCalculation(LisKYJVO lisKYJVO) {
        if (lisKYJVO.getValue() != null) {
            if (lisKYJVO.getMaxValue() != null) {
                Integer comResult = lisKYJVO.getValue().compareTo(lisKYJVO.getMaxValue());
                if (comResult > 0) {
                    lisKYJVO.setMultipleState(QuantitativeTypeEnum.Up.getName());
                    if (!lisKYJVO.getMaxValue().equals(0.0)) {
                        lisKYJVO.setMultipleValue(lisKYJVO.getValue() / lisKYJVO.getMaxValue());
                    }
                }
            }
            if (lisKYJVO.getMinValue() != null) {
                Integer comResult = lisKYJVO.getValue().compareTo(lisKYJVO.getMinValue());
                if (comResult < 0) {
                    lisKYJVO.setMultipleState(QuantitativeTypeEnum.Down.getName());
                    if (!lisKYJVO.getMinValue().equals(0.0)) {
                        lisKYJVO.setMultipleValue(lisKYJVO.getValue() / lisKYJVO.getMinValue());
                    }
                }
            }
            if (StringUtil.isBlank(lisKYJVO.getMultipleState())) {
                lisKYJVO.setMultipleState(QuantitativeTypeEnum.Normal.getName());
            }
        }
        return lisKYJVO;
    }

    /**
     * 拼接化验项的文本结果
     *
     * @param lisKYJVO
     * @return
     */
    public List<String> getLisInputs(LisKYJVO lisKYJVO) {
        List<String> stringList = Lists.newArrayList();
        if (StringUtil.isBlank(lisKYJVO.getName())) {
            return stringList;
        } else if (lisKYJVO.getValue() != null) {
            //数值
            String lisText = lisKYJVO.getName() + "," + lisKYJVO.getValue() + " " + lisKYJVO.getUnits();
            stringList.add(lisText);
            //倍数
            if (StringUtil.isBlank(lisKYJVO.getMultipleState())) {
                lisText = lisKYJVO.getName() + "," + lisKYJVO.getMultipleState() + " " + lisKYJVO.getMultipleValue();
                stringList.add(lisText);
            }
        } else if (StringUtil.isBlank(lisKYJVO.getOtherValue())) {
            //阴性阳性和其他文字描述
            String lisText = lisKYJVO.getName() + "," + lisKYJVO.getOtherValue();
            stringList.add(lisText);
        }
        return stringList;
    }

    /**
     * 获取查体模板
     *
     * @param deptName
     * @param pushVO
     * @return
     */
    public List<QuestionDTO> getVitalModule(String deptName, PushVO pushVO) {
        List<QuestionDTO> vitalDTO = Lists.newLinkedList();
        QueryWrapper<DeptInfo> deptInfoQueryWrapper = new QueryWrapper<>();
        deptInfoQueryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey()).
                eq("name", deptName);
        DeptInfo deptInfo = deptInfoFacade.getOne(deptInfoQueryWrapper);
        if (deptInfo == null) {
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "科室信息不存在");
        }

        QueryWrapper<DeptVital> deptVitalQueryWrapper = new QueryWrapper<>();
        deptVitalQueryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey()).
                eq("dept_id", deptInfo.getId());
        List<DeptVital> deptVitalList = deptVitalFacade.list(deptVitalQueryWrapper);
        if (deptVitalList.size() > 0) {
            Map<Long, DeptVital> deptVitalMap = EntityUtil.makeEntityMap(deptVitalList, "vitalId");
            //排序
            QueryWrapper<VitalOrder> vitalOrderQueryWrapper = new QueryWrapper<>();
            vitalOrderQueryWrapper.eq("is_deleted", IsDeleteEnum.N.getKey()).
                    in("question_id", deptVitalMap.keySet()).
                    orderByAsc("order_no");
            List<VitalOrder> vitalOrderList = vitalOrderFacade.list(vitalOrderQueryWrapper);
            Map<Long, VitalOrder> vitalOrderMap = EntityUtil.makeEntityMap(vitalOrderList, "questionId");
            //标签列表
            for (Map.Entry<Long, VitalOrder> entry : vitalOrderMap.entrySet()) {
                QuestionVO questionVO = new QuestionVO();
                questionVO.setAge(pushVO.getAge());
                questionVO.setSexType(pushVO.getSex());
                questionVO.setId(entry.getKey());
                QuestionDTO questionDTO = questionFacade.getById(questionVO);
                if (questionDTO != null) {
                    vitalDTO.add(questionDTO);
                }
            }
        }
        return vitalDTO;
    }
}