package com.lantone.qc.trans.beilun;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.lantone.qc.dbanaly.facade.changx.CxXmlUtil;
import com.lantone.qc.pub.model.doc.operation.*;
import com.lantone.qc.pub.model.vo.MedrecVo;
import com.lantone.qc.pub.util.FastJsonUtils;
import com.lantone.qc.pub.util.ListUtil;
import com.lantone.qc.pub.util.StringUtil;
import com.lantone.qc.trans.ModelDocTrans;
import com.lantone.qc.trans.beilun.util.*;
import com.lantone.qc.trans.comsis.ModelDocGenerate;
import com.lantone.qc.trans.comsis.OrdinaryAssistant;
import com.lantone.qc.trans.comsis.Preproc;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.jsoup.Jsoup;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Description: 手术文档生成
 * @author: rengb
 * @time: 2020/3/20 17:11
 */
@Slf4j
public class BeiLunOperationDocTrans extends ModelDocTrans {

    @Override
    public List<OperationDoc> extract(MedrecVo medrecVo) {
        List<OperationDoc> retList = Lists.newArrayList();

        Map<String, List<String>> contentMap = (Map) medrecVo.getContent().get("content");
        if (contentMap == null) {
            return retList;
        }

        Map<String, OperationDiscussionDoc> operationDiscussionDocMap = getOperationDiscussionDocMap((List) contentMap.get("术后首次病程及谈话记录"));
        Map<String, OperationRecordDoc> operationRecordDocMap = getOperationRecordDocMap((List) contentMap.get("手术记录"));
        Map<String, PreoperativeDiscussionDoc> preoperativeDiscussionDocMap = getPreoperativeDiscussionDocMap((List) contentMap.get("术前讨论、术前小结"));
        Map<String, OperationInformedConsentDoc> operationInformedConsentDocMap = getOperationInformedConsentDocMap((List) contentMap.get("手术知情同意书"));
        Map<String, OperationSafetyChecklistDoc> operationSafetyChecklistDocMap = getOperationSafetyChecklistDocMap((List) contentMap.get("手术安全核查表"));

        Set<String> operationNameSet = Sets.newHashSet();
        operationNameSet.addAll(operationDiscussionDocMap.keySet());
        operationNameSet.addAll(operationRecordDocMap.keySet());
        operationNameSet.addAll(preoperativeDiscussionDocMap.keySet());

        operationNameSet.forEach(operationName -> {
            OperationDoc operationDoc = new OperationDoc();
            operationDoc.setOperationName(operationName);
            operationDoc.setOperationDiscussionDoc(operationDiscussionDocMap.get(operationName));
            operationDoc.setOperationRecordDoc(operationRecordDocMap.get(operationName));
            operationDoc.setPreoperativeDiscussionDoc(preoperativeDiscussionDocMap.get(operationName));
            operationDoc.setOperationInformedConsentDoc(operationInformedConsentDocMap.get(operationName));
            operationDoc.setOperationSafetyChecklistDoc(operationSafetyChecklistDocMap.get(operationName));
            retList.add(operationDoc);
        });

        return retList;
    }


