package org.diagbot.bigdata.work;

import com.alibaba.fastjson.JSON;
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.ResultMappingFilter;
import org.diagbot.common.push.bean.SearchData;
import org.diagbot.common.push.cache.ApplicationCacheUtil;
import org.diagbot.nlp.feature.FeatureType;
import org.diagbot.nlp.util.Constants;
import org.diagbot.nlp.util.NegativeEnum;
import org.diagbot.nlp.util.NlpCache;

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

/**
 * @ClassName org.diagbot.bigdata.work.ResultDataProxy
 * @Description TODO
 * @Author fyeman
 * @Date 2019/1/16/016 14:55
 * @Version 1.0
 **/
public class ResultDataProxy {
    protected static String[] vital_filter_data = Constants.vital_filter_data;

    public List<FeatureRate> proxy(HttpServletRequest request, BigDataSearchData searchData, List<Map.Entry<String, Float>> featuresOrderList, String featureType) {
        int cursor = 1;
        DecimalFormat df = new DecimalFormat("0.####");
        List<FeatureRate> featureList = new ArrayList<>(10);

        Map<String, String> resultMappingDiagMap = ApplicationCacheUtil.getDoc_result_mapping_diag_map();
        Map<String, Map<String, ResultMappingFilter>> resultMappingFilterMap = ApplicationCacheUtil.getDoc_result_mapping_filter_map();
        Map<String, Map<String, String>> synonymMap = ApplicationCacheUtil.getStandard_info_synonym_map();
        for (Map.Entry<String, Float> entry : featuresOrderList) {
            //过滤特征数据, 过滤低于阈值的数据
            if (!resultFilter(request, searchData, featureType, entry.getKey(), entry.getValue(), synonymMap)) {
                continue;
            }
            //性别年龄过滤
            Map<String, ResultMappingFilter> filterMap = resultMappingFilterMap.get(featureType);
            if (filterMap != null) {
                ResultMappingFilter filter = filterMap.get(entry.getKey());
                if (filter != null) {
                    if (filter.getSex() != null && !StringUtils.isEmpty(searchData.getSex()) && !"3".equals(searchData.getSex()) && !"3".equals(filter.getSex())
                            && !filter.getSex().equals(searchData.getSex())) {      //性别过滤
                        continue;
                    }
                    //年龄过滤
                    if (filter.getAgeStart() > -1 && searchData.getAge() != 0 && searchData.getAge() < filter.getAgeStart()) {
                        continue;
                    }
                    if (filter.getAgeEnd() > -1 && searchData.getAge() != 0 && searchData.getAge() > filter.getAgeEnd()) {
                        continue;
                    }
                }
            }
            FeatureRate featureRate = new FeatureRate();
            featureRate.setRate(df.format(entry.getValue()));
            featureRate.setFeatureName(entry.getKey());

            if (FeatureType.parse(featureType) == FeatureType.DIAG) {
                featureRate.setFeatureName(entry.getKey());
                if (StringUtils.isNotEmpty(resultMappingDiagMap.get(entry.getKey()))) {
                    featureRate.setExtraProperty(resultMappingDiagMap.get(entry.getKey()));
                }
            }
            featureList.add(featureRate);
                if (cursor < searchData.getLength()) {
                    cursor++;
                } else {
                    break;
                }
        }

        return featureList;
    }

    public boolean resultFilter(HttpServletRequest request, BigDataSearchData searchData, String featureType, String result, float threshold, Map<String, Map<String, String>> synonymMap) {
        //过滤录入条件中已有的特征信息
        if (searchData.getGraphInputs().get(result) != null && FeatureType.parse(featureType) != FeatureType.DIAG) {
            return false;
        }
        if (FeatureType.parse(featureType) == FeatureType.SYMPTOM) {
            if (searchData.getGraphInputs().get(synonymMap.get(Constants.word_property_symptom).get(result))!= null) {
                return false;
            }
        }
        int searched_position = Arrays.binarySearch(vital_filter_data, result);
        if (searched_position > -1) {
            return false;
        }
        return true;
    }

