package org.diagbot.common.push.work;

import org.algorithm.core.cnn.AlgorithmCNNExecutorPacs;
import org.algorithm.factory.RelationExtractionFactory;
import org.apache.commons.lang3.StringUtils;
import org.diagbot.common.push.bean.SearchData;
import org.diagbot.common.push.util.PushConstants;
import org.diagbot.nlp.feature.FeatureAnalyze;
import org.diagbot.nlp.feature.FeatureType;
import org.diagbot.nlp.util.Constants;
import org.diagbot.pub.utils.PropertiesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName org.diagbot.bigdata.work.ParamsDataProxy
 * @Description TODO
 * @Author fyeman
 * @Date 2019/1/16/016 14:04
 * @Version 1.0
 **/
public class ParamsDataProxy {
    Logger logger = LoggerFactory.getLogger(ParamsDataProxy.class);
    private String featureNum = "";//特征提取范围

    public void createNormalInfo(SearchData searchData) throws Exception {
        //计算年龄区间
        if (searchData.getAge() > 0) {
            searchData.setAge_start(searchData.getAge() - 5);
            searchData.setAge_end(searchData.getAge() + 5);

            searchData.setNormal("年龄" + searchData.getAge() + "岁");
        }
        //修改性别代码
        if (!StringUtils.isEmpty(searchData.getSex())) {
            if ("M".equals(searchData.getSex())) {
                searchData.setSex("1");
                searchData.setNormal(searchData.getNormal() + "性别男性");
            } else if ("F".equals(searchData.getSex())) {
                searchData.setSex("2");
                searchData.setNormal(searchData.getNormal() + "性别女性");
            } else {
                searchData.setSex("3");
                searchData.setNormal(searchData.getNormal() + "性别其他");
            }
        } else {
            searchData.setSex("3");
        }
    }

