package org.diagbot.graph.jdbc;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.diagbot.common.javabean.*;
import org.diagbot.common.work.*;
import org.diagbot.pub.utils.PropertiesUtil;
import org.neo4j.driver.v1.*;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.v1.types.Path;
import org.neo4j.driver.v1.types.Relationship;

import java.io.FileWriter;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Neo4j的API接口
 * Created by Mark Huang on 2018/10/29.
 */

public class Neo4jAPI {
    Driver driver = null;
    Calendar calendar = Calendar.getInstance();
    int YY = calendar.get(Calendar.YEAR);
    int MM = calendar.get(Calendar.MONTH) + 1;
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ssss");
    PropertiesUtil propertiesUtil = new PropertiesUtil("bolt.properties");

    public Neo4jAPI(Driver driver) {
        this.driver = driver;
    }

    /**
     * 获取所有标签名称
     *
     * @param
     * @return
     */
    public String GetAllLabels() {
        Session session = null;
        String Res = "";
        StatementResult Rset = null;
        Record rec;
        JSONObject jobj = new JSONObject();


        try {
            session = driver.session(AccessMode.READ);
            String key = "labels(n)";
            String val = "count(*)";
            String query = "MATCH (n) RETURN labels(n), count(*)";

            Rset = session.run(query);
            writeLog(query);

            while (Rset.hasNext()) {
                rec = Rset.next();
                //                System.out.println(rec);
                String lbl = rec.get(key).toString();
                jobj.put(lbl.substring(1, lbl.length() - 1), rec.get(val).toString());
            }

            Res = jobj.toJSONString();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
            return Res;
        }
    }


    /**
     * 获取所有关系名称
     *
     * @param
     * @return
     */
    public String GetAllRelation() {
        Session session = null;
        String Res = "";
        StatementResult Rset = null;
        Record rec;
        JSONObject jobj = new JSONObject();

        try {
            session = driver.session(AccessMode.READ);
            String key = "type(r)";
            String val = "count(*)";
            String query = "MATCH (m)-[r]-(n) RETURN type(r), count(*)";

            Rset = session.run(query);

            while (Rset.hasNext()) {
                rec = Rset.next();

                String lbl = rec.get(key).toString();
                jobj.put(lbl.substring(1, lbl.length() - 1), rec.get(val).toString());
            }

            Res = jobj.toJSONString();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
            return Res;
        }
    }

