package com.lantone.structure.facade.tran;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lantone.common.util.ListUtil;
import com.lantone.common.util.StringUtil;
import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
import com.lantone.structure.model.doc.operation.OperationDoc;
import com.lantone.structure.model.doc.operation.OperationRecordDoc;
import com.lantone.structure.model.entity.*;
import com.lantone.structure.model.label.OperationRecordLabel;
import com.lantone.structure.util.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: 一般手术记录
 * @author: wsy
 * @time: 2021/3/11 15:49
 */
@Slf4j
public class OperationRecordDocTran extends TargetTran {
    @Override
    public Map<String, String> convert(String text) {
        List<OperationDoc> operationDocs = new ArrayList<OperationDoc>();
        OperationDoc operationDoc = new OperationDoc();
        OperationRecordDoc operationRecordDoc = new OperationRecordDoc();
        operationRecordDoc.setText(text);
        Map<String, String> structureMap = cutWord(text);
        Map<String, String> retMap = new HashMap<String, String>();
        CommonAnalysisUtil.mapKeyContrastCommon(structureMap, keyContrasts, retMap);
        operationRecordDoc.setStructureMap(retMap);
        operationDoc.setOperationRecordDoc(operationRecordDoc);
        operationDocs.add(operationDoc);
        inputInfo.setOperationDocs(operationDocs);

        aiProcess();
        fetchModelData(inputInfo.getOperationDocs(), retMap);
        retMap.entrySet().removeIf(entry -> StringUtil.isBlank(entry.getValue()));
        retMap.entrySet().removeIf(entry -> !entry.getValue().matches("[\\d]+年[\\d]+月[\\d]+日[\\d]+时[\\d]+分") && "医师签名日期时间".equals(entry.getKey()));
        return retMap;
    }

