package com.lantone.structure.ai;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.lantone.common.util.ListUtil;
import com.lantone.structure.ai.process.*;
import com.lantone.structure.client.CRFServiceClient;
import com.lantone.structure.client.SimilarityServiceClient;
import com.lantone.common.util.CatalogueUtil;
import com.lantone.structure.model.Content;
import com.lantone.structure.model.InputInfo;
import com.lantone.structure.model.doc.DailyCourseRecordDoc;
import com.lantone.structure.model.doc.FirstCourseRecordDoc;
import com.lantone.structure.model.entity.Diag;
import com.lantone.structure.model.entity.Drug;
import com.lantone.structure.model.label.*;
import com.lantone.common.util.StringUtil;
import org.apache.commons.lang3.StringUtils;

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

/**
 * @ClassName : FirstCourseRecordAI
 * @Description :
 * @Author : 楼辉荣
 * @Date: 2020-03-19 14:52
 */
public class FirstCourseRecordAI extends ModelAI {
    /**
     *
     */
    public static List<String> medicalTextType = Arrays.asList("FirstCoursera_cx", "Diagnoses_cx"
            , "FirstCourseTreatment_cx", "CourseRecordSRR","Taizhou_daily_record");
    public static String entityRelationObject = "entity_relation_object";
    public static String outputs = "outputs";
    public static String content = "content";