    /*******************************************术后首次病程及谈话记录***************************************************/
    private Map<String, OperationDiscussionDoc> getOperationDiscussionDocMap(List<Map<String, Object>> contentMaps) {
        Map<String, OperationDiscussionDoc> retMap = Maps.newHashMap();
        if (ListUtil.isEmpty(contentMaps)) {
            return retMap;
        }
        int index = 1;
        String operationName = null;
        for (Map<String, Object> contentMap : contentMaps) {
            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
                continue;
            }
            try {
                OperationDiscussionDoc operationDiscussionDoc = getOperationDiscussionDoc(contentMap);
                if (operationDiscussionDoc != null) {
                    operationName = index + "";
                    operationDiscussionDoc.setOperationName(operationName);
                    retMap.put(operationName, operationDiscussionDoc);
                    index++;
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return retMap;
    }

    private OperationDiscussionDoc getOperationDiscussionDoc(Map<String, Object> contentMap) {
        String content = contentMap.get("xmlText").toString();
        Map<String, String> structureMap = null;
        OperationDiscussionDoc operationDiscussionDoc = new OperationDiscussionDoc();
        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
            if (MapUtils.isNotEmpty(structureMap)) {
                operationDiscussionDoc = ModelDocGenerate.operationDiscussionDocGen(structureMap);
                operationDiscussionDoc.setText(content);
                operationDiscussionDoc.setPageData((Map) structureMap);
                return operationDiscussionDoc;
            } else {
                return null;
            }
        } else {
            String recTitle = contentMap.get("recTitle").toString();
            String recTypeId = contentMap.get("recTypeId").toString();
            BeiLunHtmlAnalysis beiLunHtmlAnalysis = new BeiLunOperationHtmlAnalysis();
            Map<String, String> sourceMap = beiLunHtmlAnalysis.analysis(content, recTitle, recTypeId);
            if (MapUtils.isNotEmpty(sourceMap)) {
                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, operationDiscussion_keyContrasts);
                structureMap.put("记录编号", contentMap.get("recId").toString());
                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
            }
            if (MapUtils.isNotEmpty(structureMap)) {
                operationDiscussionDoc = ModelDocGenerate.operationDiscussionDocGen(structureMap);
                String text = BeiLunHtmlAnalysisUtil.blockDivToStr(Jsoup.parse(content).selectFirst("body").child(0), true);
                operationDiscussionDoc.setText(text);
                operationDiscussionDoc.setPageData((Map) structureMap);
                return operationDiscussionDoc;
            } else {
                return null;
            }
        }
    }

    private List<String> operationDiscussion_keyContrasts = Lists.newArrayList(
            "手术简要经过(包括手术方式、术中所见、过程是否顺利、有无并发症等)=手术简要经过",
            "病情记录=手术简要经过",
            "术后诊断=术中后诊断",
            "患者手术后情况=患者术后情况",
            "术后应当特别注意观察的事项：=术后注意事项",
            "术后治疗计划(包括术后应当特别注意观察的事项)=术后注意事项",
            "医师签名=医生签名"
    );


    /**********************************************手术记录*************************************************************/
    private Map<String, OperationRecordDoc> getOperationRecordDocMap(List<Map<String, Object>> contentMaps) {
        Map<String, OperationRecordDoc> retMap = Maps.newHashMap();
        if (ListUtil.isEmpty(contentMaps)) {
            return retMap;
        }
        int index = 1;
        String operationName = null;
        for (Map<String, Object> contentMap : contentMaps) {
            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
                continue;
            }
            try {
                OperationRecordDoc operationRecordDoc = getOperationRecordDoc(contentMap);
                if (operationRecordDoc != null) {
                    operationName = index + "";
                    operationRecordDoc.setOperationName(operationName);
                    retMap.put(operationName, operationRecordDoc);
                    index++;
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return retMap;
    }

    private OperationRecordDoc getOperationRecordDoc(Map<String, Object> contentMap) {
        String content = contentMap.get("xmlText").toString();
        Map<String, String> structureMap = null;
        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
        } else {
            String recTitle = contentMap.get("recTitle").toString();
            String recTypeId = contentMap.get("recTypeId").toString();
            BeiLunHtmlAnalysis beiLunHtmlAnalysis = new BeiLunOperationRecordHtmlAnalysis();
            Map<String, String> sourceMap = beiLunHtmlAnalysis.analysis(content, recTitle, recTypeId);
            //含有手术情况知情书时间特殊处理
            if (sourceMap.containsKey("时间") && sourceMap.get("时间").contains("宁波市北仑区人民医院")) {
                sourceMap.put("时间", sourceMap.get("时间").substring(0, sourceMap.get("时间").indexOf("宁波市北仑区人民医院")));
            }
            if (MapUtils.isNotEmpty(sourceMap)) {
                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, operationRecord_keyContrasts);
                structureMap.put("记录编号", contentMap.get("recId").toString());
                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
            }
            List<String> titles = Lists.newArrayList("手术开始时间", "手术结束时间");
            for (String title : titles) {
                eliminateDate(structureMap, title);
            }
            if (structureMap.containsKey("麻醉人员")) {
                structureMap.put("麻醉人员", structureMap.get("麻醉人员").replace("\n", "").replaceAll("麻醉人员签名", ""));
            }
            if (structureMap.containsKey("接生者")) {
                structureMap.put("接生者", structureMap.get("接生者").replace("\n", "").replaceAll("接生者签名", ""));
            }
        }
        if (MapUtils.isNotEmpty(structureMap)) {
            OperationRecordDoc operationRecordDoc = ModelDocGenerate.operationRecordDocGen(structureMap);
            operationRecordDoc.setPageData((Map) structureMap);
            return operationRecordDoc;
        } else {
            return null;
        }
    }

