package org.diagbot.nlp.controller;

import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.diagbot.common.push.bean.RelevantFeature;
import org.diagbot.common.push.cache.ApplicationCacheUtil;
import org.diagbot.nlp.common.NlpWebConstants;
import org.diagbot.nlp.dao.model.Feature;
import org.diagbot.nlp.dao.model.Info;
import org.diagbot.nlp.dao.model.wrapper.FeatureWrapper;
import org.diagbot.nlp.feature.FeatureAnalyze;
import org.diagbot.nlp.feature.FeatureType;
import org.diagbot.nlp.participle.ParticipleUtil;
import org.diagbot.nlp.participle.word.Lexeme;
import org.diagbot.nlp.participle.word.LexemePath;
import org.diagbot.nlp.service.FeatureService;
import org.diagbot.nlp.service.InfoService;
import org.diagbot.nlp.util.Constants;
import org.diagbot.nlp.util.NegativeEnum;
import org.diagbot.nlp.util.NlpCache;
import org.diagbot.nlp.util.NlpUtil;
import org.diagbot.pub.api.Response;
import org.diagbot.pub.jdbc.MysqlJdbc;
import org.diagbot.pub.utils.PropertiesUtil;
import org.diagbot.pub.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/feature")
public class FeatureController extends BaseController<Feature, FeatureWrapper, Long> {
    private String[] negative_words = Constants.negative_words;
    //体征提取范围
    private String featureNum;
    private Map<String, String> propelSymptom = null;
    private Map<String, String> propelDiag = null;
    private Map<String, String> propelVital= null;
    private Map<String, String> propelLis = null;
    private Map<String, String> propelPacs = null;
    private Map<String, RelevantFeature> relevant_feature_map = null;

    {
        listView = "pages/doc/feature/list";
        Arrays.sort(negative_words);
    }

    @Autowired
    InfoService infoService;
    @Autowired
    FeatureService featureService;

    @Autowired
    private Environment env;

    @ModelAttribute
    public void initBinder() {
        super.setBaseService(featureService);
    }

    /**
     * 提取症状信息
     *
     * @return
     */
    @RequestMapping({"/find_symptom_feature"})
    @ResponseBody
    public Response findSymptomFeature(HttpServletRequest request, String text) throws Exception {
        Response response = new Response();

        Map<String, String> classifies = NlpCache.getStandard_info_chronic_map();
        LexemePath<Lexeme> lexemes = ParticipleUtil.participle(text);

        String[] properties = null;
        String[] conceptIds = null;
        List<Map<String, String>> featureList = new ArrayList<>();
        for (Lexeme lexeme : lexemes) {
            if (lexeme.getProperty() == null || lexeme.getConcept() == null) {
                continue;
            }
            properties = lexeme.getProperty().split(",");
            conceptIds = lexeme.getConcept().split(",");
            for (int i = 0; i < properties.length; i++) {
                if (NlpUtil.isFeature(properties[i], new NegativeEnum[]{NegativeEnum.SYMPTOM})) {
                    Map<String, String> map = new HashMap<>();
//                    map.put("conceptId", conceptIds[i]);
                    map.put("name", lexeme.getText());
                    map.put("libType", NegativeEnum.SYMPTOM.toString());
                    map.put("chronicLabel", "0");
                    featureList.add(map);
                }
                if (NlpUtil.isFeature(properties[i], new NegativeEnum[]{NegativeEnum.DISEASE})) {
                    if ("慢病".equals(classifies.get(lexeme.getText()))) {
                        Map<String, String> map = new HashMap<>();
//                        map.put("conceptId", conceptIds[i]);
                        map.put("name", lexeme.getText());
                        map.put("libType", NegativeEnum.DISEASE.toString());
                        map.put("chronicLabel", "0");
                        for (Lexeme l : lexemes) {
                            if (NlpUtil.isFeature(l.getProperty(), new NegativeEnum[]{NegativeEnum.RETURN_VISIT})) {
                                map.put("chronicLabel", "1");
                                featureList = new ArrayList<>();
                                featureList.add(map);
                                response.setData(featureList);
                                return response;
                            }
                        }
                    }
                }
            }
        }
        response.setData(featureList);
        return response;
    }