    private void fetchModelData(List<OperationDoc> operationDocs, Map<String, String> retMap) {
        if (ListUtil.isNotEmpty(operationDocs)) operationDocs.forEach(operationDoc -> {
            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
            if (operationRecordDoc != null) {
                int interventionCount = 1;
                int operationIncisionCount = 1;
                int drainageMaterialsNameCount = 1;
                int drainageMaterialsAmountCount = 1;
                int placePositionCount = 1;
                StringBuffer interventionString = new StringBuffer();
                StringBuffer operationIncisionString = new StringBuffer();
                StringBuffer drainageMaterialsNameString = new StringBuffer();
                StringBuffer drainageMaterialsAmountString = new StringBuffer();
                StringBuffer placePositionString = new StringBuffer();
                OperationRecordLabel operationRecordLabel = operationRecordDoc.getOperationRecordLabel();
                if (operationRecordLabel == null) {
                    return;
                }

                //介入物名称
                if (ListUtil.isNotEmpty(operationRecordLabel.getInterventions())) {
                    for (Intervention interventions : operationRecordLabel.getInterventions()) {
                        if (StringUtils.isNotEmpty(interventions.getName())) {
                            if (operationRecordLabel.getInterventions().size() > 1) {
                                interventionString.append((interventionCount++) + ".");
                            }
                            interventionString.append(interventions.getName());
                        }

                    }
                    retMap.put("介入物名称", interventionString.toString());
                }

                //皮肤消毒描述
                if (operationRecordLabel.getSkinSterilize() != null && StringUtils.isNotEmpty(operationRecordLabel.getSkinSterilize().getName())) {
                    retMap.put("皮肤消毒描述", operationRecordLabel.getSkinSterilize().getName());
                }

                //手术切口描述
                if (ListUtil.isNotEmpty(operationRecordLabel.getOperationIncision())) {
                    for (OperationIncision operationIncisions : operationRecordLabel.getOperationIncision()) {
                        if (StringUtils.isNotEmpty(operationIncisions.getName())) {
                            if (operationRecordLabel.getOperationIncision().size() > 1) {
                                operationIncisionString.append((operationIncisionCount++) + ".");
                            }
                            operationIncisionString.append(operationIncisions.getName());
                        }

                    }
                    retMap.put("手术切口描述", operationIncisionString.toString());
                }

                //输液量（mL）
                if (operationRecordLabel.getTransfuseQuantity() != null && StringUtils.isNotEmpty(operationRecordLabel.getTransfuseQuantity().getName())) {
                    retMap.put("输液量（mL）", operationRecordLabel.getTransfuseQuantity().getName());
                }

                //术前用药
                if (operationRecordLabel.getPreoperativeDrugs() != null && StringUtils.isNotEmpty(operationRecordLabel.getPreoperativeDrugs().getName())) {
                    retMap.put("术前用药", operationRecordLabel.getPreoperativeDrugs().getName());
                }

                //术中用药
                if (operationRecordLabel.getDuringDrugs() != null && StringUtils.isNotEmpty(operationRecordLabel.getDuringDrugs().getName())) {
                    retMap.put("术中用药", operationRecordLabel.getDuringDrugs().getName());
                }

                //引流材料名称
                if (ListUtil.isNotEmpty(operationRecordLabel.getDrainageMaterialsNames())) {
                    for (DrainageMaterialsName drainageMaterialsNames : operationRecordLabel.getDrainageMaterialsNames()) {
                        if (StringUtils.isNotEmpty(drainageMaterialsNames.getName())) {
                            if (operationRecordLabel.getDrainageMaterialsNames().size() > 1) {
                                drainageMaterialsNameString.append((drainageMaterialsNameCount++) + ".");
                            }
                            drainageMaterialsNameString.append(drainageMaterialsNames.getName());
                        }

                    }
                    retMap.put("引流材料名称", drainageMaterialsNameString.toString());
                }
                //放置部位
                if (ListUtil.isNotEmpty(operationRecordLabel.getPlacePositions())) {
                    for (PlacePosition PlacePositions : operationRecordLabel.getPlacePositions()) {
                        if (StringUtils.isNotEmpty(PlacePositions.getName())) {
                            if (operationRecordLabel.getPlacePositions().size() > 1) {
                                placePositionString.append((placePositionCount++) + ".");
                            }
                            placePositionString.append(PlacePositions.getName());
                        }

                    }
                    retMap.put("放置部位", placePositionString.toString());
                }

                //引流材料数目
                if (ListUtil.isNotEmpty(operationRecordLabel.getDrainageMaterialsAmounts())) {
                    for (DrainageMaterialsAmount drainageMaterialsAmounts : operationRecordLabel.getDrainageMaterialsAmounts()) {
                        if (StringUtils.isNotEmpty(drainageMaterialsAmounts.getName())) {
//                            if (operationRecordLabel.getDrainageMaterialsAmounts().size() > 1) {
//                                drainageMaterialsAmountString.append((placePositionCount++) + ".");
//                            }

                            drainageMaterialsAmountString.append(drainageMaterialsAmounts.getName() + "、");
                        }
                    }
                    Integer integer = addAmount(drainageMaterialsAmountString);
                    if(null != integer){
                        retMap.put("引流材料数目",integer+"根");
                    }
                }


            }
        });
    }