    private List<String> operationRecord_keyContrasts = Lists.newArrayList(
            "手术经过=手术经过及处理",
            "术后诊断=术中后诊断",
            "主刀=主刀医师",
            "记录者=记录医生",
            "患者手术后情况=患者术后情况",
            "麻醉方法=麻醉方式",
            "时间=记录时间"
    );


    /**********************************************术前讨论、术前小结****************************************************/
    private Map<String, PreoperativeDiscussionDoc> getPreoperativeDiscussionDocMap(List<Map<String, Object>> contentMaps) {
        Map<String, PreoperativeDiscussionDoc> retMap = Maps.newHashMap();
        if (ListUtil.isEmpty(contentMaps)) {
            return retMap;
        }
        int index = 1;
        String operationName = null;
        for (Map<String, Object> contentMap : contentMaps) {
            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
                continue;
            }
            try {
                PreoperativeDiscussionDoc preoperativeDiscussionDoc = getPreoperativeDiscussionDoc(contentMap);
                if (preoperativeDiscussionDoc != null) {
                    operationName = index + "";
                    preoperativeDiscussionDoc.setOperationName(operationName);
                    retMap.put(operationName, preoperativeDiscussionDoc);
                    index++;
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return retMap;
    }

    private PreoperativeDiscussionDoc getPreoperativeDiscussionDoc(Map<String, Object> contentMap) {
        String content = contentMap.get("xmlText").toString();
        Map<String, String> structureMap = null;
        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
        } else {
            String recTitle = contentMap.get("recTitle").toString();
            String recTypeId = contentMap.get("recTypeId").toString();
            BeiLunHtmlAnalysis beiLunHtmlAnalysis = new BeiLunPreoperativeHtmlAnalysis();
            Map<String, String> sourceMap = beiLunHtmlAnalysis.analysis(content, recTitle, recTypeId);
            if (MapUtils.isNotEmpty(sourceMap)) {
                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, preoperativeDiscussion_keyContrasts);
                structureMap.put("记录编号", contentMap.get("recId").toString());
                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
            }
        }
        List<String> titles = Lists.newArrayList("讨论时间", "手术指征", "注意事项", "术前诊断", "医生签名", "风险及防范措施", "可替代方案", "术前准备", "参加人员");
        if (structureMap.containsKey("简要病情")) {
            String value = structureMap.get("简要病情").replaceAll("医师姓名", "").replaceAll("简要病情描述", "");
            structureMap.put("简要病情", value);
        }
        if (structureMap.containsKey("可替代的方案")) {
            String value = structureMap.get("可替代的方案").replaceAll("可替代方案", "");
            structureMap.put("可替代的方案", value);
        }
        if (structureMap.containsKey("拟施麻醉方式")) {
            String value = structureMap.get("拟施麻醉方式").replaceAll("麻醉方式", "");
            structureMap.put("拟施麻醉方式", value);
        }
        if (structureMap.containsKey("其他术前相关情况")) {
            String value = structureMap.get("其他术前相关情况").replaceAll("术者术前查看患者的相关情况", "");
            structureMap.put("其他术前相关情况", value);
        }
        if (structureMap.containsKey("手术指征与禁忌")) {
            String value = structureMap.get("手术指征与禁忌").replaceAll("手术指征与禁忌征", "");
            structureMap.put("手术指征与禁忌", value);
        }
        for (String title : titles) {
            eliminateDate(structureMap, title);
        }
        if (MapUtils.isNotEmpty(structureMap)) {
            PreoperativeDiscussionDoc preoperativeDiscussionDoc = ModelDocGenerate.preoperativeDiscussionDocGen(structureMap);
            preoperativeDiscussionDoc.setPageData((Map) structureMap);
            return preoperativeDiscussionDoc;
        } else {
            return null;
        }
    }