    public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient, SimilarityServiceClient similarityServiceClient) {
        JSONArray crfContent = new JSONArray();
        JSONArray similarContent = new JSONArray();
        List<DailyCourseRecordDoc> dailyCourseRecordDocs  = inputInfo.getDailyCourseRecordDocs();
        if (ListUtil.isNotEmpty(dailyCourseRecordDocs)) {
            DailyCourseRecordDoc dailyCourseRecordDoc = dailyCourseRecordDocs.get(0);
            if (dailyCourseRecordDoc != null) {
                String text = dailyCourseRecordDoc.getText();
                putContent(crfContent, medicalTextType.get(4), text, Content.doctorAdviceRecord);
                JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
                dailyCourseRecordCrfData(midData.getJSONObject(Content.doctorAdviceRecord), inputInfo);
            }
        }
        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
        if (firstCourseRecordDoc != null) {
            Map<String, String> structureMap = firstCourseRecordDoc.getStructureMap();

            //病历特点
            //putContent(crfContent, medicalTextType.get(0), firstCourseRecordDoc.getCaseCharacteristicLabel().getText(), Content.case_feature);
            //初步诊断
            if (StringUtils.isNotEmpty(structureMap.get(Content.initial_diag))) {
                String initial_diag = structureMap.get(Content.initial_diag);
                /*if (CatalogueUtil.numberExist(initial_diag)) {
                    initial_diag = CatalogueUtil.removeBetweenWordSpace(structureMap.get(Content.initial_diag));
                }*/
                putContent(crfContent, medicalTextType.get(1), initial_diag, Content.initial_diag);
            } else if (firstCourseRecordDoc.getInitialDiagLabel() != null && StringUtil.isNotBlank(firstCourseRecordDoc.getInitialDiagLabel().getText())) {
                String initial_diag = firstCourseRecordDoc.getInitialDiagLabel().getText();
                /*if (CatalogueUtil.numberExist(initial_diag)) {
                    initial_diag = CatalogueUtil.removeBetweenWordSpace(firstCourseRecordDoc.getInitialDiagLabel().getText());
                }*/
                putContent(crfContent, medicalTextType.get(1), initial_diag, Content.initial_diag);
            }

            //诊断依据
            //putContent(crfContent, medicalTextType.get(0), firstCourseRecordDoc.getDiagnosisLabel().getText(), Content.diag_basis);
            //鉴别诊断
            if (StringUtils.isNotEmpty(structureMap.get("鉴别诊断"))) {
                String diffDiag = structureMap.get("鉴别诊断");
                /*if (CatalogueUtil.numberExist(diffDiag)) {
                    diffDiag = CatalogueUtil.removeBetweenWordSpace(diffDiag);
                }*/
                putContent(crfContent, medicalTextType.get(1), diffDiag, "鉴别诊断");
            } else if (firstCourseRecordDoc.getDifferentialDiagLabel() != null && StringUtil.isNotBlank(firstCourseRecordDoc.getDifferentialDiagLabel().getText())) {
                String diffDiag = firstCourseRecordDoc.getDifferentialDiagLabel().getText();
                /*if (CatalogueUtil.numberExist(diffDiag)) {
                    diffDiag = CatalogueUtil.removeBetweenWordSpace(diffDiag);
                }*/
                putContent(crfContent, medicalTextType.get(1), diffDiag, "鉴别诊断");
            }
            //诊疗计划
            TreatPlanLabel treatPlanLabel = firstCourseRecordDoc.getTreatPlanLabel();
            if (treatPlanLabel != null && StringUtil.isNotBlank(treatPlanLabel.getAiText())) {
                putContent(crfContent, medicalTextType.get(2), treatPlanLabel.getAiText(), "诊疗计划");
            }

            String drugContent = CatalogueUtil.structureMapJoin(structureMap, Lists.newArrayList("诊疗计划"));
            putContent(crfContent, medicalTextType.get(3), drugContent, "药品");
            /*
            if (StringUtils.isNotEmpty(structureMap.get("诊疗计划")) && StringUtils.isNotEmpty(structureMap.get("需求评估"))) {
                putContent(crfContent, medicalTextType.get(2), structureMap.get("诊疗计划") + structureMap.get("需求评估"), "诊疗计划");
                firstCourseRecordDoc.getTreatPlanLabel().setText(structureMap.get("诊疗计划") + structureMap.get("需求评估"));
            } else if (StringUtils.isNotEmpty(structureMap.get("诊疗计划"))) {
                putContent(crfContent, medicalTextType.get(2), structureMap.get("诊疗计划"), "诊疗计划");
                firstCourseRecordDoc.getTreatPlanLabel().setText(structureMap.get("诊疗计划"));
            } else if (StringUtils.isNotEmpty(structureMap.get("需求评估"))) {
                putContent(crfContent, medicalTextType.get(2), structureMap.get("需求评估"), "诊疗计划");
                firstCourseRecordDoc.getTreatPlanLabel().setText(structureMap.get("需求评估"));
            } else {
                putContent(crfContent, medicalTextType.get(2), firstCourseRecordDoc.getTreatPlanLabel().getText(), "诊疗计划");
            }
             */

            //病历特点与现病史比较相似度
            if (inputInfo.getBeHospitalizedDoc() != null) {
                //先从结构化数据找病例特点
                if (StringUtil.isNotBlank(structureMap.get("现病史")) && inputInfo.getBeHospitalizedDoc().getPresentLabel() != null) {
                    putContent(similarContent, structureMap.get("现病史"), inputInfo.getBeHospitalizedDoc().getPresentLabel().getText());
                } else if (firstCourseRecordDoc.getCaseCharacteristicLabel() != null && StringUtil.isNotBlank(firstCourseRecordDoc.getCaseCharacteristicLabel().getText())
                        && inputInfo.getBeHospitalizedDoc().getPresentLabel() != null) {
                    //再从doc找病例特点
                    putContent(similarContent, firstCourseRecordDoc.getCaseCharacteristicLabel().getText(), inputInfo.getBeHospitalizedDoc().getPresentLabel().getText());
                }
            }

            JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
            //if (midData.containsKey(Content.case_feature)) {
            //  putCaseCharacteristicCrfData(midData.getJSONObject(Content.case_feature), inputInfo);//处理病历特点
            //}
            if (midData.containsKey(Content.initial_diag)) {
                putInitialDiagCrfData(midData.getJSONObject(Content.initial_diag), inputInfo);//处理初步诊断
            }
            //if (midData.containsKey(Content.diag_basis)) {
            //    putDiagnosisCrfData(midData.getJSONObject(Content.diag_basis), inputInfo);//处理诊断依据
            //}
            if (midData.containsKey("鉴别诊断")) {
                putDifferentialDiagCrfData(midData.getJSONObject("鉴别诊断"), inputInfo);//处理鉴别诊断
            }
            if (midData.containsKey("诊疗计划")) {
                putTreatPlanCrfData(midData.getJSONObject("诊疗计划"), inputInfo);//处理诊疗计划
            }
            if (midData.containsKey("药品")) {
                putDrugCrfData(midData.getJSONObject("药品"), inputInfo);
            }

            double likeRate = loadSimilarAI(similarContent, similarityServiceClient);
            putCaseCharacteristicSimilarData(likeRate, inputInfo);//存放与现病史文本相似度
        }
    }

    /**
     * 病历特点
     *
     * @param jsonObject
     * @param inputInfo
     */
    public void putCaseCharacteristicCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
        //使用现病史结构来处理病历特点
        if (aiOut == null) {
            return;
        }
        EntityProcessClinic entityProcessClinic = new EntityProcessClinic();
        PresentLabel presentLabel = entityProcessClinic.extractEntity(aiOut);
        //临床表现
        inputInfo.getFirstCourseRecordDoc().getCaseCharacteristicLabel().setClinicals(presentLabel.getClinicals());
    }

    /**
     * 病历特点与现病史相似度
     *
     * @param likeRate
     * @param inputInfo
     */
    public void putCaseCharacteristicSimilarData(double likeRate, InputInfo inputInfo) {
        //存放与现病史文本相似度
        inputInfo.getFirstCourseRecordDoc().getCaseCharacteristicLabel().setLikeRate(likeRate);
    }

    /**
     * 初步诊断
     *
     * @param jsonObject
     * @param inputInfo
     */
    public void putInitialDiagCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
        if (aiOut == null) {
            return;
        }
        //诊断信息
        EntityProcessDiag entityProcessDiag = new EntityProcessDiag();
        List<Diag> diags = entityProcessDiag.extractEntity(aiOut);
        inputInfo.getFirstCourseRecordDoc().getInitialDiagLabel().setDiags(diags);
    }

    /**
     * 处理日常病程记录
     *
     * @param jsonObject
     */
    public void dailyCourseRecordCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        if (jsonObject == null) {
            return;
        }
        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
        if (aiOut == null) {
            return;
        }
        EntityDailyCourseRecord entityDailyCourseRecord = new EntityDailyCourseRecord();
        DailyCourseRecordLabel dailyCourseRecordLabel = entityDailyCourseRecord.extractEntity(aiOut);
        inputInfo.getDailyCourseRecordDocs().get(0).setDailyCourseRecordLabel(dailyCourseRecordLabel);
    }

    /**
     * 诊断依据
     *
     * @param jsonObject
     * @param inputInfo
     */
    public void putDiagnosisCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
        if (aiOut == null) {
            return;
        }
        //使用现病史结构来处理诊断依据
        EntityProcessClinic entityProcessClinic = new EntityProcessClinic();
        PresentLabel presentLabel = entityProcessClinic.extractEntity(aiOut);
        //临床表现
        inputInfo.getFirstCourseRecordDoc().getDiagnosisLabel().setClinicals(presentLabel.getClinicals());
    }

    /**
     * 鉴别诊断
     *
     * @param jsonObject
     * @param inputInfo
     */
    public void putDifferentialDiagCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
        if (aiOut == null) {
            return;
        }
        //诊断信息
        EntityProcessDiag entityProcessDiag = new EntityProcessDiag();
        List<Diag> diags = entityProcessDiag.extractEntity(aiOut);
        inputInfo.getFirstCourseRecordDoc().getDifferentialDiagLabel().setDiags(diags);
    }

    /**
     * 诊疗计划
     *
     * @param jsonObject
     * @param inputInfo
     */
    public void putTreatPlanCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
        if (aiOut == null) {
            return;
        }
        //诊疗计划
        EntityProcessTreatPlan entityProcessTreatPlan = new EntityProcessTreatPlan();
        TreatPlanLabel treatPlanLabel = entityProcessTreatPlan.extractEntity(aiOut);
        treatPlanLabel.setText(inputInfo.getFirstCourseRecordDoc().getTreatPlanLabel().getText());
        inputInfo.getFirstCourseRecordDoc().setTreatPlanLabel(treatPlanLabel);
    }

    /**
     * 存放抓取的药品
     *
     * @param jsonObject
     * @param inputInfo
     */
    public void putDrugCrfData(JSONObject jsonObject, InputInfo inputInfo) {
        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
        if (aiOut == null) {
            return;
        }
        EntityProcessDrug entityProcessDrug = new EntityProcessDrug();
        List<Drug> drugs = entityProcessDrug.extractEntity(aiOut);
        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
        DrugLabel label = new DrugLabel();
        label.setDrugs(drugs);
        firstCourseRecordDoc.setDrugLabel(label);
    }
}