    public void createSearchData(SearchData searchData) throws Exception {
        //消除空格
        if (searchData.getSymptom() != null) {
            searchData.setSymptom(searchData.getSymptom().trim());
        }
        if (searchData.getDiag() != null) {
            searchData.setDiag(searchData.getDiag().trim());
        }
        //默认查询门诊数据
        if (StringUtils.isEmpty(searchData.getResourceType())) {
            searchData.setResourceType(PushConstants.resource_type_o);
        }
        if (StringUtils.isNotEmpty(searchData.getSymptom())) {
            searchData.setSymptom(searchData.getSymptom().trim());
        }
        //一次推送多个类别信息
        String[] featureTypes = searchData.getFeatureType().split(",");
        //featureType统一转换
        String[] convertFeatureTypes = new String[featureTypes.length];
        for (int i = 0; i < featureTypes.length; i++) {
            convertFeatureTypes[i] = convertFeatureType(searchData.getSysCode(), featureTypes[i]);
        }
        searchData.setFeatureType(StringUtils.join(convertFeatureTypes, ","));
        searchData.setFeatureTypes(convertFeatureTypes);

        //获取入参中的特征信息
        FeatureAnalyze fa = new FeatureAnalyze();
        List<Map<String, Object>> featuresList = new ArrayList<>();
        //获取配置文件中的特征范围
        PropertiesUtil propertiesUtil = new PropertiesUtil("nlp.properties");
        featureNum = propertiesUtil.getProperty("push.feature.num");
        fa.setFeatureNum(featureNum);
        if (!StringUtils.isEmpty(searchData.getSymptom())) {
            //提取现病史
            featuresList = fa.start(searchData.getSymptom(), FeatureType.FEATURE);
            paramFeatureInit(searchData, featuresList);
            //提取时间信息
            featuresList = fa.start(searchData.getSymptom(), FeatureType.TIME);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getVital())) {
            //提取体征
            featuresList = fa.start(searchData.getVital(), FeatureType.FEATURE);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getPast())) {
            //提取既往史
            featuresList = fa.start(searchData.getPast(), FeatureType.FEATURE);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getOther()) || !StringUtils.isEmpty(searchData.getIndications())) {
            //提取其他史等
            featuresList = fa.start((searchData.getOther() == null ? "" : searchData.getOther()) + (searchData.getIndications() == null ? "" : searchData.getIndications()), FeatureType.FEATURE);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getPacs())) {
            featuresList = fa.start(searchData.getPacs(), FeatureType.PACS);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getLis())) {
            featuresList = fa.start(searchData.getLis(), FeatureType.LIS);
            paramFeatureInit(searchData, featuresList);
        }
        // 清洗特征词，去除词性不匹配的词
        searchData = cleanFeature(featuresList, fa, searchData);
        if (!StringUtils.isEmpty(searchData.getOther())) {
            //如果既往史中诊断信息，需要提取这个特征
            featuresList = fa.start(searchData.getOther(), FeatureType.DIAG);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getDiag()) && StringUtils.isEmpty(searchData.getSymptom())) {
            featuresList = fa.start(searchData.getDiag(), FeatureType.DIAG);
            paramFeatureInit(searchData, featuresList);
        }
        if (!StringUtils.isEmpty(searchData.getPacs())) {
            //关系抽取模型
            AlgorithmCNNExecutorPacs algorithmCNNExecutor = RelationExtractionFactory.getInstance();
            RelationExtractionUtil re = new RelationExtractionUtil();
            //Pacs原始分词结果
            List<List<String>> execute = algorithmCNNExecutor.execute(searchData.getPacs(), re.createTriad(searchData));
            if (execute != null && execute.size() > 0) {
                re.addToSearchDataInputs(execute, searchData);
            }
        }
        //模型需要病历文本信息传入
        Map<String, String> map = new HashMap<>();
        map.put("sentence", searchData.getSymptom());
        searchData.getInputs().put("sentence", map);

    }

    /**
     * 外部系统featureType需要转化为大数据定义的featureType
     *
     * @param sysCode
     * @param featureType
     * @return
     */
    private String convertFeatureType(String sysCode, String featureType) {
        if (StringUtils.isEmpty(sysCode) || sysCode.equals("1")) {
            if ("1".equals(featureType)) {
                return PushConstants.feature_type_symptom;
            }
            if ("7".equals(featureType)) {
                return PushConstants.feature_type_diag;
            }
            if ("4".equals(featureType)) {
                return PushConstants.feature_type_vital;
            }
            if ("5".equals(featureType)) {
                return PushConstants.feature_type_lis;
            }
            if ("6".equals(featureType)) {
                return PushConstants.feature_type_pacs;
            }
            if ("3".equals(featureType)) {
                return PushConstants.feature_type_history;
            }
            if ("8".equals(featureType)) {
                return PushConstants.feature_type_treat;
            }
            if ("22".equals(featureType)) {
                return PushConstants.feature_type_labelpush;
            }
            if ("11".equals(featureType)) {
                return PushConstants.feature_type_manju;
            }
            if ("42".equals(featureType)) {
                return PushConstants.feature_type_vital_index;
            }
            return null;
        }
        return featureType;
    }

    private SearchData cleanFeature(List<Map<String, Object>> featuresList, FeatureAnalyze fa,
                                    SearchData searchData) {
        // 在输入的辅检文本中，只提取辅检信息
        String[] PACS_Feature = { Constants.word_property_PACS,
                Constants.word_property_PACS_Detail, Constants.word_property_PACS_Result };
        searchData = removeFeature(searchData.getLis(), fa, searchData, PACS_Feature, FeatureType.PACS);

        // 在输入的化验文本中，只提取化验信息
        String[] LIS_Feature = { Constants.word_property_LIS,
                Constants.word_property_LIS_Detail, Constants.word_property_LIS_Result };
        searchData = removeFeature(searchData.getPacs(), fa, searchData, LIS_Feature, FeatureType.LIS);

        return searchData;
    }

    private SearchData removeFeature(String text, FeatureAnalyze fa,
                                     SearchData searchData, String[] properties, FeatureType featureType) {
        String name = "";
        Boolean related = false;

        try {
            List<Map<String, Object>> featureList = fa.start(text, featureType);
            if (featureList != null) {
                for (Map<String, Object> item : featureList) {
                    name = item.get("feature_name").toString();
                    String[] property = item.get("property").toString().split(",");
                    for (String prop : property) {
                        if (Arrays.asList(properties).contains(prop)) {
                            //                            related = true;
                            searchData.getInputs().remove(name);
                            break;
                        }
                    }
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            return searchData;
        }
    }

    /**
     * 推送模型入参
     *
     * @param searchData
     * @throws Exception
     */
    private void paramFeatureInit(SearchData searchData, List<Map<String, Object>> featuresList) throws Exception {
        if (featuresList != null && featuresList.size() > 0) {
            Map<String, Object> featureMap = null;
            for (int i = 0; i < featuresList.size(); i++) {
                featureMap = featuresList.get(i);
                Map<String, String> map = new HashMap<>();
                for (Map.Entry<String, Object> entry : featureMap.entrySet()) {
                    map.put(entry.getKey(), String.valueOf(entry.getValue()));
                }
                map.put("featureType", String.valueOf(featureMap.get("feature_type")));
                map.put("featureName", String.valueOf(featureMap.get("feature_name")));
                map.put("property", String.valueOf(featureMap.get("property")));
                map.put("concept", String.valueOf(featureMap.get("concept")));
                if (Constants.default_negative.equals(featureMap.get("negative"))) {
                    if (map.get("featureType").equals(Constants.feature_type_time)) {
//                        searchData.getInputs().put("时间", map);
                    } else {
                        if (searchData.getInputs().get(map.get("feature_name")) == null) {
                            if (i < 8) {
                                searchData.getInputs().put(map.get("feature_name"), map);
                            }
                            searchData.getGraphInputs().put(map.get("feature_name"), map);
                        }
                    }
                } else {
                    searchData.getFilters().put(map.get("feature_name"), map);
                }
            }
        }
    }
}