    private void eliminateDate(Map<String, String> structureMap, String text) {
        if (structureMap.containsKey(text)) {
            String value = structureMap.get(text).replaceAll(text, "");
            structureMap.put(text, value);
        }
    }

    private List<String> preoperativeDiscussion_keyContrasts = Lists.newArrayList(
            "1.术前诊断=术前诊断",
            "2.手术指征与禁忌征=手术指征与禁忌",
            "3.可替代方案=可替代的方案",
            "4.拟施手术方式（名称）及可能的变更方案=拟施手术方式、名称及可能的变更与禁忌症",
            "5.计划性多次手术=计划性多次手术",
            "6.拟施麻醉方式=拟施麻醉方式",
            "5.拟施麻醉方式=拟施麻醉方式",
            "5.本次手术是否属于计划性多次手术=计划性多次手术",
            "6.术前特殊准备=术前准备",
            "7.术前特殊准备=术前准备",
            "7.主要术中、术后风险及防范措施=风险及防范措施",
            "8.主要术中、术后风险及防范措施=风险及防范措施",
            "9.术中、术后注意事项（含护理事项）=术中术后注意事项",
            "8.术中、术后注意事项（含护理事项）=术中术后注意事项",
            //"术中、术后注意事项（含护理事项）=术后注意事项",
            //"拟施手术方式（名称）及可能的变更方案=拟施手术方式、名称及可能的变更与禁忌症",
            //"术前特殊准备=术前准备",
            //"手术指征与禁忌征=手术指征与禁忌",
            "经治医生签字时间=记录时间",
            "签字时间=记录时间"
    );