    /**
     * 提取特征信息
     *
     * @return
     */
    @RequestMapping({"/generate"})
    @ResponseBody
    public Response generate(HttpServletRequest request, String featureTypes, String resourceType) throws Exception {
        Response response = new Response();
        response.start();
        try {
            //提取特征前先删除已有特征
            Map<String, Object> map = new HashMap<>(10);
            map.put("featureType", featureTypes.split(","));
            if (StringUtils.isNotEmpty(resourceType)) {
                map.put("resourceType", resourceType);
            }
            featureService.deleteList(map);

            map = new HashMap<>(10);
            map.put("resourceType", resourceType);
            PageInfo<Info> pageInfo = infoService.selectListPage(map, 0, 10000000);
            List<Info> docInfos = pageInfo.getList();

            initServletAttribute(request);

            String content = "";
            List<Map<String, Object>> featureList = null;
            Map<String, Object> featureMap = null;
            Map<String, String> propel = null;
            List<Map<String, Object>> data = new ArrayList<>();

            PropertiesUtil propertiesUtil = new PropertiesUtil("nlp.properties");
            featureNum = propertiesUtil.getProperty("extract.feature.num");
            Boolean filter = false;//判断是否需要过滤
            if(propertiesUtil.getProperty("extract.feature.filter").equals("1")){//配置为1时过滤
                filter = true;
            }
            if (filter){
                relevant_feature_map = ApplicationCacheUtil.get_relevant_feature();
            }
            FeatureAnalyze sa = new FeatureAnalyze();
            for (String featureType : featureTypes.split(",")) {
                for (String feature : featureNum.split(",")) {
                    sa.setFeatureNum(feature);
                    for (Info info : docInfos) {
                        switch (FeatureType.parse(featureType)) {
                            case SYMPTOM:
                                content = info.getPresent();
                                propel = propelSymptom;
                                break;
                            case TIME:
                                content = info.getPresent();
                                propel = propelSymptom;
                                break;
                            case FEATURE:
                                content = info.getChief() + info.getPresent() + info.getVital();
                                propel = propelSymptom;
                                break;
                            case VITAL:
                                content = info.getVital();
                                propel = propelVital;
                                break;
                            case PACS:
                                content = info.getPacs();
                                propel = propelPacs;
                                break;
                            case LIS:
                                content = info.getLis();
                                propel = propelLis;
                                break;
                            case DIAG:
                                content = info.getDiag();
                                propel = propelDiag;
                                break;
                        }
                        featureList = sa.start(content, FeatureType.parse(featureType));
                        if (featureList == null) {
                            continue;
                        }
                        for (int i = 0; i < featureList.size(); i++) {
                            featureMap = featureList.get(i);
                            featureMap.put("rdn", info.getRdn() + "_" + feature);
                            featureMap.put("age", StringUtils.isEmpty(info.getAge()) ? "0" : info.getAge());
                            featureMap.put("sex", info.getSex());
                            featureMap.put("resource_type", info.getResourceType());
                            if (propel.get(featureMap.get("feature_name")) == null) {
                                featureMap.put("is_push", "0");
                            } else {
                                featureMap.put("is_push", "1");
                            }
                            if(filter){//过滤过的结果
                                if(relevant_feature_map != null){
                                    if(relevant_feature_map.get(info.getDiag()) != null){//获取对应疾病特征信息
                                        if(relevant_feature_map.get(info.getDiag()).getFeature().equals(featureMap.get("feature_name"))){//与特征信息作对比
                                            data.add(featureMap);
                                        }
                                    }
                                }
                            }else {
                                data.add(featureMap);
                            }
                        }

                    }
                }

            }

            MysqlJdbc jdbc = new MysqlJdbc(env.getProperty("spring.datasource.username"),
                    env.getProperty("spring.datasource.password"), env.getProperty("spring.datasource.url"));
            jdbc.insert(data, "doc_feature",
                    new String[]{"rdn", "sex", "age", "feature_name", "feature_type", "is_push", "sn", "negative", "resource_type"});

        } catch (Exception e) {
            e.printStackTrace();
            return response.failure("提取特征失败:" + e.getMessage());
        }
        return response.success();
    }

    public void initServletAttribute(HttpServletRequest request) {
        if (request.getServletContext().getAttribute(NlpWebConstants.standard_info_symptom_propel) == null) {
            propelSymptom = new HashMap<String, String>();
        }
        if (request.getServletContext().getAttribute(NlpWebConstants.standard_info_diag_propel) == null) {
            propelDiag = new HashMap<String, String>();
        }
        if (request.getServletContext().getAttribute(NlpWebConstants.standard_info_vital_propel) == null) {
            propelVital = new HashMap<String, String>();
        }
        if (request.getServletContext().getAttribute(NlpWebConstants.standard_info_lis_propel) == null) {
            propelLis = new HashMap<String, String>();
        }
        if (request.getServletContext().getAttribute(NlpWebConstants.standard_info_pacs_propel) == null) {
            propelPacs = new HashMap<String, String>();
        }
        propelSymptom = (Map<String, String>) request.getServletContext().getAttribute(NlpWebConstants.standard_info_symptom_propel);
        propelDiag = (Map<String, String>) request.getServletContext().getAttribute(NlpWebConstants.standard_info_diag_propel);
        propelVital = (Map<String, String>) request.getServletContext().getAttribute(NlpWebConstants.standard_info_vital_propel);
        propelLis = (Map<String, String>) request.getServletContext().getAttribute(NlpWebConstants.standard_info_lis_propel);
        propelPacs = (Map<String, String>) request.getServletContext().getAttribute(NlpWebConstants.standard_info_pacs_propel);
    }
}
