package com.lantone.qc.kernel.catalogue.ninghaiyiyi.threelevelward;

import com.lantone.qc.kernel.catalogue.QCCatalogue;
import com.lantone.qc.kernel.util.CatalogueUtil;
import com.lantone.qc.pub.Content;
import com.lantone.qc.pub.model.InputInfo;
import com.lantone.qc.pub.model.OutputInfo;
import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
import com.lantone.qc.pub.model.doc.operation.OperationDoc;
import com.lantone.qc.pub.util.DateUtil;
import com.lantone.qc.pub.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

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

/**
 * @ClassName : THR0127
 * @Description : 每周无2次副主任医师/主任医师查房记录
 * @Author : 胡敬
 * @Date: 2020-03-19 15:52
 */
@Component
public class THR0127 extends QCCatalogue {
    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
        status.set("0");
        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
        if (medicalRecordInfoDoc != null && medicalRecordInfoDoc.getStructureMap() != null) {
            //入院日期
            String admisTime = medicalRecordInfoDoc.getStructureMap().get("behospitalDate");
            //出院日期
            String dischargeTime = medicalRecordInfoDoc.getStructureMap().get("leaveHospitalDate");
            if (CatalogueUtil.isEmpty(admisTime)) {
                return;
            }
            String presentTime = DateUtil.nowString();
            //如果如果入院未超过7天则不判断该条规则
            if (!CatalogueUtil.isEmpty(admisTime) && !CatalogueUtil.isEmpty(presentTime)) {
                if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(presentTime), (long) (7 * 24 * 60))) {
                    return;
                }
            }
            //如果住院天数小于7天则不判断该条规则
            if (!CatalogueUtil.isEmpty(admisTime) && !CatalogueUtil.isEmpty(dischargeTime)) {
                if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (7 * 24 * 60))) {
                    return;
                }
            } else {
                if (inputInfo.getThreeLevelWardDocs().size() == 0) {
                    status.set("-1");
                    return;
                }
            }

            if (inputInfo.getBeHospitalizedDoc() != null && inputInfo.getThreeLevelWardDocs().size() > 0) {
                if (CatalogueUtil.isEmpty(admisTime)) {
                    return;
                }
                //开始时间(入院时间)
                Date beginDate = StringUtil.parseDateTime(admisTime);
                if (beginDate == null) {
                    return;
                }

                ThreeLevelWardDoc threeLevelWardDoc = inputInfo.getThreeLevelWardDocs().get(0);
                List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDoc.getAllDoctorWradDocs();
                if (allDoctorWradDocs.size() == 0) {
                    status.set("0");
                    return;
                }
                Date lastRecordDate = getLastRecordDate(allDoctorWradDocs);
                if (lastRecordDate == null) {
                    return;
                }
                int hoursPerWeek = 7 * 24 * 60;
                String roundRecordThisWeek = "";
                List<String> roundRecordEveryWeek = new ArrayList<>();
                beginDate = DateUtil.dateZeroClear(beginDate);//从入院记录当天0点开始算
                int i = 1;
                String lastWardDateRange = "";
                List<String> lastWardDateRangeList = new ArrayList<>();
                //每周的病历记录
                while (i >= 1) {
                    roundRecordThisWeek = extractWardRecord(inputInfo, allDoctorWradDocs, beginDate, hoursPerWeek, lastRecordDate);
                    if (CatalogueUtil.isEmpty(roundRecordThisWeek)) {
                        break;
                    }
                    //如果6天后日期大于出院日期，跳过
                    if (StringUtil.isBlank(dischargeTime)) {
                        dischargeTime = presentTime;
                    }
                    Date sixDate = DateUtil.addDate(beginDate, 7);
                    if (StringUtil.parseDateTime(dischargeTime).before(sixDate)) {
                        break;
                    }
                    lastWardDateRange = DateUtil.formatDate(beginDate) + "    ->    " + DateUtil.formatDate(sixDate);
                    lastWardDateRangeList.add(lastWardDateRange);
                    roundRecordEveryWeek.add(roundRecordThisWeek);
                    beginDate = DateUtil.addDate(beginDate, 7);
                    i++;
                }
                if (roundRecordEveryWeek.size() == 0) {
                    status.set("0");
                    return;
                }
                List<String> resultInfos = new ArrayList<>();
                for (int j = 0; j < roundRecordEveryWeek.size(); j++) {
                    int directorNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.director);
                    int dept_doctorNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.dept_doctor);
                    //三级医师查房算一次主任查房
                    int threeDoctorNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), "三级");
                    //北仑内分泌科（主任携主任代主治）
                    int endocrinologyTitleNum = endocrinologyTitleNum(roundRecordEveryWeek.get(j).split(","));
                    if (directorNum + dept_doctorNum + threeDoctorNum + endocrinologyTitleNum < 2) {
                        //每周无2次主任医师查房记录/科主任查房记录
                        status.set("-1");
                        resultInfos.add(lastWardDateRangeList.get(j));
                    }
                }
                if (resultInfos.size() > 0) {
                    info.set(StringUtils.join(resultInfos.toArray(), "；"));
                }
            }
        }
    }

    /**
     * 北仑内分泌科主任主治处理
     *
     * @param srcText
     * @return
     */
    private int endocrinologyTitleNum(String[] srcText) {
        int count = 0;
        for (String title : srcText) {
            String regex = ".*主任.*主任.*主治.*";
            if (title.matches(regex)) {
                count++;
            }
        }
        return count;
    }

    private Date getLastRecordDate(List<ThreeLevelWardDoc> allDoctorWradDocs) {
        ThreeLevelWardDoc threeLevelWardDoc = allDoctorWradDocs.get(allDoctorWradDocs.size() - 1);
        Map<String, String> lastWardDocStructureMap = threeLevelWardDoc.getStructureMap();
        String wardDateStr = lastWardDocStructureMap.get("查房日期");
        if (StringUtil.isNotBlank(wardDateStr)) {
            return StringUtil.parseDateTime(wardDateStr);
        }
        return null;
    }

    /**
     * 抽取duration分钟内所有查房标题
     * 抽取一周内所有查房标题，若一周内记录少于6天，则返回""
     *
     * @param threeLevelWardDocs
     * @param admisDate
     * @param duration
     * @return
     */
    private static String extractWardRecord(InputInfo inputInfo, List<ThreeLevelWardDoc> threeLevelWardDocs, Date admisDate, int duration, Date maxRecordDate) {
        String recordTime = "", recordTitle = "", title = "";
        List<Date> dateList = new ArrayList();
        for (ThreeLevelWardDoc threeLevelWardDoc : threeLevelWardDocs) {
            Map<String, String> threeLevelWardStructureMap = threeLevelWardDoc.getStructureMap();
            recordTime = threeLevelWardStructureMap.get("查房日期");
            title = threeLevelWardStructureMap.get("查房标题");
            if (StringUtil.isBlank(recordTime) || StringUtil.isBlank(title)) {
                continue;
            }
            Date recordDate = StringUtil.parseDateTime(recordTime);
            if (recordDate == null) {
                continue;
            }
            /* 替换查房标题中主刀/一助的职称 */
            List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
            if (title.contains("主刀") || title.contains("术后第")) {
                String doctorTitle = CatalogueUtil.getDoctorTitle(operationDocs, recordDate, "主刀医师");
                title = title.replace("主刀", doctorTitle).replace("术后第", doctorTitle);
            } else if (title.contains("一助")) {
                String doctorTitle = CatalogueUtil.getDoctorTitle(operationDocs, recordDate, "一助");
                title = title.replace("一助", doctorTitle);
            }
            if (admisDate.before(recordDate) && !CatalogueUtil.compareTime(admisDate, DateUtil.dateZeroClear(recordDate), Long.valueOf(duration))) {
                recordTitle += title + ",";
                dateList.add(recordDate);
            }
        }
        if (dateList.size() > 0) {
            //dateList.sort(Date::compareTo);
            if (!maxRecordDate.equals(dateList.get(dateList.size() - 1)) || CatalogueUtil.compareTime(admisDate, dateList.get(dateList.size() - 1), Long.valueOf(6 * 24 * 60))) {
                return recordTitle;
            }
        }
        return "";
    }
}