package org.diagbot.graphWeb.work;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.diagbot.common.push.bean.FeatureRate;
import org.diagbot.common.push.bean.ResponseData;
import org.diagbot.common.push.bean.SearchData;
import org.diagbot.common.push.bean.neo4j.Filnlly;
import org.diagbot.common.push.bean.neo4j.MangementEvaluation;
import org.diagbot.common.push.bean.neo4j.MedicalIndication;
import org.diagbot.common.push.bean.neo4j.MedicalIndicationDetail;
import org.diagbot.common.push.cache.CacheUtil;
import org.diagbot.graph.jdbc.DriverManager;
import org.diagbot.graph.jdbc.Neo4jAPI;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import org.diagbot.nlp.rule.module.PreResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GraphCalculate {
    Logger logger = LoggerFactory.getLogger(GraphCalculate.class);
    private static Neo4jAPI neo4jAPI ;

    /**
     * 返回诊断和治疗
     *
     * @param request
     * @param searchData
     * @return
     * @throws Exception
     */
    public ResponseData calculate(HttpServletRequest request, SearchData searchData) throws Exception {

        long starttime = System.currentTimeMillis();
        System.out.println("Start at: " + starttime);
        ResponseData responseData = new ResponseData();
//        ParamsDataProxy paramsDataProxy = new ParamsDataProxy();
//        paramsDataProxy.createSearchData(request, searchData);
        List<String> inputList = new ArrayList<>();
        int age = searchData.getAge();
        String sex = searchData.getSex();
        String diseaseName = searchData.getDiseaseName();
        logger.info("前端传来的年龄为 :"+age+" 前端传来的性别为 :"+sex);
        Map<String, Map<String, String>> sexAgeCache = CacheUtil.getSexAgeCache();
        Map<String, Map<String, String>> inputs = searchData.getGraphInputs();
        Set<String> ss = new HashSet<>();
        if(inputs.size()>0){
            for (Map.Entry<String, Map<String, String>> input:inputs.entrySet()) {
                Map<String, String> value = input.getValue();
                String concept = value.get("concept");
                String[] splits = StringUtils.split(concept, ",");
                for (String s:splits) {
                    ss.add(s);
                }
            }
        }

        logger.info("从分词系统接收到的词 :" + ss);
        System.out.println("Participle takes: " + (System.currentTimeMillis()-starttime)/1000d + 's');
        List<String> featureTypeList = Arrays.asList(searchData.getFeatureTypes());
        logger.info("featureTypeList : " + featureTypeList);
        inputList.addAll(ss);
        if(neo4jAPI == null){
            neo4jAPI = new Neo4jAPI(DriverManager.newDrive());
        }
        logger.info("图谱开始推送诊断!!!!!!!!!!!");
        String webDiag = searchData.getDiag();
        logger.info("页面诊断为 :"+webDiag);
        String[] webDiagList = webDiag.split(",|，|、|;|:|；");
        //计算诊断
        Map<String, Object> condition =null;
        Map<String, Map<String, String>> excludelist = null;
        if(featureTypeList.contains("2")){
            condition = neo4jAPI.getNewCondition((String[]) inputList.toArray(new String[inputList.size()]),webDiag );
            // 查找需要排除的诊断
            excludelist = neo4jAPI.getExcludeDiag(inputList);
            responseData.setExcludeDiag(Arrays.asList(excludelist.keySet().stream().toArray(String[]::new)));
        }
        List<FeatureRate> featureRates = new ArrayList<>();
        if(condition != null){
            Map<String, Map<String,String>> allCondition = (Map<String, Map<String,String>>)condition.get("全部诊断");
            if(allCondition != null && allCondition.size()>0){
                for (Map.Entry<String, Map<String,String>> d : allCondition.entrySet()) {
                    String dis = d.getKey();
                    Map<String, String> sexAgeMap = sexAgeCache.get(dis);
                    if(sexAgeMap != null){
                        String sexType = sexAgeMap.get("sexType");
                        Integer min_age = Integer.parseInt(sexAgeMap.get("min_age"));
                        Integer max_age = Integer.parseInt(sexAgeMap.get("max_age"));
                        if(("1".equals(sexType) &&sex.equals(sexType)) || ("2".equals(sexType) &&sex.equals(sexType)) || "3".equals(sexType)){
                            if(min_age <age && age<=max_age){
                                FeatureRate featureRate = new FeatureRate();
                                featureRate.setFeatureName(dis);
                                Map<String, String> value = d.getValue();
                                String s = JSON.toJSONString(value);
                                featureRate.setDesc(s);
                                featureRate.setSource("neo4j");
                                featureRates.add(featureRate);
                            }
                        }
                    }
                }
            }
        }
        Set<String> diseaseSet =null;
        if(condition != null){
            diseaseSet = condition.keySet();
            logger.info("diseaseSet :" + diseaseSet);
        }
        Integer diseaseType = searchData.getDisType();
        List<PreResult> lisArr = searchData.getLisArr();
        Set<String> lisSet = new HashSet<>();
        Map<String,Double> lis_Result = new HashMap<>();
        if(lisArr != null && lisArr.size() > 0){
            for (PreResult lis:lisArr) {
                String detailName = lis.getUniqueName();
                logger.info("公表名为  :"+detailName);
                String lisValue = lis.getValue();
                if(StringUtils.isNotEmpty(lisValue)){
                    Double value = Double.valueOf(lisValue);
                    lis_Result.put(detailName,value);
                    lisSet.add(detailName);
                }
            }
        }
        logger.info("页面导入的所有化验项为 :" +lisSet);
        //走治疗
        if (StringUtils.isNotEmpty(diseaseName) && featureTypeList.contains("6")) {
            // 查找页面诊断里是否有不良反应
            Map<String, List<String>> disUE = neo4jAPI.getDisUE(diseaseName, diseaseType);
            //根据页面输入内容推出的不良反应集合
            Set<String> ue = neo4jAPI.getUe((String[]) inputList.toArray(new String[inputList.size()]));
            //走平常诊断治疗
            Map<String, Filnlly> mulDiseaseTreat = neo4jAPI.getMulDiseaseTreat_2(diseaseName,webDiag, diseaseType, diseaseSet,disUE,ue,String.join(",", inputList));
            responseData.setTreat(mulDiseaseTreat);
        }
        //管理评估(慢病才有)
        if (featureTypeList.contains("11") && diseaseType == 1 && diseaseType != null) {
            logger.info("featureTypeList 包含11,走管理评估!!!");
            if(webDiag != null){
                MangementEvaluation mangementEvaluation = neo4jAPI.pushMe(webDiagList,lis_Result);
                Map<String, JSONObject> mangementEvaluation1 = mangementEvaluation.getMangementEvaluation();
                responseData.setManagementEvaluation(mangementEvaluation1);
            }
        }
        //指标推送
        if (featureTypeList.contains("22") ) {
            List<MedicalIndication> idns =new ArrayList<>();
            Set<String> newindSet = new HashSet<>();
            Set<String> newindSet1 = new HashSet<>();
            //查找指标
            Set<String> indSet = neo4jAPI.getInd((String[]) inputList.toArray(new String[inputList.size()]),sex,age);
            if(indSet != null && indSet.size()>0){
                for (String ind:indSet) {
                    if("肾功能不全".equals(ind)){
                        newindSet.add(ind);
                    }else {
                        newindSet1.add(ind);
                    }
                }
            }
            Map<String, String> indLiang =null;
            if(newindSet1 != null && newindSet1.size()>0){
                indLiang =neo4jAPI.getIndLiang(newindSet1);

            }
            logger.info("featureTypeList 包含22,走指标推送!!!,图谱推出的指标为:" + indSet);
            List<MedicalIndication> idn =null;
            if(newindSet.contains("肾功能不全")){
                idn = neo4jAPI.getIdn(newindSet, age, sex);
                if(idn!= null && idn.size()>0){
                    idns.addAll(idn);
                }
            }
            if(newindSet1 != null && newindSet1.size()>0){
                for (String ind:newindSet1
                     ) {
                    MedicalIndication medicalIndication= new MedicalIndication();
                    medicalIndication.setName(ind);
                    List<MedicalIndicationDetail> ds = new ArrayList<>();
                    MedicalIndicationDetail medicalIndicationDetail = new MedicalIndicationDetail();
                    medicalIndicationDetail.setType(1);
                    JSONObject jsonObject = new JSONObject();
                    if(indLiang != null){
                        jsonObject.put("name",indLiang.get(ind)); 
                    }
                    medicalIndicationDetail.setContent(jsonObject);
                    ds.add(medicalIndicationDetail);
                    medicalIndication.setDetails(ds);
                    idns.add(medicalIndication);
                }
            }
            responseData.setMedicalIndications(idns);
        }
        //诊断推送
        responseData.setDis(featureRates);
        responseData.setInputs(searchData.getInputs());
        System.out.println("Total takes: " + (System.currentTimeMillis()-starttime)/1000d + 's');
        return responseData;
    }
}
