package com.lantone.qc.trans.taizhou;

import com.google.common.collect.Lists;
import com.lantone.qc.dbanaly.facade.taizhou.TzXmlUtil;
import com.lantone.qc.dbanaly.lt.facade.ModelHospitalFacade;
import com.lantone.qc.dbanaly.util.KernelConstants;
import com.lantone.qc.dbanaly.util.SpecialStorageUtil;
import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
import com.lantone.qc.pub.model.doc.operation.OperationDoc;
import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
import com.lantone.qc.pub.model.doc.ward.AttendingDoctorWardDoc;
import com.lantone.qc.pub.model.doc.ward.DirectorDoctorWardDoc;
import com.lantone.qc.pub.model.doc.ward.GeneralDoctorWardDoc;
import com.lantone.qc.pub.model.vo.MedrecVo;
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.OrdinaryAssistant;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description: 查房记录文档生成
 * @author: rengb
 * @time: 2020/3/17 13:27
 */
@Setter
public class TaiZhouThreeLevelWardDocTrans extends ModelDocTrans {

    private List<String> recTitles;
    private List<OperationDoc> operationDocs;

    @Override
    public List<ThreeLevelWardDoc> extract(MedrecVo medrecVo) {
        ModelHospitalFacade modelHospitalFacade = SpringContextUtil.getBean(ModelHospitalFacade.class);
        recTitles = modelHospitalFacade.getRecTitles(3l, 4l);

        List<ThreeLevelWardDoc> retList = Lists.newArrayList();
        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");

        ThreeLevelWardDoc result = new ThreeLevelWardDoc();
        contentMaps.forEach(contentMap -> {
            classifyThreeLevelWardDoc(result, contentMap);
        });
        retList.add(result);
        return retList;
    }

    private void classifyThreeLevelWardDoc(ThreeLevelWardDoc result, Map<String, Object> contentMap) {
        String content = contentMap.get("xmlText").toString();
        Map<String, String> sourceMap = TzXmlUtil.getXmlToMapForTZ(content);
        sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
        String recTitle = contentMap.get("recTitle").toString();
        if (recTitles.contains(recTitle)) {
            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
        }
        Map<String, String> structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);

        if (StringUtils.isEmpty(structureMap.get("查房日期"))) {
            return;
        }
        //不能简单的标准转化，如果有查房标题，优先使用
        if (StringUtils.isEmpty(structureMap.get("查房标题")) && StringUtils.isNotEmpty(structureMap.get("查房备注"))) {
            structureMap.put("查房标题", structureMap.get("查房备注"));
        }
        if (StringUtils.isEmpty(structureMap.get("查房标题")) && StringUtils.isNotEmpty(structureMap.get("查房类别"))) {
            structureMap.put("查房标题", structureMap.get("查房类别"));
        }
        if (StringUtils.isEmpty(structureMap.get("查房标题")) && StringUtils.isNotEmpty(structureMap.get("上级查房医生职称"))) {
            structureMap.put("查房标题", structureMap.get("上级查房医生职称"));
        }
        //总的查房记录 汇总
        ThreeLevelWardDoc allDoctorWradDoc = new ThreeLevelWardDoc();
        allDoctorWradDoc.setStructureMap(structureMap);
        allDoctorWradDoc.setPageData((Map) structureMap);
        result.addAllDoctorWradDoc(allDoctorWradDoc);

