package com.lantone.qc.trans.yiwu;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lantone.qc.dbanaly.facade.yiwu.YiWuXmlUtil;
import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
import com.lantone.qc.dbanaly.util.SpecialStorageUtil;
import com.lantone.qc.pub.model.doc.BeHospitalizedDoc;
import com.lantone.qc.pub.model.label.*;
import com.lantone.qc.pub.model.vo.BehospitalInfoVO;
import com.lantone.qc.pub.model.vo.MedrecVo;
import com.lantone.qc.pub.util.FastJsonUtils;
import com.lantone.qc.pub.util.SpringContextUtil;
import com.lantone.qc.pub.util.StringUtil;
import com.lantone.qc.trans.ModelDocTrans;
import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
import com.lantone.qc.trans.comsis.OrdinaryAssistant;
import org.apache.commons.lang3.StringUtils;

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

/**
 * @Description: 入院记录文档生成
 * @author: rengb
 * @time: 2020/3/5 15:47
 */
public class YiWuBeHospitalizedDocTrans extends ModelDocTrans {
    private String modeId = "1";

    /**
     * @param medrecVo
     * @return
     */
    @Override
    public BeHospitalizedDoc extract(MedrecVo medrecVo) {
        Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
        String content = contentMap.get("xmlText").toString();
        SpecialStorageUtil specialStorageUtil = SpringContextUtil.getBean("specialStorageUtil");
        BehospitalInfoVO behospitalInfoVO = specialStorageUtil.getBehospitalInfoThreadLocal().get();
        Map<String, String> structureMap = null;
        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
        } else {
            Map<String, String> sourceMap = YiWuXmlUtil.xmlToMap(content);
            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
            String text = sourceMap.get("原始文本").replace("：", ":").replaceAll("■", "");
            //日间病历单独处理
            String behDeptId = behospitalInfoVO.getBehDeptId();
            if ("51923".equals(behDeptId) || "52883".equals(behDeptId) || "52903".equals(behDeptId) || "52923".equals(behDeptId) || "53523".equals(behDeptId)) {
                Map<String, String> dailyTrans = dailyTrans(text, behDeptId);
                mapJoin(sourceMap, dailyTrans);
            } else {
                Map<String, String> cutMap = Maps.newHashMap();
                List<String> titles = Lists.newArrayList("婚    姻", "联系地址", "工作单位", "入院日期", "婚姻状况", "男友姓名", "丈夫姓名", "联系人姓名", "姐姐姓名", "末次月经", "住      址", "出生日期", "联系 电话", "职    业", "身份证号码", "供 史 者", "主　　诉", "性      别", "主    诉", "婚　　姻", "籍      贯", "民　　族", "民    族", "个人史", "个 人 史", "妇科检查", "产科检查",
                        "实验室", "诊断和诊断修正", "婚 育 史", "家 族 史", "体格检查（一）", "体 格 检 查（一）", "现 病 史", "既往史", "既 往 史", "月 经 史", "系统回顾", "其他", "职        业", "联系人及电话");
                List<String> sortTitles = CommonAnalysisUtil.sortTitlesNoColon(titles, text);
                CommonAnalysisUtil.cutByTitlesNoColon(text, sortTitles, 0, cutMap);
                List<String> modifyKey = Lists.newArrayList("初步诊断", "修正诊断", "补充诊断");
                sortTitles = CommonAnalysisUtil.sortTitlesNoColon(modifyKey, text);
                if (text.contains("初步诊断:")) {
                    text = text.substring(text.indexOf("初步诊断:")).replaceAll("[ ]", "");
                    for (String key : sortTitles) {
                        text = modifyDiagKey(text, key);
                    }
                    modifyKey = Lists.newArrayList("初步诊断", "修正诊断", "补充诊断", "初步诊断医师", "修正诊断医师", "补充诊断医师", "初步诊断时间", "修正诊断时间", "补充诊断时间");
                    sortTitles = CommonAnalysisUtil.sortTitles(modifyKey, text);
                    CommonAnalysisUtil.cutByTitles(text, sortTitles, 0, cutMap);
                }
                if (sourceMap.containsKey("修正诊断") && (sourceMap.get("修正诊断").contains(":") || sourceMap.get("修正诊断").contains("："))) {
                    sourceMap.put("修正诊断", "");
                }
                //妇科日间出院医嘱部分特殊处理
                List<String> titles1 = Lists.newArrayList("注意事项", "医生办公室电话", "随访安排", "活动能力与生活自理情况"
                        , "出院带药", "出院去向");
                String text1 = sourceMap.get("出院医嘱");
                if (text1 != null) {
                    text1.replaceAll("[0-9,、]", "");
                    List<String> sortTitles1 = CommonAnalysisUtil.sortTitles(titles1, text1);
                    CommonAnalysisUtil.cutByTitles(text1, sortTitles1, 0, cutMap);
                }
                sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
                sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");

                //产科孕产次
                if (sourceMap.containsKey("入院记录")) {
                    String value = sourceMap.get("入院记录").split(" ")[0];
                    sourceMap.put("孕产次", value);
                }
                //产科入院记录个人史处理
                if (sourceMap.containsKey("个人史")) {
                    String value = sourceMap.get("个人史").split("月经史")[0];
                    sourceMap.put("个人史", value);
                }

                //入院记录标题部分解析不出的  婚姻和民族处理
                //注意中间的空格是什么字符
                List<String> titletitles = Lists.newArrayList("住      址",
                        "婚　　姻", "民　　族", "民    族", "供 史 者", "性      别", "婚    姻", "婚姻状况", "病史提供者", "职业", "联系人及电话");
                for (String str : titletitles) {
                    String str1 = str.replaceAll("[　 ]", "");
                    if (sourceMap.containsKey(str)) {
                        String value = (sourceMap.get(str).split(" ")[0]).split("\\\\n")[0];
                        sourceMap.put(str1, value);
                    }
                    if (sourceMap.containsKey(str1)) {
                        String value = (sourceMap.get(str1).split(" ")[0]).split("\\\\n")[0];
                        sourceMap.put(str1, value);
                    }
                }
                mapJoin(sourceMap, cutMap);
            }

            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
            OrdinaryAssistant.removeBlank(structureMap);
        }
        //姓名+姓名问题解决
        if (structureMap.containsKey("姓名")) {
            String value = structureMap.get("姓名").split(" ")[0];
            structureMap.put("姓名", value);
        }
        //如果有入院时间，优先使用
        addKeyMapping(structureMap, "入院时间", "入病房时间");
        //如果有职业，优先使用
        addKeyMapping(structureMap, "职业", "工作性质");
        BeHospitalizedDoc beHospitalizedDoc = beHospitalizedDocGen(structureMap); // 不走共用
        beHospitalizedDoc.setPageData((Map) structureMap);
        //structureMap.forEach((k, v) -> System.out.println(k + "\n" + v + "\n----------------------------------------"));
        return beHospitalizedDoc;
    }

    private void mapJoin(Map<String, String> sourceMap, Map<String, String> dailyTrans) {
        dailyTrans.forEach((k, v) -> {
            if (!sourceMap.containsKey(k)) {
                sourceMap.put(k, v);
            }
        });
    }

    private List<String> keyContrasts = Lists.newArrayList(
            "初步诊断医师=初步诊断医师签名",
            "修正诊断医师=修正诊断医师签名",
            "补充诊断医师=补充诊断医师签名",
            "初步诊断时间=初步诊断日期",
            "补充诊断时间=补充诊断日期",
            "补充诊断时间=补充诊断日期",
            "本人姓名=姓名",
            "性别=性别",
            "年龄=年龄",
            "民族=民族",
            "职业=职业",
            "出生地址=出生地",
            "出生、生长史=出生生长史",
            "地址=联系地址",
            "工作场所=工作单位",
            "患者工作单位名称=工作单位",
            "信息来源=病史陈述者",
            "生日=出生日期",
            "出生时间=出生日期",
            "病人出生日期=出生日期",
            "新生儿出生日期=出生日期",
            //            "出生地址=户口地址",
            "本人电话=联系电话电话",
            "入病房时间=入院日期",
            "病历日期=记录日期",
            "主诉=主诉",
            "现病史=现病史",
            "内科疾病史(其它)=内科疾病史其它",
            "一般健康状况=既往健康状况",
            "婚姻家庭关系和睦=夫妻关系",
            "体格检查=体格检查",
            "初步诊断=初步诊断",
            "修正诊断=修正诊断",
            "医生=医师签名",
            "补充诊断=补充诊断",
            //            "户口地址=联系地址",
            "家属提供的信息可信吗=病史可靠性",
            "入院诊断(中医疾病)=中医诊断",
            "长期用药情况(包括可能成瘾的药物)=长期用药",
            "体温(口)=体温",
            "性别代码=性别",
            "家庭住址=户口地址",
            "联系人电话号码=联系电话",
            "家长姓名=联系人",
            "联系人姓名=联系人",
            "患者出生地址=出生地",
            "入院日期时间=入院日期",
            "现住址=户口地址",
            //            "_{K4}=性别",
            "联系住址=户口地址",
            "联系地址=户口地址",
            "患者工作单位名称=户口地址",
            "出生日期时间=出生日期",
            //            "医生签名=初步诊断医师签名",
            "签字日期=初步诊断日期",
            "供史者=病史陈述者",
            "无痛人流主诉=主诉",
            "联系人电话=联系电话",
            "医师签字时间=初步诊断日期",
            "医师签名时间=初步诊断日期",
            "入院诊断编码=初步诊断",
            "婚姻=婚姻状况",
            "病史提供者=病史陈述者",
            "家庭地址=户口地址",
            "患者手机号码=联系电话",
            "孕 产次=孕产次",
            "有/无=产前检查",
            "末次月经日期=末次月经",
            "入院诊断1=入院诊断",
            //            "记录医师=初步诊断医师签名",
            "修正诊断签名日期=修正诊断日期",
            "修正诊断一医师签名=修正诊断医师签名",
            "患者姓名=姓名",
            "年月日=初步诊断日期",
            "年月日时分=初步诊断日期",
            "诊疗经过=诊疗情况",
            "随访安排=随访计划",
            "活动能力与生活自理情况=出院医嘱",
            "患者籍贯新=籍贯",
            "现住址邮编=邮政编码",
            "患者签名时间=初步诊断日期",
            "日期=初步诊断日期",
            "骨盆外测量=专科检查",
            "婚姻=婚姻状况",
            "住址=户口地址",
            "患者籍贯=出生地",
            "他=其他",
            "入院诊断1=初步诊断",
            "出院诊断1=出院诊断",
            "主刀医师签名=记录医师",
            "签名医师=记录医师",
            "时间=记录时间",
            "诊断和诊断修正=修正诊断"
    );


    /**
     * 入院记录
     *
     * @param structureMap
     * @return
     */
    public static BeHospitalizedDoc beHospitalizedDocGen(Map<String, String> structureMap) {
        BeHospitalizedDoc beHospitalizedDoc = new BeHospitalizedDoc();

        // 走模型
        ChiefLabel chiefLabel = new ChiefLabel();
        chiefLabel.setText(structureMap.get("主诉"));
        beHospitalizedDoc.setChiefLabel(chiefLabel);
        if (StringUtil.isBlank(structureMap.get("主诉"))) {
            beHospitalizedDoc.setChiefLabel(null);
        }

        // 走模型
        PresentLabel presentLabel = new PresentLabel();
        if (StringUtil.isNotBlank(structureMap.get("现病史"))) {
            presentLabel.setText(structureMap.get("现病史"));
        } else if (StringUtil.isNotBlank(structureMap.get("入院情况"))) {
            presentLabel.setText(structureMap.get("入院情况"));
        }
        beHospitalizedDoc.setPresentLabel(presentLabel);

        PastLabel pastLabel = new PastLabel();
        pastLabel.setCrfLabel(false);
        if (StringUtil.isNotBlank(structureMap.get("既往史"))) {
            pastLabel.setText(structureMap.get("既往史"));
        } else if (StringUtil.isNotBlank(structureMap.get("入院情况"))) {
            pastLabel.setText(structureMap.get("入院情况"));
        }
        beHospitalizedDoc.setPastLabel(pastLabel);

        PersonalLabel personalLabel = new PersonalLabel();
        //        personalLabel.setCrfLabel(false);
        personalLabel.setText(structureMap.get("个人史"));
        beHospitalizedDoc.setPersonalLabel(personalLabel);
        if (StringUtil.isBlank(structureMap.get("个人史"))) {
            beHospitalizedDoc.setPersonalLabel(null);
        }

        MaritalLabel maritalLabel = new MaritalLabel();
        //        maritalLabel.setCrfLabel(false);
        maritalLabel.setText("婚育史: " + structureMap.get("婚育史"));
        beHospitalizedDoc.setMaritalLabel(maritalLabel);
        if (StringUtil.isBlank(structureMap.get("婚育史"))) {
            beHospitalizedDoc.setMaritalLabel(null);
        }

        MenstrualLabel menstrualLabel = new MenstrualLabel();
        //        menstrualLabel.setCrfLabel(false);
        menstrualLabel.setText("月经史:" + structureMap.get("月经史"));
        beHospitalizedDoc.setMenstrualLabel(menstrualLabel);
        if (StringUtil.isBlank(structureMap.get("月经史"))) {
            beHospitalizedDoc.setMenstrualLabel(null);
        }

        FamilyLabel familyLabel = new FamilyLabel();
        //        familyLabel.setCrfLabel(false);
        familyLabel.setText(structureMap.get("家族史"));
        beHospitalizedDoc.setFamilyLabel(familyLabel);
        if (StringUtil.isBlank(structureMap.get("家族史"))) {
            beHospitalizedDoc.setFamilyLabel(null);
        }

        VitalLabel vitalLabel = new VitalLabel();
        //        vitalLabel.setCrfLabel(false);
        vitalLabel.setText(structureMap.get("体格检查"));
        beHospitalizedDoc.setVitalLabel(vitalLabel);
        if (StringUtil.isBlank(structureMap.get("体格检查"))) {
            beHospitalizedDoc.setVitalLabel(null);
        }

        VitalLabelSpecial vitalLabelSpecial = new VitalLabelSpecial();
        //        vitalLabelSpecial.setCrfLabel(false);
        vitalLabelSpecial.setText(structureMap.get("专科体格检查"));
        beHospitalizedDoc.setVitalLabelSpecial(vitalLabelSpecial);
        if (StringUtil.isBlank(structureMap.get("专科体格检查"))) {
            beHospitalizedDoc.setVitalLabelSpecial(null);
        }

        // 走模型
        PacsLabel pacsLabel = new PacsLabel();
        //        pacsLabel.setCrfLabel(false);
        pacsLabel.setText(structureMap.get("辅助检查"));
        beHospitalizedDoc.setPacsLabel(pacsLabel);
        if (StringUtil.isBlank(structureMap.get("辅助检查"))) {
            beHospitalizedDoc.setPacsLabel(null);
        }

        // 走模型
        DiagLabel initialDiagLabel = new DiagLabel();
        initialDiagLabel.setText(structureMap.get("初步诊断"));
        beHospitalizedDoc.setInitialDiagLabel(initialDiagLabel);
        if (StringUtil.isBlank(structureMap.get("初步诊断"))) {
            beHospitalizedDoc.setInitialDiagLabel(null);
        }

        // 走模型
        DiagLabel revisedDiagLabel = new DiagLabel();
        revisedDiagLabel.setText(structureMap.get("修正诊断"));
        beHospitalizedDoc.setRevisedDiagLabel(revisedDiagLabel);
        if (StringUtil.isBlank(structureMap.get("修正诊断"))) {
            beHospitalizedDoc.setRevisedDiagLabel(null);
        }

        // 走模型
        DiagLabel suppleDiagLabel = new DiagLabel();
        suppleDiagLabel.setText(structureMap.get("补充诊断"));
        beHospitalizedDoc.setSuppleDiagLabel(suppleDiagLabel);
        if (StringUtil.isBlank(structureMap.get("补充诊断"))) {
            beHospitalizedDoc.setSuppleDiagLabel(null);
        }

        beHospitalizedDoc.setStructureMap(structureMap);

        return beHospitalizedDoc;
    }

    /**
     * 给structureMap添加一个key（映射）
     *
     * @param structureMap
     * @param target       需要用到的key
     * @param source       structureMap中含有的key
     */
    protected void addKeyMapping(Map<String, String> structureMap, String target, String source) {
        if (StringUtils.isEmpty(structureMap.get(target)) && StringUtils.isNotEmpty(structureMap.get(source))) {
            structureMap.put(target, structureMap.get(source));
        }
    }

    /**
     * 日间病历解析全用切词方式
     *
     * @param text
     * @param behDeptId
     */
    private Map<String, String> dailyTrans(String text, String behDeptId) {
        Map<String, String> parseMap = Maps.newHashMap();
        List<String> titles = Lists.newArrayList();
        switch (behDeptId) {
            case "51923":
                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "月 经 史", "婚 育 史", "体格检查", "妇科检查", "入院诊断", "诊疗情况",
                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "医师签名", "记录医师", "主刀医师签名",
                        "记录时间", "时间");
                break;
            case "52883":
                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
                        "记录医师", "记录时间", "时间");
                break;
            case "52903":
                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
                        "记录医师", "记录时间", "时间");
                break;
            case "52923":
                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
                        "记录医师", "记录时间", "时间");
                break;
            case "53523":
                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
                        "记录医师", "记录时间", "时间");
                break;
        }
        titles = CommonAnalysisUtil.sortTitles(titles, text);
        CommonAnalysisUtil.cutByTitles(text, titles, 0, parseMap);
        return parseMap;
    }

    private String modifyDiagKey(String text, String key) {
        if (text.contains(key + ":")) {
            text = text.replaceFirst("医师签名", key + "医师");
            text = text.replaceFirst("日期", key + "时间");
        }
        return text;
    }

}