    /**********************************************手术知情同意书****************************************************/
    private Map<String, OperationInformedConsentDoc> getOperationInformedConsentDocMap(List<Map<String, Object>> contentMaps) {
        Map<String, OperationInformedConsentDoc> retMap = Maps.newHashMap();
        if (ListUtil.isEmpty(contentMaps)) {
            return retMap;
        }
        int index = 1;
        String operationName = null;
        for (Map<String, Object> contentMap : contentMaps) {
            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
                continue;
            }
            operationName = index + "";
            OperationInformedConsentDoc operationInformedConsentDoc = getOperationInformedConsentDoc(contentMap);
            operationInformedConsentDoc.setOperationName(operationName);
            retMap.put(operationName, operationInformedConsentDoc);
            index++;
        }
        return retMap;
    }

    private OperationInformedConsentDoc getOperationInformedConsentDoc(Map<String, Object> contentMap) {
        String modeId = "16";
//        String content = contentMap.get("xmlText").toString();
//        Map<String, String> xmlNodeValueMap = CxXmlUtil.firstLevelNodeValue(content);
//        xmlNodeValueMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
//        xmlNodeValueMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
//        Map<String, String> structureMap = OrdinaryAssistant.mapKeyContrast(xmlNodeValueMap, operationInformedConsent_keyContrasts, modeId);
//
//        String text = CxXmlUtil.getXmlText(content);
//        Map<String, String> cutWordMap = Preproc.getCutWordMap(true, operationInformedConsent_sourceTitles, text);
//        cutWordMap.putAll(structureMap);
//
//        OperationInformedConsentDoc operationInformedConsentDoc = ModelDocGenerate.operationInformedConsentDocGen(cutWordMap);
        OperationInformedConsentDoc operationInformedConsentDoc = new OperationInformedConsentDoc();
//        operationInformedConsentDoc.setText(text);
//        operationInformedConsentDoc.setPageData((Map) cutWordMap);

        return operationInformedConsentDoc;
    }

    private List<String> operationInformedConsent_sourceTitles = Lists.newArrayList(
            "姓名",
            "性别",
            "病区",
            "床号",
            "病案号",
            "手术医生",
            "目前诊断",
            "手术名称",
            "手术指征",
            "风险及并发症",
            "保守治疗",
            "其他手术",
            "签名",
            "签名时间"
    );

    private List<String> operationInformedConsent_keyContrasts = Lists.newArrayList(
            "姓名++++患者姓名=姓名",
            "性别=",
            "病区++++病区名称=病区",
            "床号=",
            "病案号++++住院号=病案号",
            "手术医生=",
            "目前诊断=",
            "手术名称=",
            "手术指征=",
            "风险及并发症=",
            "++++保守治疗=保守治疗",
            "++++其他手术=其他手术",
            "签名++++=签名",
            "签名时间=签名时间"
    );

    /**********************************************手术安全核查表****************************************************/
    private Map<String, OperationSafetyChecklistDoc> getOperationSafetyChecklistDocMap(List<Map<String, Object>> contentMaps) {
        Map<String, OperationSafetyChecklistDoc> retMap = Maps.newHashMap();
        if (ListUtil.isEmpty(contentMaps)) {
            return retMap;
        }
        int index = 1;
        String operationName = null;
        for (Map<String, Object> contentMap : contentMaps) {
            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
                continue;
            }
            operationName = index + "";
            OperationSafetyChecklistDoc operationSafetyChecklistDoc = getOperationSafetyChecklistDoc(contentMap);
            operationSafetyChecklistDoc.setOperationName(operationName);
            retMap.put(operationName, operationSafetyChecklistDoc);
            index++;
        }
        return retMap;
    }

    private OperationSafetyChecklistDoc getOperationSafetyChecklistDoc(Map<String, Object> contentMap) {
        String modeId = "21";
//        String content = contentMap.get("xmlText").toString();
//        Map<String, String> xmlNodeValueMap = CxXmlUtil.firstLevelNodeValue(content);
//        xmlNodeValueMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
//        xmlNodeValueMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
//        Map<String, String> structureMap = OrdinaryAssistant.mapKeyContrast(xmlNodeValueMap, operationSafetyChecklist_keyContrasts, modeId);
//
//        String text = CxXmlUtil.getXmlText(content);
//        Map<String, String> cutWordMap = Preproc.getCutWordMap(true, operationSafetyChecklist_sourceTitles, text);
//        cutWordMap.putAll(structureMap);

//        OperationSafetyChecklistDoc operationSafetyChecklistDoc = ModelDocGenerate.operationSafetyChecklistDocGen(cutWordMap);
        OperationSafetyChecklistDoc operationSafetyChecklistDoc = new OperationSafetyChecklistDoc();
//        operationSafetyChecklistDoc.setText(text);
//        operationSafetyChecklistDoc.setPageData((Map) cutWordMap);

        return operationSafetyChecklistDoc;
    }

    private List<String> operationSafetyChecklist_sourceTitles = Lists.newArrayList(
            "姓名",
            "性别",
            "病区",
            "床号",
            "病案号",
            "签名"
    );

    private List<String> operationSafetyChecklist_keyContrasts = Lists.newArrayList(
            "姓名++++患者姓名=姓名",
            "性别",
            "病区",
            "床号",
            "病案号++++住院号=病案号",
            "签名++++=签名"
    );
}