    public Map<String, Float> synonymConvert(HttpServletRequest request, Map<String, Float> map, String featureType) {
        Map<String, Map<String, String>> standardInfoSynonymMap = NlpCache.getStandard_info_synonym_map();
        Map<String, Float> result = new HashMap<>();
        String lexiconId = "";
        switch (FeatureType.parse(featureType)) {
            case SYMPTOM:
                lexiconId = NegativeEnum.SYMPTOM.toString();
                break;
            case DIAG:
                lexiconId = NegativeEnum.DISEASE.toString();
                break;
            case VITAL:
                lexiconId = NegativeEnum.VITAL_RESULT.toString();
                break;
            case LIS:
                lexiconId = NegativeEnum.LIS_TYPE.toString();
                break;
            case PACS:
                lexiconId = NegativeEnum.PACS_NAME.toString();
                break;
        }
        Map<String, String> synonymMap = standardInfoSynonymMap.get(lexiconId);
        if (synonymMap == null) return map;

        result = mapAdd(map, synonymMap, false);
        return result;
    }

    public Map<String, Float> mapAdd(Map<String, Float> map, Map<String, String> convertMap, boolean isFilter) {
        if (convertMap == null) return map;

        Map<String, Float> result = new HashMap<>();
        String synonym = "";
        for (Map.Entry<String, Float> entry : map.entrySet()) {
            synonym = convertMap.get(entry.getKey());
            if (synonym != null) {
                if (result.get(synonym) == null) {
                    result.put(synonym, entry.getValue());
                } else {
                    result.put(synonym, result.get(synonym) + entry.getValue());
                }
            } else if (!isFilter) {
                result.put(entry.getKey(), entry.getValue());
            }
        }
        return result;
    }

    /**
     * 化验辅检体征，年龄性别过滤
     *
     * @param responseData
     * @param searchData
     * @return
     */
    public ResponseData resultSexAgeFilter(HttpServletRequest request, ResponseData responseData, SearchData searchData) {
        if (responseData.getLabs().size() > 0) {//化验
            responseData.setLabs(sexFilter(request, responseData.getLabs(), searchData, Constants.feature_type_lis));
        }
        if (responseData.getPacs().size() > 0) {//辅检
            responseData.setPacs(sexFilter(request, responseData.getPacs(), searchData, Constants.feature_type_pacs));
        }
        if (responseData.getVitals().size() > 0) {//查体
            responseData.setVitals(sexFilter(request, responseData.getVitals(), searchData, Constants.feature_type_vital));
        }
        return responseData;
    }

    public List<FeatureRate> sexFilter(HttpServletRequest request, List<FeatureRate> featureList, SearchData searchData, String featureType) {
        List<FeatureRate> featureRates = new ArrayList<>(10);//用来存放传入的数据结果
        List<FeatureRate> featureRateList = new ArrayList<>(10);//用来存放返回结果
        Map<String, Map<String, ResultMappingFilter>> resultMappingFilterMap = ApplicationCacheUtil.getDoc_result_mapping_lpvSex_filter_map();
        boolean isFirst = false;
        for (int i = 0; i < featureList.size(); i++) {
            FeatureRate entity = JSON.parseObject(JSON.toJSONString(featureList.get(i)), FeatureRate.class);
            featureRates.add(entity);
        }
        for (FeatureRate featureRate : featureRates) {
            isFirst = false;
            //性别年龄过滤
            Map<String, ResultMappingFilter> filterMap = resultMappingFilterMap.get(featureType);
            if (filterMap != null) {
                ResultMappingFilter filter = filterMap.get(featureRate.getFeatureName());
                if (filter != null) {
                    if (filter.getSex() != null && !StringUtils.isEmpty(searchData.getSex())
                            && !filter.getSex().equals(searchData.getSex())) {      //性别过滤
                        isFirst = true;
                    } else {
                        isFirst = false;
                    }
                    //年龄过滤
                    if (filter.getAgeStart() > -1 && searchData.getAge() != 0 && searchData.getAge() < filter.getAgeEnd()) {
                        isFirst = true;
                    } else {
                        isFirst = false;
                    }
                    if (filter.getAgeEnd() > -1 && searchData.getAge() != 0 && searchData.getAge() > filter.getAgeStart()) {
                        isFirst = true;
                    } else {
                        isFirst = false;
                    }
                }
                if (isFirst) {
                    featureRateList.add(featureRate);
                }
            }
        }
        return featureRateList;
    }

}