        private Integer addAmount(StringBuffer sb) {
            if(StringUtil.isNotEmpty(sb.toString())){
            List<Integer> list = new ArrayList<>();
            String str = sb.toString();
            if(str.contains("、")){
                String[] split = str.split("、");
                for (int i = 0; i < split.length; i++) {
                    String sc = parseStr(split[i]);
                    try {
                        Integer integer = Integer.valueOf(sc);
                        list.add(integer);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                }
            }
            return list.stream().reduce(Integer::sum).get();
        }
            return null;
    }

    private String parseStr(String sb) {
       sb = sb.replace("根", "");
       if(sb.equals("十")){
           sb = "10";
       }
        if(sb.equals("二十")){
            sb = "20";
        }
        sb =  sb.replace("二十", "2").replace("十", "1").replace("一", "1").replace("二", "2").replace("三", "3").replace("四", "4").replace("五", "5").replace("六", "6").replace("七", "7").replace("八", "8").replace("九", "9");
        return sb;
    }

    private Map<String, String> cutWord(String text) {
        Map<String, String> sourceMap = Maps.newHashMap();
        if (text.contains("问题错误")) {
            text = text.substring(0, text.indexOf("问题错误"));
        }
        text = text.replace("年  月  日  时  分", "").replace("年 月 日 时 分","")
                .replace("第1次手术", "")
                .replace("（包括体位、切口处理经过，病理标本肉眼所见）", "")
                .replace("\\r", "");
        List<String> titles = CommonAnalysisUtil.sortTitles(
                Lists.newArrayList("手术开始时间", "手术结束时间", "术前诊断", "手术名称", "术中诊断", "手 术 者", "手术人员", "助手", "护婴者",
                        "麻醉方法", "麻醉方式", "麻 醉 者", "麻醉医师", "手术标本", "手术切除标本", "术中并发症", "术中失血量", "术中输血量", "手术简要经过（包括“术中所见”）",
                        "手术经过", "术后情况及诊疗计划", "术后注意事项", "记录者", "主刀医生", "医生签名", "主刀医师签名", "记录时间", "患者或代理人签名", "与病人关系"),
                text
        );
        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
        if (sourceMap != null) {
            if (sourceMap.containsKey("主刀医生")) {
                String dataStr = sourceMap.get("主刀医生");
                String date = extractDate(dataStr);
                if (StringUtil.isNotBlank(date)) {
                    sourceMap.put("主刀医生", dataStr.replace(date, ""));
                    sourceMap.put("签名日期时间", date);
                }else{
                    if(dataStr.contains("年 月 日 时 分")){
                        sourceMap.put("主刀医生", dataStr.replace("年 月 日 时 分", ""));
                    }
                }
            } else if (sourceMap.containsKey("医生签名")) {
                String dataStr = sourceMap.get("医生签名");
                String date = extractDate(dataStr);
                if (StringUtil.isNotBlank(date)) {
                    sourceMap.put("医生签名", dataStr.replace(date, ""));
                    sourceMap.put("签名日期时间", date);
                }
            }

            //其他模块使用
            if (sourceMap.containsKey("手术开始时间") && sourceMap.containsKey("手术结束时间")) {
                sourceMap.put("手术日期时间", sourceMap.get("手术开始时间") + "-" + sourceMap.get("手术结束时间"));
            }

            CommonAnalysisUtil.removeKey(sourceMap, "术前诊断", "术中诊断", "⒈患者基本情况", "⒉拟实施的输血方案", "手术标本", "手术切除标本", "术中并发症",
                    "与病人关系", "术后情况及诊疗计划", "术后注意事项", "护婴者");
        }
        return sourceMap;
    }

    /**
     * 抽取文本中的第一个时间
     *
     * @param top
     * @return
     */
    private String extractDate(String top) {
        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
        Matcher matcher = pattern.matcher(top);
        if (matcher.find()) {
            return matcher.group(0);
        } else {
            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日 [0-9]+时[0-9]+分");
            Matcher m1 = p1.matcher(top);
            if (m1.find()) {
                return m1.group(0);
            }
        }
        return null;
    }

    private void disDate(Map sourceMap, String... args) {
        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
        if (sourceMap.containsKey(args[0]) && sourceMap_.get(args[0]).contains(args[1])) {
            int index = sourceMap_.get(args[0]).indexOf(args[1]);
            sourceMap.put(args[0], sourceMap_.get(args[0]).substring(0, index));
            sourceMap.put(args[0] + args[1], sourceMap_.get(args[0]).substring(index).replace(args[1], "").replaceAll("[:：]", ""));
        }
    }


    private List<String> keyContrasts = Lists.newArrayList(
            "手术开始时间=手术开始日期时间",
            "手术结束时间=手术结束日期时间",
            "手术简要经过（包括“术中所见”）=手术过程描述",
            "手术经过=手术过程描述",
            "手术者=手术者姓名",
            "手术人员=手术者姓名",
            "麻醉者=麻醉医师姓名",
            "麻醉医师=麻醉医师姓名",
            "医护人员陈述=手术者签名",
            "主刀医生=手术者签名",
            "术中失血量=出血量（mL）",
            "术中输血量=输血量（mL）",
            "主刀医师签名=手术者签名",
            "记录时间=签名日期时间"
    );
}