        //主任医师查房
        DirectorDoctorWardDoc directorDoctorWardDoc = findDirectorDoctorWardDoc(structureMap);
        if (directorDoctorWardDoc != null) {
            result.addDirectorDoctorWardDoc(findDirectorDoctorWardDoc(structureMap));
        }
        //主治医师查房
        AttendingDoctorWardDoc attendingDoctorWardDoc = findAttendingDoctorWardDoc(structureMap);
        if (attendingDoctorWardDoc != null) {
            result.addAttendingDoctorWardDoc(attendingDoctorWardDoc);
        }
        //普通医师查房
        if (directorDoctorWardDoc == null && attendingDoctorWardDoc == null) {
            GeneralDoctorWardDoc generalDoctorWardDoc = new GeneralDoctorWardDoc();
            generalDoctorWardDoc.setStructureMap(structureMap);
            generalDoctorWardDoc.setPageData((Map) structureMap);
            result.addGeneralDoctorWardDoc(generalDoctorWardDoc);
        }
    }

    /**
     * 主任医师查房
     *
     * @param structureMap
     */
    private DirectorDoctorWardDoc findDirectorDoctorWardDoc(Map<String, String> structureMap) {
        String title = structureMap.get("查房标题");
        String recordDateStr = structureMap.get("查房日期");
        Date recordDate = StringUtil.parseDateTime(recordDateStr);
        DirectorDoctorWardDoc directorDoctorWardDoc = null;
        if (StringUtils.isNotEmpty(title)) {
            if (title.contains("主刀")) {
                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "主刀医师");
                title = title.replace("主刀", doctorTitle);
            } else if (title.contains("一助")) {
                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "一助");
                title = title.replace("一助", doctorTitle);
            }
            if (StringUtils.isNotEmpty(subTitle(title)) && subTitle(title).contains("主任")) {    //标题有代字)
                directorDoctorWardDoc = new DirectorDoctorWardDoc();
                directorDoctorWardDoc.setStructureMap(structureMap);
                directorDoctorWardDoc.setPageData((Map) structureMap);
            }
        }
        return directorDoctorWardDoc;
    }

    /**
     * 主治医师查房
     *
     * @param structureMap
     */
    private AttendingDoctorWardDoc findAttendingDoctorWardDoc(Map<String, String> structureMap) {
        String title = structureMap.get("查房标题");
        String recordDateStr = structureMap.get("查房日期");
        Date recordDate = StringUtil.parseDateTime(recordDateStr);
        AttendingDoctorWardDoc attendingDoctorWardDoc = null;
        if (StringUtils.isNotEmpty(title)) {
            if (title.contains("主刀")) {
                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "主刀医师");
                title = title.replace("主刀", doctorTitle);
            } else if (title.contains("一助")) {
                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "一助");
                title = title.replace("一助", doctorTitle);
            }
            if (StringUtils.isNotEmpty(subTitle(title)) && subTitle(title).contains("主治")) {    //标题有代字)
                attendingDoctorWardDoc = new AttendingDoctorWardDoc();
                attendingDoctorWardDoc.setStructureMap(structureMap);
                attendingDoctorWardDoc.setPageData((Map) structureMap);
            }
        }
        return attendingDoctorWardDoc;
    }

    private List<String> keyContrasts = Lists.newArrayList(
            "事件日期=记录时间",
            "事件日期=查房日期",
            "简要病情=病情记录",
            "查房记录=病情记录",
            "医生=记录医师"
    );

    public static String subTitle(String srcText) {
        if (StringUtil.isNotBlank(srcText) && srcText.contains("代") && srcText.indexOf("代") != srcText.length() - 1) {
            srcText = srcText.substring(srcText.lastIndexOf("代") + 1);
        }
        return srcText;
    }

    /**
     * 获取主刀医师/一助职称(取距离查房记录时间最近的一次手术记录)
     *
     * @param operationDocs
     * @return
     */
    public static String getDoctorTitle(List<OperationDoc> operationDocs, Date recordDate, String findTitle) {
        String title = "";
        SpecialStorageUtil specialStorageUtil = SpringContextUtil.getBean("specialStorageUtil");
        Map<String, Object> surgeon = specialStorageUtil.getJsonStringValue(KernelConstants.HOSPITAL_DOCTOR_MAP);
        if (surgeon == null) {
            return title;
        }
        /* 用于存放手术结束时间距离查房时间最近的一次时间差 */
        long timeDiff = 0L;
        for (OperationDoc operationDoc : operationDocs) {
            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
            if (operationRecordDoc == null) {
                continue;
            }
            Map<String, String> structureMap = operationRecordDoc.getStructureMap();
            String chiefSurgeon = structureMap.get(findTitle);
            String operatorEndDateStr = structureMap.get("手术结束时间");

            if (StringUtil.isBlank(chiefSurgeon) || StringUtil.isBlank(operatorEndDateStr)) {
                continue;
            }
            Map<String, String> doctor = (Map) surgeon.get(chiefSurgeon);
            if (doctor != null) {
                String professor = doctor.get("professor");
                Date operatorEndDate = StringUtil.parseDateTime(operatorEndDateStr);
                if (operatorEndDate != null) {
                    long timeDifference = timeDifference(operatorEndDate, recordDate);
                    if (timeDifference == 0) {
                        continue;
                    }
                    if (timeDiff == 0 || timeDiff > timeDifference) {
                        /* 取距离此次主刀医师查房最近的一次手术时间 */
                        timeDiff = timeDifference;
                        title = professor;
                    }
                }
            }
        }
        return title;
    }

    public static long timeDifference(Date firstDate, Date secondDate) {
        long timeDifference = 0L;
        if (firstDate == null || secondDate == null) {
            return timeDifference;
        }
        boolean flag = false;
        if (firstDate.before(secondDate)) {
            flag = true;
        }
        Calendar calendarS = Calendar.getInstance();
        Calendar calendarE = Calendar.getInstance();
        long timeS, timeE;
        try {
            calendarS.setTime(firstDate);
            calendarE.setTime(secondDate);

            timeS = calendarS.getTimeInMillis();
            timeE = calendarE.getTimeInMillis();

            if (flag) {
                timeDifference = (timeE - timeS) / (1000 * 60);
            } else {
                timeDifference = (timeS - timeE) / (1000 * 60);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return timeDifference;
    }

}