package com.lantone.qc.kernel.catalogue.threelevelward;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lantone.qc.kernel.catalogue.QCCatalogue;
import com.lantone.qc.kernel.util.CatalogueUtil;
import com.lantone.qc.pub.model.InputInfo;
import com.lantone.qc.pub.model.OutputInfo;
import com.lantone.qc.pub.model.doc.CrisisInfoDoc;
import com.lantone.qc.pub.model.doc.LisDoc;
import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
import com.lantone.qc.pub.util.DateUtil;
import com.lantone.qc.pub.util.StringUtil;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author HUJING
 * @create 2020-08-17 15:29
 * @desc 异常化验未记录
 **/
@Component
public class THR03070 extends QCCatalogue {
    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
        status.set("0");
        List<LisDoc> lisDocs = inputInfo.getLisDocs();
        List<CrisisInfoDoc> crisisInfoDocs = inputInfo.getCrisisInfoDocs();
        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
        if (lisDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
            return;
        }
        List<String> crisisNames = crisisInfoDocs
                .stream()
                .map(CrisisInfoDoc::getStructureMap)
                .filter(x -> StringUtil.isNotBlank(x.get("危急值名称")))
                .map(x -> x.get("危急值名称"))
                .collect(Collectors.toList());
        //异常数据列表
        List<String> abnormal = Lists.newArrayList();
        Map<String, String> abnormalMap = Maps.newHashMap();
        StringBuffer sb = new StringBuffer();
        for (LisDoc lisDoc : lisDocs) {
            double resultValue = -1, max = -1, min = -1;
            Map<String, String> structureMap = lisDoc.getStructureMap();
            String itemName = structureMap.get("报告名称");
            if (crisisNames.contains(itemName)) {
                continue;
            }
            String result = structureMap.get("检验结果");
            String reference = structureMap.get("参考值");
            String itemDate = structureMap.get("报告创建时间");
            if (StringUtil.isBlank(itemName) || StringUtil.isBlank(result)
                    || StringUtil.isBlank(reference) || StringUtil.isBlank(itemDate)) {
                continue;
            }
            itemName = itemName.split("=")[1];
            //1.化验结果是阳性时，直接把该化验名称放入异常数据列表中
            if (result.contains("阳")) {
                abnormal.add(itemName);
                abnormalMap.put(itemName, itemDate);
                continue;
            }
            //2.化验结果为阴性，或化验结果中不包含数字，跳过该条化验结果
            if (result.contains("阴") || !CatalogueUtil.numberExist(result)) {
                continue;
            }
            try {
                resultValue = Double.parseDouble(result);
            } catch (Exception e) {
                System.out.println("THR03070--解析result出错：" + itemName + "->" + result);
            }
            if (resultValue < 0) {
                continue;
            }
            //3.化验正常值在一个范围内，以“-”分割，最小值最大值返回都扩大10%，再与化验结果比较，在这范围之外，把该化验名称放入异常数据列表中
            if (reference.contains("-")) {
                try {
                    String[] minMax = reference.split("-");
                    min = Double.parseDouble(getNumber(minMax[0])) * 0.85;        //最小值范围缩小10%
                    String maxNumber = getNumber(minMax[1]);
                    if (StringUtil.isNotBlank(maxNumber)) {
                        max = Double.parseDouble(maxNumber) * 1.15;    //最大值范围扩大10%
                    }
                    //化验结果在正常范围之外（返回扩大10%），把该化验名称放入异常数据列表中
                    if (min >= 0 && max >= 0 && (resultValue < min || resultValue > max)) {
                        abnormal.add(itemName);
                        abnormalMap.put(itemName, itemDate);
                    }
                } catch (Exception e) {
                    System.out.println("THR03070--3.出异常");
                }
            }
            //4.化验正常值比某个值小，但该化验结果比该值大，把该化验名称放入异常数据列表中
            else if (reference.contains("<")) {
                try {
                    String maxNumber = getNumber(reference);
                    if (StringUtil.isNotBlank(maxNumber)) {
                        max = Double.parseDouble(maxNumber);
                    }
                    if (resultValue > max) {
                        abnormal.add(itemName);
                        abnormalMap.put(itemName, itemDate);
                    }
                } catch (Exception e) {
                    System.out.println("THR03070--4.出异常");
                }
            }
            //5.化验正常值比某个值大，但该化验结果比该值小，把该化验名称放入异常数据列表中
            else if (reference.contains(">")) {
                try {
                    String maxNumber = getNumber(reference);
                    if (StringUtil.isNotBlank(maxNumber)) {
                        min = Double.parseDouble(maxNumber);
                    }
                    if (resultValue < min) {
                        abnormal.add(itemName);
                        abnormalMap.put(itemName, itemDate);
                    }
                } catch (Exception e) {
                    System.out.println("THR03070--5.出异常");
                }
            }
        }

        Map<String, Integer> abnormalCount = Maps.newHashMap();
        abnormal = abnormal.stream().map(x -> {
            if (x.contains("[")) {
                x = x.substring(0, x.indexOf("["));
            }
            if (x.contains("(")) {
                x = x.substring(0, x.indexOf("("));
            }
            x = x.replaceAll("[^\\u4e00-\\u9fa5]", "");
            return x;
        }).distinct().collect(Collectors.toList());
        abnormal.forEach(i -> abnormalCount.put(i, 0));

        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
        for (ThreeLevelWardDoc doc : allDoctorWradDocs) {
            Map<String, String> structureMap = doc.getStructureMap();
            String content = CatalogueUtil.structureMapJoin(structureMap, Lists.newArrayList("体检", "病情记录"));
            for (String lis : abnormal) {
                if (content.contains(lis)) {
                    abnormalCount.put(lis, abnormalCount.get(lis) + 1);
                }
            }
        }

        List<String> abnormalMiss = Lists.newArrayList();
        for (Map.Entry<String, Integer> lis : abnormalCount.entrySet()) {
            if (lis.getValue() == 0) {
                abnormalMiss.add(lis.getKey());
            }
            if (abnormalMiss.size() > 0) {
                infoAppend(sb, lis.getKey(), abnormalMap);
            }
        }
//        if (abnormalMiss.size() > 0) {
//            status.set("-1");
//            info.set(abnormalMiss.toString().replaceAll("[\\[\\]]", ""));
//        }

        if (sb.toString().length() > 0) {
            status.set("-1");
            info.set("化验：" + sb.toString().substring(0, sb.toString().length() - 1));
        }
    }

    public String getNumber(String content) {
        String group = "";
        String compile = "([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]|0)";
        Pattern p = Pattern.compile(compile);
        Matcher matcher = p.matcher(content);
        if (matcher.find()) {
            group = matcher.group(0);
        }
        return group;
    }

    /**
     * 拼接提示信息
     *
     * @param sb
     * @param repNm
     * @param abnormalMap
     */
    private void infoAppend(StringBuffer sb, String repNm, Map<String, String> abnormalMap) {
        for (Map.Entry<String, String> map : abnormalMap.entrySet()) {
            if (repNm.equals(map.getKey())) {
                sb.append(repNm).append("(").append(DateUtil.formatDateTime(StringUtil.parseDateTime(map.getValue()))).append(")").append("_");
            }
        }
    }
}