    /**
     * 处理所有节点的申请
     *
     * @param name   节点名称
     * @param label  标签名称
     * @param prop   节点属性
     * @param origin 原始节点
     * @param newval 新节点
     * @param option 操作标志 (-1:删除,0:查询,1:更新/添加,)
     * @return
     */
    public Map<String, String> ProcessNode(String name, String label, JSONObject prop, JSONObject origin,
                                           JSONObject newval, String option) {
        Map<String, String> Res = new HashMap<>();

        try {
            switch (option) {
                case "-1":
                    Res = RemoveNode(name, label);
                    break;
                case "0":
                    Res = GetNode(name, label, prop);
                    break;
                case "1":
                    if (origin != null) {
                        name = origin.get(Neo4jModel.name).toString();
                        label = origin.get(Neo4jModel.label).toString();
                    }
                    if (newval != null) {
                        prop = newval.getJSONObject(Neo4jModel.property);
                    }
                    UpsertNode(name, label, origin, newval);
                    Res = GetNode(name, label, prop);
                    break;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            return Res;
        }
    }

    /**
     * 查询节点
     *
     * @param name  节点名称
     * @param label 标签名称
     * @param prop  节点属性
     * @return
     */
    public Map<String, String> GetNode(String name, String label, JSONObject prop) {

        Map<String, Object> coll = new HashMap<>();
        Map<String, String> Res = new HashMap<>();
        StatementResult Rset = null;
        Session session = null;
        Map<String, Map<String, String>> Result = new HashMap<>();
        int count = 0;

        try {
            System.out.println("name:\t" + name + "\tlabel:\t" + label);
            session = driver.session(AccessMode.READ);

            String query = "MATCH (n";

            if (name.length() == 0) {
                if (label.trim().length() > 0) {
                    query += ":" + label.trim();
                }

                if (name.trim().length() > 0) {
                    query += "{" + Neo4jModel.name + ":'" + name + "'}";
                }
                query += ") ";

                if (prop.size() > 0) {
                    query += " WHERE ";
                    for (String key : prop.keySet()) {
                        query += "n." + key + "='" + prop.get(key) + "'";
                        count += 1;
                        if (count < prop.size()) {
                            query += " AND ";
                        }
                    }
                }
            } else if (label.length() == 0) {
                String[] namelist = name.split("，|,|、");

                query += ") WHERE ";

                for (String item : namelist) {
                    if (item.indexOf("*") >= 0) {

                        item = item.replaceAll("\\*", ".*");
                        query += "n.name=~'" + item + "' or ";
                    } else {
                        query += "n.name='" + item + "' or ";
                    }
                }

                query = query.substring(0, query.length() - 3);
            }

            query += " RETURN n LIMIT 50";

            Rset = session.run(query);

            writeLog(query);

            while (Rset.hasNext()) {
                Record rec = Rset.next();
                Node node = rec.get("n").asNode();
                String lbl = "";
                name = "";
                Result = new HashMap<>();

                Iterator<String> lbls = node.labels().iterator();

                while (lbls.hasNext()) {
                    lbl = lbls.next();
                    Result.put(lbl, new HashMap<>());
                }

                Map<String, Object> property = node.asMap();
                for (String key : property.keySet()) {
                    Result.get(lbl).put(key, property.get(key).toString());

                    if (key.equals("name")) {
                        name = property.get(key).toString();
                    }
                }

                if (coll.get(name) == null) {
                    coll.put(name, (Object) Result);
                } else {
                    JSONObject jobj = JSONObject.parseObject(JSONUtils.toJSONString(coll.get(name)));
                    jobj.put(lbl, Result.get(lbl));
                    coll.put(name, (Object) jobj);
                }

                //                System.out.println(name + "\t" + lbl + "\t" + JSONUtils.toJSONString(Result));
            }

            for (String key : coll.keySet()) {
                String val = JSONUtils.toJSONString(coll.get(key));
                Res.put(key, val);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
            return Res;
        }
    }

    /**
     * 更新节点
     *
     * @param name   节点名称
     * @param label  标签名称
     * @param origin 原始节点
     * @param newval 新节点
     * @return
     */
    public void UpsertNode(String name, String label, JSONObject origin, JSONObject newval) {
        Map<String, String> Res = new HashMap<>();
        Session session = null;
        String query, createset, matchset, val;
        JSONObject prop = new JSONObject();

        try {
            session = driver.session(AccessMode.WRITE);

            if (origin != null) {
                prop = newval.getJSONObject(Neo4jModel.property);
            }

            query = "MERGE (n";
            createset = " on CREATE SET ";
            matchset = " on MATCH SET ";

            if (label.trim().length() > 0) {
                query += ":" + label;
            }

            if (name.trim().length() > 0) {
                query += "{name:'" + name + "'}";
                createset += " n.name='" + name + "', ";
            }

            for (String key : prop.keySet()) {
                val = prop.get(key).toString();
                createset += " n." + key + "='" + val + "', ";
                matchset += " n." + key + "='" + val + "', ";
            }

            createset = createset.substring(0, createset.length() - 2);
            matchset = matchset.substring(0, matchset.length() - 2);
            query += ")" + createset + matchset;

            session.run(query);

            writeLog(query);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
        }
    }

    /**
     * 删除节点
     *
     * @param name  节点名称
     * @param label 标签名称
     * @return
     */
    public Map<String, String> RemoveNode(String name, String label) {
        Session session = null;

        Map<String, String> Res = new HashMap<>();

        StatementResult Rset = null;
        String query = "";
        try {
            session = driver.session(AccessMode.WRITE);

            String cond = "MATCH (n";

            if (label.trim().length() > 0) {
                cond += ":" + label.trim();
            }
            cond += ") ";

            if (name.trim().length() > 0) {
                cond += " WHERE n.name = " + name;
            }

            query = cond + " DETACH DELETE n; ";

            session.run(query);
            writeLog(query);

            Res = GetNode(name, label, new JSONObject());
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
            return Res;
        }
    }


    /**
     * 获取节点信息
     *
     * @param node 节点
     * @return
     */
    public String GetNodeInfo(Node node) {
        String res = "";
        String lbl = "", name = "";
        Map<String, Map<String, String>> resmap = new HashMap<>();
        Map<String, String> content = new HashMap<>();
        try {
            Iterator<String> lbls = node.labels().iterator();

            while (lbls.hasNext()) {
                lbl += lbls.next() + ",";
            }
            lbl = lbl.substring(0, lbl.length() - 1);

            content.put(Neo4jModel.label, lbl);

            Map<String, Object> property = node.asMap();
            for (String key : property.keySet()) {
                content.put(key, property.get(key).toString());
            }

            if (content.get(Neo4jModel.name) != null && content.get(Neo4jModel.name).toString().trim().length() > 0) {
                name = content.get(Neo4jModel.name).toString();
            } else if ((content.get("title") != null && content.get("title").toString().trim().length() > 0)) {
                name = content.get("title").toString();
            } else {
                name = "name";
            }

            resmap.put(name, content);
            res = JSONUtils.toJSONString(resmap);
            //            System.out.println(res);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            return res;
        }
    }

    /**
     * 处理所有路径的申请
     *
     * @param name     路径名称
     * @param label    标签名称
     * @param start    起始节点
     * @param end      终止节点
     * @param oldrel   原始关系名称
     * @param relation 新关系名称
     * @param option   操作标志 (-1:删除,0:查询,1:更新/添加,)
     * @return
     */
    public Map<String, String> ProcessPath(String name, String label, String level, JSONObject start,
                                           JSONObject end, String oldrel, String relation, String option) {
        Map<String, String> Res = new HashMap<>();

        try {
            switch (option) {
                case "-1":
                    RemovePath(start, end, oldrel);
                    //                    Res = GetPath(name, label, "1");
                    break;
                case "0":
                    Res = GetPath(name, label, level);
                    break;
                case "1":
                    if (start != null) {
                        name = start.get(Neo4jModel.name).toString();
                        label = start.get(Neo4jModel.label).toString();
                    }
                    UpsertPath(start, end, oldrel, relation);
                    Res = GetPath(name, label, "1");
                    break;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            return Res;
        }
    }

    /**
     * 获取路径
     *
     * @param name  路径名称
     * @param label 标签名称
     * @param level 路径层级
     * @return
     */
    public Map<String, String> GetPath(String name, String label, String level) {
        Session session = null;
        StatementResult result;
        Map<String, Map<String, String>> coll = new HashMap<>();
        Map<String, String> route = new HashMap<>();
        Record rec;
        int count = 0;
        String Path = "";
        String query = "";
        Map<String, String> Res = new HashMap<>();

        try {
            session = driver.session(AccessMode.READ);

            if (label.equals("Relation")) {
                if (level.length() == 0 || level.equals("0")) {
                    level = "2";
                }
                query = "MATCH p=((n{name:'" + name + "'})-[*.." + level + "]-(e)) RETURN p";
            } else if (name.length() == 0) {
                level = "2";
                query = "MATCH p=((n:" + label + ")-[*.." + level + "]-(e)) RETURN p";
            } else {
                if (level.length() == 0) {
                    level = "3";
                }

                String[] items = name.split(",|，|、");
                query = "MATCH p=((n)-[*.." + level + "]-(c:" + label + ")) WHERE n.name in [";
                for (int i = 0; i < items.length; i++) {
                    query += "'" + items[i] + "',";
                }
                query = query.substring(0, query.length() - 1);
                query += "] ";
                query += "RETURN p";
            }

            result = session.run(query);

            writeLog(query);
            System.out.println(query);

            while (result.hasNext()) {
                rec = result.next();
                Path path = rec.get("p").asPath();
                Iterator<Path.Segment> iterator = path.iterator();

                while (iterator.hasNext()) {
                    route = new HashMap<>();
                    Path.Segment element = iterator.next();
                    Node start = element.start();
                    String snode = GetNodeInfo(start);

                    Relationship relation = element.relationship();
                    String rel = relation.type();

                    Node end = element.end();
                    String enode = GetNodeInfo(end);

                    if (start.id() == relation.startNodeId()) {
                        route.put("start", snode);
                        route.put("end", enode);
                    } else if (start.id() == relation.endNodeId()) {
                        route.put("start", enode);
                        route.put("end", snode);
                    }

                    route.put("relation", rel);

                    coll.put(Integer.toString(count), route);
                    count += 1;
                }
            }

            Res.put("path", JSONUtils.toJSONString(coll));

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
            return Res;
        }
    }

    /**
     * 更新路径
     *
     * @param start    起始节点
     * @param end      终止节点
     * @param oldrel   原始关系名称
     * @param relation 新关系名称
     * @return
     */
    public void UpsertPath(JSONObject start, JSONObject end, String oldrel, String relation) {
        Session session = null;
        String query = "";

        try {
            session = driver.session(AccessMode.WRITE);

            query = "MATCH (s:" + start.getString(Neo4jModel.label);

            if (start.get(Neo4jModel.name) != null) {
                query += "{name:'" + start.getString(Neo4jModel.name) + "'})";
            }

            query += "-[r:" + oldrel + "]->";

            query += "(e:" + end.getString(Neo4jModel.label);

            if (end.get(Neo4jModel.name) != null) {
                query += "{name:'" + end.getString(Neo4jModel.name) + "'}) ";
            }

            query += " CREATE (s)-[r1:" + relation + "]->(e) ";
            query += "SET r1 = r WITH r DELETE r";

            session.run(query);

            writeLog(query);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
        }
    }

    /**
     * 删除路径
     *
     * @param start  起始节点
     * @param end    终止节点
     * @param oldrel 原始关系名称
     * @return
     */
    public void RemovePath(JSONObject start, JSONObject end, String oldrel) {

        Session session = null;
        String query = "";

        try {
            session = driver.session(AccessMode.WRITE);

            query = "MATCH (s:" + start.getString(Neo4jModel.label);

            if (start.get(Neo4jModel.name) != null) {
                query += "{name:'" + start.getString(Neo4jModel.name) + "'})";
            }

            query += "-[r:" + oldrel + "]->";

            query += "(e:" + end.getString(Neo4jModel.label);

            if (end.get(Neo4jModel.name) != null) {
                query += "{name:'" + end.getString(Neo4jModel.name) + "'}) ";
            }

            query += " DELETE r; ";

            session.run(query);

            writeLog(query);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
        }
    }

    /**
     * 只包含返回确诊的
     *
     * @param keys
     * @return
     */
    public Map<String, String> getCondition(String[] keys) {
        Map<String, String> conditionMap = new LinkedHashMap<>();
        Map<String, String> diseaseCondition = new LinkedHashMap<>();
        List<String> newList = new ArrayList<>();
        ArrayList<String> fildList = new ArrayList<>();
        //输出确诊集合
        Set<String> quezhen = new LinkedHashSet<>();
        for (String fild : keys) {
            fildList.add("\"" + fild.trim() + "\"");
        }
        Session session = null;
        StatementResult result = null;
        String query = "";
        try {
            session = driver.session(AccessMode.WRITE);
            //第一步查询是否有组合的词
            query = propertiesUtil.getProperty("searchCollection").replace("fildList",fildList.toString());
            result = session.run(query);
            while (result.hasNext()){
                Record next = result.next();
                String jundgement = next.get("jundgement").toString();
                String standName = next.get("standName").toString();
                if ("TRUE".equals(jundgement)){
                    fildList.add(standName);
                }
            }
            query = propertiesUtil.getProperty("serchCollect").replace("fildList", fildList.toString());
            result = session.run(query);
            while (result.hasNext()) {
                Record record = result.next();
                String fild = record.get("fild").toString();
                List<Object> typeCollect = record.get("typeCollect").asList();
                //如果不包含诊断依据就找它的同义词,否则就要这个词
                if ("近义词".equals(typeCollect.get(0)) && typeCollect.size() == 1) {
                    query = "match(l)-[r:近义词]->(h) where l.name=" + fild + " return h.name as js";
                    StatementResult jinyiResult = session.run(query);
                    while (jinyiResult.hasNext()) {
                        Record next = jinyiResult.next();
                        String js = next.get("js").toString();
                        fildList.remove(fild);
                        fildList.add(js);
                    }
                }
//                else {
//                    fildList.add(fild);
//                    query = "match(l)-[r:近义词]->(h) where l.name="+fild+" return h.name as js";
//                    StatementResult run1 = session.run(query);
//                    while (run1.hasNext()){
//                        Record next = run1.next();
//                        String js = next.get("js").toString();
//                        fildList.add(js);
//                    }
//                }
            }
            newList.addAll(fildList);
            int i = 0;
            while (newList.size() > 0) {
                i++;
                query = propertiesUtil.getProperty("searchCondition").replace("newList",newList.toString()).replace("fildList",fildList.toString());
                result = session.run(query);
                newList.clear();
                while (result.hasNext()) {
                    Record record = result.next();
                    String condition = record.get("condition").toString();
                    String jundgement = record.get("jundgement").toString();
                    String label = record.get("label").toString();
                    if ("TRUE".equals(jundgement)) {
                        newList.add(condition);
                        fildList.add(condition);
                    }
                }
            }
            //第三步查找确诊
            query = propertiesUtil.getProperty("searchQuezhen").replace("fildList",fildList.toString());
            result = session.run(query);
            while (result.hasNext()) {
                Record record = result.next();
                String quezhenName = record.get("name").toString().replace("\"", "");
                String conditionType = record.get("relationType").toString().replace("\"", "");
                if ("确诊".equals(conditionType)) {
                    quezhen.add(quezhenName);
                } else if ("拟诊".equals(conditionType)) {
                    quezhen.add(quezhenName);
                }
            }
            for (String qu : quezhen) {
                Map<String, String> dis_res = new HashMap<>();
                dis_res.put("确诊", "");
                diseaseCondition.put(qu, JSON.toJSONString(dis_res));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseSession(session);
            return diseaseCondition;
        }
    }

    /**
     * 新的诊断逻辑
     * 包含确诊和疑诊集合
     *
     * @param iputList
     * @return
     */
    public Map<String, ArrayList> newConditionProcess(ArrayList<String> iputList) {
        Map<String, ArrayList> conditionMap = new HashMap<>();
        ArrayList<String> quezhenList = new ArrayList<>();
        ArrayList<String> yizhenList = new ArrayList<>();
        //处理原始输入
        List<String> arrayList = inputProcess(iputList);
        List<String> newList = new ArrayList<>();
        newList.addAll(arrayList);
        Session session = null;
        StatementResult stat = null;
        String query = "";
        try {
            session = driver.session(AccessMode.READ);
            while (newList.size() > 0) {
                //查找符合条件的判断节点
                query = "with " + newList + " as data unwind data as row\n" +
                        "match (l)-[r:诊断依据]->(m)\n" +
                        "where row.label in labels(l) and l.name=row.name\n" +
                        "with m," + arrayList + " as data unwind data as row\n" +
                        "match (n)-[r:诊断依据]->(m)\n" +
                        "where row.label in labels(n) and n.name=row.name\n" +
                        "return m.name as condition, count(distinct r)>=m.path as jundgement, labels(m)[0] as label";
                stat = session.run(query);
                newList.clear();
                while (stat.hasNext()) {
                    Record record = stat.next();
                    String condition = record.get("condition").toString();
                    String jundgement = record.get("jundgement").toString();
                    String label = record.get("label").toString();
                    if ("TRUE".equals(jundgement)) {
                        newList.add("{label:" + label + ",name:" + condition + "}");
                        arrayList.add("{label:" + label + ",name:" + condition + "}");
                    }
                }
            }
            //计算确诊,可能诊断
            query = "with " + arrayList + " as data unwind data as row\n" +
                    "match (n)-[r:确诊|:可能诊断]->(m)\n" +
                    "where row.label in labels(n) and n.name=row.name\n" +
                    "with distinct m,r\n" +
                    "return m.name as name, labels(m)[0] as label,type(r) as relationType";
            stat = session.run(query);
            while (stat.hasNext()) {
                Record record = stat.next();
                if ("\"确诊\"".equals(record.get("relationType").toString())) {
                    quezhenList.add(record.get("name").toString().replaceAll("\"", ""));
                } else if ("\"可能诊断\"".equals(record.get("relationType").toString())) {
                    yizhenList.add(record.get("name").toString().replaceAll("\"", ""));
                }
            }
            conditionMap.put("确诊", quezhenList);
            conditionMap.put("可能诊断", yizhenList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseSession(session);
            return conditionMap;
        }
    }

    /**
     * 多疾病下治疗方案
     *
     * @param disease
     * @param filds
     * @return
     */
    public Map<String, String> getMulDiseaseTreat(String disease, String filds) {
        Session session = null;
        NumberFormat nf = NumberFormat.getPercentInstance();
        Map<String, String> resultMap = new HashMap<>();
        String[] diseaseArray = disease.split(",|，|、");
        List<String> diseaseList = new ArrayList<>();//诊断数组
        for (int i = 0; i < diseaseArray.length; i++) {
            diseaseList.add(diseaseArray[i]);
        }
        Map<String, ArrayList> diseFilds = new HashMap<>();
        for (int i = 0; i < diseaseList.size(); i++) {
            String[] fildsArray = filds.split(",");
            ArrayList<String> fildsList = new ArrayList<>();//其他条件数组
            for (String fild : fildsArray) {
                fildsList.add("\'" + fild + "\'");
            }
            for (int j = 0; j < diseaseList.size(); j++) {
                if (i != j) {
                    fildsList.add("\'" + diseaseList.get(j) + "\'");
                }
            }
            diseFilds.put(diseaseList.get(i), fildsList);
        }
        try {
            session = driver.session(AccessMode.WRITE);
            session.writeTransaction(new TransactionWork<Integer>() {
                @Override
                public Integer execute(Transaction tx) {
                    StatementResult result = null;
                    String query = "";
                    for (Map.Entry<String, ArrayList> df : diseFilds.entrySet()) {
                        String diseaseName = df.getKey();//疾病
                        ArrayList value = df.getValue();//其他条件
                        StringBuffer s1 = new StringBuffer();
                        s1.append("match (d:Disease{name:'" + disease + "'})-[r0:推荐]->(m:Drugs)-[:包含]->(n:Medicine),(d)-[r1:推荐]->(n)");
                        s1.append("\n");
                        s1.append("where r0.p<6").append("\n");
                        s1.append("return m.name as 类, r0.p as sort, n.name as 药物, r1.rate as a order by sort , a desc");
                        query = s1.toString();
                        result = tx.run(query);
                        LinkedHashMap<String, LinkedHashMap<String, String>> contentMap = new LinkedHashMap<>();
                        while (result.hasNext()) {
                            Record record = result.next();
                            String[] splits = record.values().toString().split(",");
                            String drugs = splits[0].replace("[", "").replace("\"", "");
                            if (contentMap.containsKey(drugs)) {
                                LinkedHashMap<String, String> stringStringHashMap = contentMap.get(drugs);
                                stringStringHashMap.put(splits[2].replace("\"", ""), splits[3].replace("]", ""));
                                contentMap.put(drugs, stringStringHashMap);
                            } else {
                                LinkedHashMap<String, String> sa = new LinkedHashMap<>();
                                sa.put(splits[2].replace("\"", ""), splits[3].replace("]", ""));
                                contentMap.put(drugs, sa);
                            }
                        }

                        HashMap<String, String> shortLargeMap = new HashMap<>();
                        //大项查询
                        query = "match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d:Drugs)<-[:包含]-(m) return d.name as short,m.name as large";
                        result = tx.run(query);
                        while (result.hasNext()) {
                            Record record = result.next();
                            String aShort = record.get("short").toString().replace("\"", "");
                            String large = record.get("large").toString().replace("\"", "");
                            shortLargeMap.put(aShort, large + "(" + aShort + ")");
                        }
                        LinkedHashMap<String, LinkedHashMap<String, String>> mapSortValueDa = new LinkedHashMap<>();
                        for (Map.Entry<String, LinkedHashMap<String, String>> f : contentMap.entrySet()
                                ) {
                            String key = f.getKey();
                            if (shortLargeMap.get(key) != null) {
                                mapSortValueDa.put(shortLargeMap.get(key), contentMap.get(key));
                            } else {
                                mapSortValueDa.put(key, contentMap.get(key));
                            }
                        }
                        /**
                         * mapSortValueDa是包含大小项的Map
                         * 抗胃酸药(质子泵抑制剂)  兰索拉唑  0.85
                         */

                        Map<String, String> medicationUseMap = new HashMap<>();//key:药名 value:禁忌(慎用)
                        StringBuffer fildBuffer = new StringBuffer();
                        fildBuffer.append("match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d)<-[r0:慎用]-(m)").append("\n");
                        fildBuffer.append("where m.name in " + value + "").append("\n");
                        fildBuffer.append("return d.name as ff,type(r0) as hh").append("\n").append("union\n");
                        fildBuffer.append("match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d)<-[r0:忌用]-(m)\n");
                        fildBuffer.append("where m.name in " + value + "").append("\n");
                        fildBuffer.append("return d.name as ff,type(r0) as hh");
                        query = fildBuffer.toString();
                        result = tx.run(query);
                        while (result.hasNext()) {
                            Record next = result.next();
                            String name = next.get("ff").toString().replace("\"", "");//药名
                            String type = next.get("hh").toString().replace("\"", "");//忌用(慎用)
                            medicationUseMap.put(name, type);
                        }
                        //大对象集合
                        ArrayList<Drugs> drugs = new ArrayList<Drugs>();
                        for (Map.Entry<String, LinkedHashMap<String, String>> w : mapSortValueDa.entrySet()) {
                            int i = 0;
                            Drugs drugs1 = new Drugs();
                            //                                drugs1.setDrugsName(w.getKey().trim());//药类
                            LinkedList<Medicition> medicitions = new LinkedList<>();
                            LinkedHashMap<String, String> value2 = w.getValue();
                            for (Map.Entry<String, String> d : value2.entrySet()) {
                                Medicition medicition = new Medicition();
                                medicition.setMedicitionName(d.getKey().trim());//药名
                                medicition.setRate(nf.format(Double.parseDouble(d.getValue().trim())));//使用率
                                i++;
                                if (i < 2) {
                                    medicition.setIsShow(1);//展示
                                } else {
                                    medicition.setIsShow(0);//不展示
                                }
                                if ("忌用".equals(medicationUseMap.get(d.getKey().trim()))) {
                                    medicition.setForbidden(2);
                                } else if ("慎用".equals(medicationUseMap.get(d.getKey().trim()))) {
                                    medicition.setForbidden(1);
                                } else {
                                    medicition.setForbidden(0);
                                }
                                medicitions.add(medicition);
                            }
                            drugs1.setMedicitionsList(medicitions);
                            drugs.add(drugs1);
                        }
                        Filnlly filnlly = new Filnlly();
                        filnlly.setTreatment(drugs);
                        String s = JSON.toJSONString(filnlly);
                        resultMap.put(diseaseName, s);
                    }
                    return 1;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseSession(session);
            return resultMap;
        }
    }

    /**
     * 第二版治疗方案
     *
     * @param disease
     * @param filds   //     * @param sign 标志,2是平常诊断的治疗,0是复诊诊断的治疗,1是急诊
     * @return
     */
    public Map<String, Filnlly> getMulDiseaseTreat_2(String disease, String filds) {
        Map<String, Filnlly> diagTreat = new HashMap<>();
        Session session = null;
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(0);//设置该百分比数字，保留2位小数;
        nf.setRoundingMode(RoundingMode.HALF_UP); //设置满5向上进位，即四舍五入;
        Map<String, String> resultMap = new HashMap<>();
        String[] diseaseArray = disease.split(",|，|、|;|:|；");
        List<String> diseaseList = new ArrayList<>();//诊断数组
        for (int i = 0; i < diseaseArray.length; i++) {
            diseaseList.add(diseaseArray[i]);
        }
        Map<String, ArrayList> diseFilds = new HashMap<>();
        for (int i = 0; i < diseaseList.size(); i++) {
            String[] fildsArray = filds.split(",");
            ArrayList<String> fildsList = new ArrayList<>();//其他条件数组
            for (String fild : fildsArray) {
                fildsList.add("\'" + fild + "\'");
            }
            for (int j = 0; j < diseaseList.size(); j++) {
                if (i != j) {
                    fildsList.add("\'" + diseaseList.get(j) + "\'");
                }
            }
            diseFilds.put(diseaseList.get(i), fildsList);
        }
        try {
            session = driver.session(AccessMode.WRITE);
            Integer integer = session.writeTransaction(new TransactionWork<Integer>() {
                @Override
                public Integer execute(Transaction tx) {
                    StatementResult result = null;
                    String query = "";
                    for (Map.Entry<String, ArrayList> df : diseFilds.entrySet()) {
                        String diseaseName = df.getKey();//疾病
                        ArrayList value = df.getValue();//其他条件
                        StringBuffer s1 = new StringBuffer();
                        s1.append("match (d:Disease{name:'" + diseaseName + "'})-[r0:推荐]->(m:Drugs)-[:包含]->(n:Medicine),(d)-[r1:推荐]->(n)");
                        s1.append("\n");
                        s1.append("where r0.p<6").append("\n");
                        s1.append("return m.name as 类, r0.p as sort, n.name as 药物, r1.rate as a order by sort , a desc");
                        query = s1.toString();
                        result = tx.run(query);
                        Map<String, LinkedHashMap<String, String>> contentMap = new LinkedHashMap<>();
                        while (result.hasNext()) {
                            Record record = result.next();
                            List<Value> values = record.values();
                            String drugs = values.get(0).toString().replace("\"", "");
                            if (contentMap.containsKey(drugs)) {
                                LinkedHashMap<String, String> stringStringHashMap = contentMap.get(drugs);
                                stringStringHashMap.put(values.get(2).toString().replace("\"", ""), values.get(3).toString());
                                contentMap.put(drugs, stringStringHashMap);
                            } else {
                                LinkedHashMap<String, String> sa = new LinkedHashMap<>();
                                sa.put(values.get(2).toString().replace("\"", ""), values.get(3).toString());
                                contentMap.put(drugs, sa);
                            }
                        }
                        //药类型的大小类拼接
                        Map<String, String> shortLargeMap = new HashMap<>();
                        //                        query="match (n:Disease{name:'"+diseaseName+"'})-[:推荐]->(d:Drugs)<-[:包含]-(m) return d.name as short,m.name as large";
                        query = "match (n:Disease{name:'" + diseaseName + "'})-[r0:推荐]->(m:Drugs)-[:包含]->(k:Drugs) return k.name as short,m.name as large";
                        result = tx.run(query);
                        while (result.hasNext()) {
                            Record record = result.next();
                            String aShort = record.get("short").toString().replace("\"", "");
                            String large = record.get("large").toString().replace("\"", "");
                            shortLargeMap.put(aShort, large + "(" + aShort + ")");
                        }
                        Map<String, LinkedHashMap<String, String>> shortLargeMapConcat = new LinkedHashMap<>();
                        for (Map.Entry<String, LinkedHashMap<String, String>> f : contentMap.entrySet()
                                ) {
                            String key = f.getKey();
                            if (shortLargeMap.get(key) != null) {
                                shortLargeMapConcat.put(shortLargeMap.get(key), contentMap.get(key));
                            } else {
                                shortLargeMapConcat.put(key, contentMap.get(key));
                            }
                        }
                        Map<String, String> medicationUseMap = new HashMap<>();//key:药名 value:禁忌(慎用)
                        StringBuffer fildBuffer = new StringBuffer();
                        fildBuffer.append("match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d:Medicine)<-[r0:慎用]-(m)").append("\n");
                        fildBuffer.append("where m.name in " + value + "").append("\n");
                        fildBuffer.append("return d.name as ff,type(r0) as hh").append("\n").append("union\n");
                        fildBuffer.append("match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d:Medicine)<-[r0:忌用]-(m)\n");
                        fildBuffer.append("where m.name in " + value + "").append("\n");
                        fildBuffer.append("return d.name as ff,type(r0) as hh");
                        query = fildBuffer.toString();
                        result = tx.run(query);
                        while (result.hasNext()) {
                            Record next = result.next();
                            String name = next.get("ff").toString().replace("\"", "");//药名
                            String type = next.get("hh").toString().replace("\"", "");//忌用(慎用)
                            medicationUseMap.put(name, type);
                        }
                        /**
                         * 查找药类的忌用
                         */
                        Map<String, String> drugsUseMap = new HashMap<>();//key:药名 value:禁忌(慎用)
                        query = "match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d:Drugs)<-[r0:慎用]-(m)\n" +
                                "where m.name in " + value + "" +
                                "return d.name as ff,type(r0) as hh\n" +
                                "union\n" +
                                "match (n:Disease{name:'" + diseaseName + "'})-[:推荐]->(d:Drugs)<-[r0:忌用]-(m)\n" +
                                "where m.name in " + value + "" +
                                "return d.name as ff,type(r0) as hh";
                        result = tx.run(query);
                        while (result.hasNext()) {
                            Record next = result.next();
                            String name = next.get("ff").toString().replace("\"", "");//类名
                            String type = next.get("hh").toString().replace("\"", "");//忌用(慎用)
                            drugsUseMap.put(name, type);
                        }
                        //大对象集合
                        ArrayList<Drugs> drugsList = new ArrayList<Drugs>();
                        DrugsPattern drugsPattern = new DrugsPattern();
                        for (Map.Entry<String, LinkedHashMap<String, String>> w : shortLargeMapConcat.entrySet()) {
                            int i = 0;
                            Drugs drugs = new Drugs();
                            String drugsName = w.getKey();//药类
                            //                            Map<String, String> bigSubDrugs = new DrugsPattern().bigSubDrugs(drugsName);
                            Map<String, String> bigSubDrugs = drugsPattern.bigSubDrugs(drugsName);
                            drugs.setBigdrugsName(bigSubDrugs.get("big"));
                            drugs.setSubdrugsName(bigSubDrugs.get("sub"));
                            LinkedList<Medicition> medicitionsList = new LinkedList<>();
                            LinkedHashMap<String, String> meditionRate = w.getValue();
                            if ("忌用".equals(drugsUseMap.get(bigSubDrugs.get("big"))) || "忌用".equals(drugsUseMap.get(bigSubDrugs.get("sub")))) {
                                drugs.setDrugsForbidden(2);
                                for (Map.Entry<String, String> g : meditionRate.entrySet()
                                        ) {
                                    Medicition medicition = new Medicition();
                                    String meditionName = g.getKey().trim();//药名
                                    String rate = nf.format(Double.parseDouble(g.getValue().trim()));//百分比
                                    medicition.setMedicitionName(meditionName);
                                    medicition.setRate(rate);
                                    if (i < 3) {
                                        medicition.setIsShow(1);
                                        i++;
                                    } else {
                                        medicition.setIsShow(0);
                                    }
                                    medicition.setForbidden(2);
                                    medicitionsList.add(medicition);
                                }
                            } else if ("慎用".equals(drugsUseMap.get(bigSubDrugs.get("big"))) || "慎用".equals(drugsUseMap.get(bigSubDrugs.get("sub")))) {
                                drugs.setDrugsForbidden(1);
                                for (Map.Entry<String, String> g : meditionRate.entrySet()
                                        ) {
                                    Medicition medicition = new Medicition();
                                    String meditionName = g.getKey().trim();//药名
                                    String rate = nf.format(Double.parseDouble(g.getValue().trim()));//百分比
                                    medicition.setMedicitionName(meditionName);
                                    medicition.setRate(rate);
                                    if (i < 3) {
                                        medicition.setIsShow(1);
                                        i++;
                                    } else {
                                        medicition.setIsShow(0);
                                    }
                                    medicition.setForbidden(1);
                                    medicitionsList.add(medicition);
                                }
                            } else {
                                drugs.setDrugsForbidden(0);
                                for (Map.Entry<String, String> g : meditionRate.entrySet()
                                        ) {
                                    Medicition medicition = new Medicition();
                                    String meditionName = g.getKey().trim();//药名
                                    String rate = nf.format(Double.parseDouble(g.getValue().trim()));//百分比
                                    medicition.setMedicitionName(meditionName);
                                    medicition.setRate(rate);
                                    if (i < 3) {
                                        medicition.setIsShow(1);
                                        i++;
                                    } else {
                                        medicition.setIsShow(0);
                                    }
                                    if ("忌用".equals(medicationUseMap.get(meditionName))) {
                                        medicition.setForbidden(2);
                                    } else if ("慎用".equals(medicationUseMap.get(meditionName))) {
                                        medicition.setForbidden(1);
                                    } else {
                                        medicition.setForbidden(0);
                                    }
                                    medicitionsList.add(medicition);
                                }
                            }
                            drugs.setMedicitionsList(medicitionsList);
                            drugsList.add(drugs);
                        }

                        Filnlly filnlly = new Filnlly();
                        List<Indicators> indicatorsList1 = new ArrayList<>();
                        List<Detail> detailList1 = new ArrayList<>();
                        Detail detail1 = new Detail();
                        detail1.setName("无");
                        detail1.setValue(0);
                        Detail detail2 = new Detail();
                        detail2.setName("偶尔");
                        detail2.setValue(0);
                        Detail detail3 = new Detail();
                        detail3.setName("频");
                        detail3.setValue(0);
                        detailList1.add(detail1);
                        detailList1.add(detail2);
                        detailList1.add(detail3);
                        Indicators indicators1 = new Indicators();
                        indicators1.setName("低血糖反应");
                        indicators1.setControlType(2);
                        indicators1.setDetails(detailList1);
                        indicatorsList1.add(indicators1);

                        List<Detail> detailList2 = new ArrayList<>();
                        Detail detail11 = new Detail();
                        detail11.setName("腹胀");
                        detail11.setValue(0);
                        Detail detail12 = new Detail();
                        detail12.setName("厌食");
                        detail12.setValue(0);
                        Detail detail13 = new Detail();
                        detail13.setName("嗳气");
                        detail13.setValue(0);
                        Detail detail14 = new Detail();
                        detail14.setName("恶心");
                        detail14.setValue(0);
                        Detail detail15 = new Detail();
                        detail15.setName("呕吐");
                        detail15.setValue(0);
                        detailList2.add(detail11);
                        detailList2.add(detail12);
                        detailList2.add(detail13);
                        detailList2.add(detail14);
                        detailList2.add(detail15);
                        Indicators indicators11 = new Indicators();
                        indicators11.setName("胃肠道不良反应");
                        indicators11.setControlType(2);
                        indicators11.setDetails(detailList2);
                        indicatorsList1.add(indicators11);
                        filnlly.setAdverseEvent(indicatorsList1);
                        filnlly.setTreatment(drugsList);
                        diagTreat.put(diseaseName, filnlly);

                    }
                    return 1;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseSession(session);
            return diagTreat;
        }
    }

    /**
     * 倒推实现
     *
     * @param diseaseName
     * @return
     */
    public Map<String, List> getPushBack(String diseaseName, int sign) {
        //        Map<String, String> labelMap = new HashMap<>();
        HashMap<String, List> backMap = new HashMap<>();
        String[] label = { "Symptom", "Vital", "LIS", "PACS", "History" };
        Session session = null;
        StatementResult result = null;
        String query = "";
        try {
            if (sign == 1) {
                session = driver.session(AccessMode.WRITE);
                for (String l : label) {
                    query = "match (d1:Disease{name:'" + diseaseName + "'})-[r1]->(s1:" + l + ") return s1.name as symptom";
                    result = session.run(query);
                    while (result.hasNext()) {
                        String symptom = result.next().get("symptom").toString().replaceAll("\"", "");
                        if (backMap.containsKey(l)) {
                            List symptomList = backMap.get(l);
                            symptomList.add(symptom);
                            backMap.put(l, symptomList);
                        } else {
                            List<String> sList = new ArrayList<>();
                            sList.add(symptom);
                            backMap.put(l, sList);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseSession(session);
        }

        return backMap;
    }

    /**
     * 高危逻辑
     *
     * @param diseaseName
     * @return
     */
    public Map<String, String> getHighRisk(String diseaseName) {
        String[] diseaseArray = diseaseName.split(",|，|、");
        List<String> diseaseList = new ArrayList<>();
        for (String di : diseaseArray) {
            diseaseList.add("'" + di + "'");
        }
        Map<String, String> riskMap = new HashMap<>();
        Session session = null;
        StatementResult result = null;
        String query = "match(d:Disease) where d.name in " + diseaseList + " return d.name as name, d.high_risk as risk";
        try {
            session = driver.session(AccessMode.WRITE);
            result = session.run(query);
            while (result.hasNext()) {
                Record next = result.next();
                String name = next.get("name").toString().replaceAll("\"", "");
                String risk = next.get("risk").toString();
                riskMap.put(name, risk);
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            CloseSession(session);
            return riskMap;
        }
    }

    /**
     * 反推LIS,PACS
     *
     * @param diseases
     * @return
     */
    public Map<String, Set<String>> getLisPacs(List<String> diseases) {
        Session session = null;
        StatementResult result = null;
        String serchLisPacs = propertiesUtil.getProperty("serchLisPacs");
        String query = null;
        Map<String, Set<FeatureRate>> lisPacsMap = new HashMap<>();
        Map<String, Set<String>> lisPacsMap1 = new HashMap<>();
        List<String> diseaseList = new ArrayList<>();//诊断数组
        for (String dis : diseases) {
            diseaseList.add("\"" + dis + "\"");
        }
        try {
            session = driver.session(AccessMode.WRITE);
            List<FeatureRate> lisList = new ArrayList<>();
            List<FeatureRate> pacsList = new ArrayList<>();
            List<String> lisArray = new ArrayList<>();
            List<String> pacsArray = new ArrayList<>();
            query = serchLisPacs.replace("diseaseNmae", diseaseList.toString());
            System.out.println(query);
            result = session.run(query);
            while (result.hasNext()) {
                Record next = result.next();
                String lei = next.get("lei").toString().replaceAll("\"", "");
                String name = next.get("n").toString().replaceAll("\"", "");
                String subLis = next.get("lr").toString().replaceAll("\"", "");
                if ("LIS".equals(lei)) {
                    lisArray.add(name);
                } else if ("PACS".equals(lei)) {
                    pacsArray.add(name);
                }
            }

            //            lisPacsMap.put("LIS", processList(lisList));
            //            lisPacsMap.put("PACS", processList(pacsList));
            lisPacsMap1.put("LIS", processList(lisArray));
            lisPacsMap1.put("PACS", processList(pacsArray));
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            CloseSession(session);
            return lisPacsMap1;
        }
    }

    public Set<String> processList(List<String> list) {
        Set<String> resultSet = new LinkedHashSet<>();
        Map<String, Integer> featuerInt = new HashMap<String, Integer>();
        for (String d : list) {
            if (featuerInt.containsKey(d)) {
                featuerInt.put(d, featuerInt.get(d) + 1);
            } else {
                featuerInt.put(d, 1);
            }
        }
        List<Map.Entry<String, Integer>> reslist = new ArrayList<Map.Entry<String, Integer>>(featuerInt.entrySet());
        Collections.sort(reslist, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        for (Map.Entry<String, Integer> f : reslist
                ) {
            //排好序的set
            resultSet.add(f.getKey());
        }
        return resultSet;
    }

    /**
     * 化验结果文本化
     *
     * @param lisres
     * @return
     */
    public ArrayList<String> AnalysisLISResult(JSONArray lisres) {
        Session session = null;
        ArrayList<String> reslist = new ArrayList<>();
        JSONObject jobj = null;
        String jsonstr = "";
        String idx = "";

        String regnum = "^([0-9]+[.])*[0-9]+$";
        Pattern patnum = Pattern.compile(regnum);
        Matcher num_mat;

        String query = "with [";
        try {
            session = driver.session(AccessMode.READ);

            if (lisres != null || !lisres.isEmpty()) {
                for (int i = 0; i < lisres.size(); i++) {

                    jobj = lisres.getJSONObject(i);
                    jsonstr = "{";

                    for (String key : jobj.keySet()) {
                        jsonstr += key + ":";

                        String val = jobj.getString(key);

                        num_mat = patnum.matcher(val);
                        if (num_mat.find(0)) {
                            jsonstr += val + ", ";
                        } else {
                            jsonstr += "'" + val + "', ";
                        }
                    }
                    jsonstr = jsonstr.substring(0, jsonstr.length() - 2);

                    query += jsonstr + "},";
                }

                query = query.substring(0, query.length() - 1);

                query += "]\n" +
                        "as result_info\n" +
                        "unwind result_info as row\n" +
                        "match (n:LIS)-[:结果]->(m:LIS_Result)\n" +
                        "where n.name=row.uniqueName\n" +
                        "with m,\n" +
                        "case\n" +
                        "when m.判断1 is null or m.判断1 = '' then '未定义'\n" +
                        "when m.判断1 = \"位于\" then row.otherValue in m.判断系数1\n" +
                        "when m.判断1= \"升高\" and row.maxValue<>\"\" then row.value > row.maxValue\n" +
                        "when m.判断1= \"大于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) > m.判断系数1\n" +
                        "when m.判断1= \"大于等于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) >= m.判断系数1\n" +
                        "when m.判断1= \"小于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) < m.判断系数1\n" +
                        "when m.判断1= \"小于等于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) <= m.判断系数1\n" +
                        "when m.判断1= \"降低\" and row.minValue<>\"\" then row.value < row.minValue\n" +
                        "when m.判断1= \"大于\" and m.单位=row.units then row.value > m.判断系数1\n" +
                        "when m.判断1= \"大于等于\" and m.单位=row.units then row.value >= m.判断系数1\n" +
                        "when m.判断1= \"小于\" and m.单位=row.units then row.value < m.判断系数1\n" +
                        "when m.判断1= \"小于等于\" and m.单位=row.units then row.value <= m.判断系数1\n" +
                        //                        "when m.单位<>row.unit and m.单位 is not null then '单位不同'\n" +
                        "else 'Unknown'\n" +
                        "end as judgement1,\n" +
                        "case\n" +
                        "when m.判断2 is null or m.判断2 = '' then '未定义'\n" +
                        "when m.判断2 = \"位于\" then row.otherValue in m.判断系数2\n" +
                        "when m.判断2 = \"升高\" and row.maxValue<>\"\" then row.value > row.maxValue\n" +
                        "when m.判断2 = \"降低\" and row.minValue<>\"\" then row.value < row.minValue\n" +
                        "when m.判断2 = \"大于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) > m.判断系数2\n" +
                        "when m.判断2 = \"大于等于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) >= m.判断系数2\n" +
                        "when m.判断2 = \"小于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) < m.判断系数2\n" +
                        "when m.判断2 = \"小于等于倍数\" and row.maxValue<>\"\" then (row.value/row.maxValue) <= m.判断系数2\n" +
                        "when m.判断2 = \"大于\" and m.单位=row.units then row.value > m.判断系数2\n" +
                        "when m.判断2 = \"大于等于\" and m.单位=row.units then row.value >= m.判断系数2\n" +
                        "when m.判断2 = \"小于\" and m.单位=row.units then row.value < m.判断系数2\n" +
                        "when m.判断2 = \"小于等于\" and m.单位=row.units then row.value <= m.判断系数2\n" +
                        //                        "when m.单位<>row.unit and m.单位 is not null then '单位不同'\n" +
                        "else 'Unknown'\n" +
                        "end as judgement2\n" +
                        "return m.name as LIS_Result,\n" +
                        "case \n" +
                        "when judgement1 = True and judgement2 = True then True\n" +
                        "when judgement1 = True and judgement2 = '未定义' then True\n" +
                        "when judgement2 = True and judgement1 = '未定义' then True\n" +
                        //                        "when judgement2 = '单位不同' or judgement1 = '单位不同' then 'Unknown'\n" +
                        //                        "when judgement2 = '未定义' and judgement1 = '未定义' then 'Unknown'\n" +
                        //                        "when judgement2 is null or judgement1 is null then 'Unknown'\n" +
                        //                        "when judgement2 = false or judgement1 = false then false\n" +
                        "else False end as judgement order by LIS_Result";

                //                System.out.println(query);

                StatementResult run = session.run(query);
                while (run.hasNext()) {
                    Record next = run.next();
                    idx = "";
                    for (String k : next.keys()) {
                        if (next.get(k).getClass().toString().indexOf("Boolean") == -1) {
                            idx = next.get(k).toString().replaceAll("\"", "");
                        }
                        if (next.get(k).isTrue()) {
                            reslist.add(idx);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            CloseSession(session);
            return reslist;
        }
    }

    public static LinkedHashMap<String, String> mapSortByValue(HashMap<String, String> source) {
        LinkedList<Map.Entry<String, String>> entries = new LinkedList<>(source.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        LinkedHashMap<String, String> sada = new LinkedHashMap<>();
        for (Iterator it = entries.iterator(); it.hasNext(); ) {
            Map.Entry<String, String> next = (Map.Entry<String, String>) it.next();
            sada.put(next.getKey(), next.getValue());
        }
        return sada;
    }

    public ArrayList<String> inputProcess(ArrayList<String> fildsList) {
        ArrayList<String> ssd = new ArrayList<>();
        for (String a : fildsList) {
            String start = "";
            String[] splits = a.split(":");
            switch (splits[1]) {
                case "Symptom":
                    start = "{label:" + "\"" + splits[1] + "\"," + "name:" + "\"" + splits[0] + "\"}";
                    ssd.add(start);
                    break;
                case "Vital":
                    start = "{label:" + "\"" + splits[1] + "\"," + "name:" + "\"" + splits[0] + "\"}";
                    ssd.add(start);
                    break;
                case "LIS_Result":
                    start = "{label:" + "\"" + splits[1] + "\"," + "name:" + "\"" + splits[0] + "\"}";
                    ssd.add(start);
                    break;
                case "PACS_Result":
                    start = "{label:" + "\"" + splits[1] + "\"," + "name:" + "\"" + splits[0] + "\"}";
                    ssd.add(start);
                    break;
                case "History":
                    start = "{label:" + "\"" + splits[1] + "\"," + "name:" + "\"" + splits[0] + "\"}";
                    ssd.add(start);
                    break;
                default:
                    break;
            }
        }
        return ssd;
    }

    /**
     * 记录操作日志
     *
     * @param query 查询语句
     * @return
     */
    public void writeLog(String query) {
        FileWriter fw;
        try {
            int DD = calendar.get(Calendar.DATE);
            String stamp = String.valueOf(YY) + "-" +
                    ((String.valueOf(MM).length() == 1) ? "0" : "") + String.valueOf(MM) + "-" +
                    ((String.valueOf(DD).length() == 1) ? "0" : "") + String.valueOf(DD) + ".log";

            fw = new FileWriter(stamp, true);

            String time = format.format(new Date());
            fw.write(time + " " + query + "\r\n");

            fw.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void CloseSession(Session session) {
        if (session != null) {
            session.close();
        }
    }

    public void CloseDriver() {
        if (driver != null) {
            driver.close();
        }
    }

    public List<String> getGrapWords(String[] keys) {
        List<String> graphWordsList = new ArrayList<>();
        ArrayList<String> fildList = new ArrayList<>();
        //输出确诊集合
        Set<String> quezhen = new HashSet<>();
        for (String fild : keys) {
            fildList.add("\"" + fild.trim() + "\"");
        }
        Session session = null;
        StatementResult result = null;
        String query = "";
        try {
            session = driver.session(AccessMode.WRITE);
            //判断是否有近义词
            query = "match(d) where d.name in " + fildList + " return distinct d.name as name";
            result = session.run(query);
            while (result.hasNext()) {
                Record next = result.next();
                String word = next.get("name").toString();
                graphWordsList.add(word);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseSession(session);
        }
        return graphWordsList;
    }

    /**
     * 根据是否需要计算调取相应返回量表的方法
     *
     * @param scaleName
     * @return
     */
    public Map<String, Object> getScale(String scaleName) {
        Session session = driver.session(AccessMode.READ);
        StatementResult Rset;
        scaleName = scaleName.toUpperCase();
        Map<String, Object> scale = new LinkedHashMap<>();

        try {
            String query = "match (m:Scale) WHERE m.name=~'.*" + scaleName + ".*' return m.type";
            Rset = session.run(query);
            String type = Rset.next().get("m.type").toString().replace("\"", "");
            if ("NoCalc".equals(type)) {
                scale = this.getScaleNoCalc(scaleName);
            } else {
                scale = this.getScaleCalc(scaleName);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调量表方法时出了问题！");
        } finally {
            CloseSession(session);
            return scale;
        }

    }

    /**
     * 返回带得分需要计算的量表
     *
     * @param scaleName
     * @return
     */
    public Map<String, Object> getScaleCalc(String scaleName) {
        Session session = driver.session(AccessMode.READ);
        StatementResult Rset1 = null;
        StatementResult Rset2 = null;
        Record rec;
        scaleName = scaleName.toUpperCase();

        Map<String, Object> threeLevelItems = new LinkedHashMap<>();
        //<<=44,0>

        TreeMap<String, Object> result = null;
        Map<String, Object> title = new LinkedHashMap<>();
        List<TreeMap<String, Object>> results = new ArrayList<>();
        List<Object> titles;

        threeLevelItems.put("type", "");

        try {
            String query1 = "match (m:Scale)-[r1]->(n1)-[r2]->(n2) WHERE m.name=~'.*" + scaleName + ".*' return n1.name,n1.method,r1.score,n2.name," +
                    "r2.score,n2.type,r2.p order by toInt(r2.p),n2.type";

            String query2 = "match (m:Scale)-[r1]->(n1)-[r2]->(n2)-[r3]->(n3) WHERE m.name=~'.*" + scaleName + ".*' return n1.name,r1.score,n2.name," +
                    "r2.score,r2.p,n3.name,r3.score,r3.p,n3.type order by toInt(r2.p),n2.type";
            writeLog(query1);
            Rset1 = session.run(query1);
            Rset2 = session.run(query2);
            writeLog(query2);

            String item = "";
            String optionOrIndex = "";
            String score1 = "";
            String index = "";
            String score2 = "";
            String priority1 = "";
            String priority2 = "";

            while (Rset1.hasNext()) {
                rec = Rset1.next();
                item = rec.get("n1.name").toString().replace("\"", "");
                optionOrIndex = rec.get("n2.name").toString().replace("\"", "");
                score1 = rec.get("r2.score").toString().replace("\"", "");
                priority1 = rec.get("r2.p").toString().replace("\"", "");


                if (!"NULL".equals(score1)) {
                    if (item.contains("计算方法")) {
                        String[] score = score1.split("~|-");
                        String min = score[0];
                        String max = score[1];
                        result = new TreeMap<>();
                        result.put("min", min);
                        result.put("max", max);
                        result.put("text", optionOrIndex);
                        result.put("priority",priority1);
                        results.add(result);
                    }

                } else {
                    titles = new ArrayList<>();
                    title.put("name", item);
                    title.put("column", "name");
                    titles.add(title);
                    title = new LinkedHashMap<>();
                    title.put("name", "临床症状");
                    title.put("column", "detailName");
                    titles.add(title);
                    title = new LinkedHashMap<>();
                    title.put("name", "得分");
                    title.put("column", "score");
                    titles.add(title);
                    title = new LinkedHashMap<>();
                    title.put("name", "推荐选项");
                    title.put("column", "state");
                    titles.add(title);
                    threeLevelItems.put("title", titles);
                }
            }

            Collections.sort(results, new Comparator<TreeMap<String, Object>>() {
                @Override
                public int compare(TreeMap<String, Object> o1, TreeMap<String, Object> o2) {
                    Integer priorityo1 = Integer.valueOf(o1.get("priority").toString());
                    Integer priorityo2 = Integer.valueOf(o2.get("priority").toString());
                    return priorityo1.compareTo(priorityo2);
                }
            });
            for (TreeMap<String, Object> resMap:results) {
                resMap.remove("priority");
            }
            threeLevelItems.put("result", results);

            Map<String, List<Map<String, String>>> nameDetails = new HashMap<>();
            List<TreeMap<String, Object>> finalResult = new ArrayList<>();
            while (Rset2.hasNext()) {
                rec = Rset2.next();
                item = rec.get("n1.name").toString().replace("\"", "");
                //左拇指震动觉、右拇指振动觉
                optionOrIndex = rec.get("n2.name").toString().replace("\"", "");
                //正常、存在、消失
                index = rec.get("n3.name").toString().replace("\"", "");
                //score
                score2 = rec.get("r3.score").toString().replace("\"", "");
                priority1 = rec.get("r2.p").toString().replace("\"", "");
                priority2 = rec.get("r3.p").toString().replace("\"", "");

                optionOrIndex = optionOrIndex + "_" + priority1;

                Map<String, String> detailInfo = new LinkedHashMap<>();
                detailInfo.put("detailName", index);
                detailInfo.put("score", score2);
                detailInfo.put("state","0");
                detailInfo.put("priority",priority2);

                if (nameDetails.containsKey(optionOrIndex)){
                    nameDetails.get(optionOrIndex).add(detailInfo);
                }else{
                    nameDetails.put(optionOrIndex, new ArrayList<>());
                    nameDetails.get(optionOrIndex).add(detailInfo);
                }
            }

            for (Map.Entry<String, List<Map<String, String>>> nameDetailEntry: nameDetails.entrySet()){
                String key = nameDetailEntry.getKey();
                List<Map<String, String>> value = nameDetailEntry.getValue();
                TreeMap<String, Object> detailsResult = new TreeMap<>();

                Collections.sort(value, new Comparator<Map<String, String>>() {
                    @Override
                    public int compare(Map<String, String> o1, Map<String, String> o2) {
                        Integer priorityo1 = Integer.valueOf(o1.get("priority"));
                        Integer priorityo2 = Integer.valueOf(o2.get("priority"));
                        return priorityo1.compareTo(priorityo2);
                    }
                });

                for (Map<String, String> map:value){
                    map.remove("priority");
                }

                detailsResult.put("name", key.split("_")[0]);
                detailsResult.put("details", value);
                detailsResult.put("type",0);
                detailsResult.put("priority",key.split("_")[1]);
                finalResult.add(detailsResult);
            }
            Collections.sort(finalResult, new Comparator<TreeMap<String,Object>>() {

                @Override
                public int compare(TreeMap<String, Object> o1, TreeMap<String, Object> o2) {
                    Integer priorityo1 = Integer.valueOf(o1.get("priority").toString());
                    Integer priorityo2 = Integer.valueOf(o2.get("priority").toString());
                    return priorityo1.compareTo(priorityo2);
                }
            });
            for (TreeMap<String, Object> map:finalResult) {
                map.remove("priority");
            }
            threeLevelItems.put("detials", finalResult);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("返回带得分需要计算的量表时出了问题！---->getScaleCalc");
        } finally {
            CloseSession(session);
            return threeLevelItems;
        }
    }

    /**
     * 返回不带得分不需要计算的量表
     *
     * @param scaleName
     * @return
     */
    public Map<String, Object> getScaleNoCalc(String scaleName) {
        Session session = driver.session(AccessMode.READ);
        StatementResult Rset1 = null;
        StatementResult Rset2 = null;
        Record rec;
        scaleName = scaleName.toUpperCase();

        Map<String, Object> fourLevelItems = new LinkedHashMap<>();
        Map<String, Object> threeLevelItems = new LinkedHashMap<>();
        Map<String, Object> twoLevelItems = new LinkedHashMap<>();
        Map<Object, Object> firstLevelItems = new LinkedHashMap<>();

        try {
            String query1 = "match (m:Scale)-[r1]->(n1) where m.name=~'.*" + scaleName + ".*' " +
                    "return m.name,r1.grade,n1.name order by r1.grade,toInt(r1.p)";

            String query2 = "match (m:Scale)-[r1]->(n1)-[r2]->(n2) where m.name=~'.*" + scaleName + ".*' " +
                    "return m.name,r1.grade,n1.name,r2.stage,n2.name order by r1.grade,r2.stage,toInt(r1.p)";
            writeLog(query1);
            Rset1 = session.run(query1);
            Rset2 = session.run(query2);
            writeLog(query2);

            String scale = "";
            String grade = "";
            String gradeName = "";
            String stage = "";
            String stageName = "";

            while (Rset1.hasNext()) {
                rec = Rset1.next();
                scale = rec.get("m.name").toString().replace("\"", "");
                grade = rec.get("r1.grade").toString().replace("\"", "");
                gradeName = rec.get("n1.name").toString().replace("\"", "");

                firstLevelItems.put(gradeName, grade);
                fourLevelItems.put(scale, firstLevelItems);

            }

            while (Rset2.hasNext()) {
                rec = Rset2.next();
                scale = rec.get("m.name").toString().replace("\"", "");
                grade = rec.get("r1.grade").toString().replace("\"", "");
                gradeName = rec.get("n1.name").toString().replace("\"", "");
                stage = rec.get("r2.stage").toString().replace("\"", "");
                stageName = rec.get("n2.name").toString().replace("\"", "");

                if (!threeLevelItems.containsKey(gradeName)) {
                    firstLevelItems = new LinkedHashMap<>();
                    twoLevelItems = new LinkedHashMap<>();
                }
                if (!twoLevelItems.containsKey(grade)) {
                    firstLevelItems = new LinkedHashMap<>();
                }
                firstLevelItems.put(stageName, stage);
                twoLevelItems.put(grade, firstLevelItems);
                threeLevelItems.put(gradeName, twoLevelItems);
                fourLevelItems.put(scale, threeLevelItems);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("返回不带得分不需要计算的量表出了问题！---->getScaleNoCalc");
        } finally {
            CloseSession(session);
            return fourLevelItems;
        }
    }

}
