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

import com.lantone.qc.kernel.catalogue.QCCatalogue;
import com.lantone.qc.kernel.util.CatalogueUtil;
import com.lantone.qc.kernel.util.KernelConstants;
import com.lantone.qc.kernel.util.RedisUtil;
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.FirstCourseRecordDoc;
import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
import com.lantone.qc.pub.util.DateUtil;
import com.lantone.qc.pub.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @ClassName : THR0128
 * @Description : 每周无3次主治医师查房记录
 * @Author : 胡敬
 * @Date: 2020-03-19 16:52
 */
@Component
public class THR0128 extends QCCatalogue {
    @Autowired
    private RedisUtil redisUtil;

    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
        status.set("0");
        if (inputInfo.getLeaveHospitalDoc() != null
                && inputInfo.getBeHospitalizedDoc() != null && inputInfo.getBeHospitalizedDoc().getStructureMap() != null
                && inputInfo.getThreeLevelWardDocs().size() > 0) {
            Map<String, String> leaveHospitalStructureMap = inputInfo.getLeaveHospitalDoc().getStructureMap();
            String admisTime = leaveHospitalStructureMap.get(Content.admisTime);
            String dischargeTime = leaveHospitalStructureMap.get(Content.dischargeTime);
            if (CatalogueUtil.isEmpty(admisTime) || CatalogueUtil.isEmpty(dischargeTime)) {
                return;
            }
            //开始时间(入院时间)
            Date beginDate = StringUtil.parseDateTime(admisTime);
            if (beginDate == null) {
                return;
            }
            //如果住院天数小于7天则不判断该条规则
            if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (7 * 24 * 60))) {
                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(DateUtil.addDate(beginDate, 1));
            int i = 1;
            String lastWardDateRange = "";
            //每周的病历记录
            while (i >= 1) {
                roundRecordThisWeek = extractWardRecord(allDoctorWradDocs, beginDate, hoursPerWeek, lastRecordDate);
                if (CatalogueUtil.isEmpty(roundRecordThisWeek)) {
                    break;
                }
                lastWardDateRange = DateUtil.formatDate(beginDate) + "    ->    " + DateUtil.formatDate(DateUtil.addDate(beginDate, 7));
                roundRecordEveryWeek.add(roundRecordThisWeek);
                beginDate = DateUtil.addDate(beginDate, 7);
                i++;
            }
            if (roundRecordEveryWeek.size() == 0) {
                status.set("0");
                return;
            }
            boolean firstRecordAttendExist = findfirstRecordAttend(inputInfo);
            for (int j = 0; j < roundRecordEveryWeek.size(); j++) {
                int indicationsNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.attend);
                if (j == 0 && firstRecordAttendExist) { //如果首程中医师签名为主治医师，第一周查房记录也要加上
                    indicationsNum += 1;
                }
                if (indicationsNum < 3) {
                    //每周无3次主治医师查房记录
                    status.set("-1");
                    info.set(lastWardDateRange);
                    return;
                }
            }
            for (String roundRecord : roundRecordEveryWeek) {
                int indicationsNum = CatalogueUtil.appearNumber(roundRecord.split(","), Content.attend);
                if (indicationsNum < 3) {
                    //每周无3次主治医师查房记录
                    status.set("-1");
                    info.set(lastWardDateRange);
                    return;
                }
            }
        }
    }

    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(List<ThreeLevelWardDoc> threeLevelWardDocs, Date admisDate, int duration, Date maxRecordDate) {
        String recordTime = "", recordTitle = "";
        List<Date> dateList = new ArrayList();
        for (ThreeLevelWardDoc threeLevelWardDoc : threeLevelWardDocs) {
            Map<String, String> threeLevelWardStructureMap = threeLevelWardDoc.getStructureMap();
            recordTime = threeLevelWardStructureMap.get("查房日期");
            Date recordDate = StringUtil.parseDateTime(recordTime);
            if (recordDate == null) {
                continue;
            }
            if (admisDate.before(recordDate) && !CatalogueUtil.compareTime(admisDate, recordDate, Long.valueOf(duration))) {
                String title = threeLevelWardStructureMap.get("查房标题");
                if (StringUtil.isNotBlank(title)) {
                    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 "";
    }

    private boolean findfirstRecordAttend(InputInfo inputInfo) {
        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
        if (firstCourseRecordDoc == null) {
            return false;
        }
        Map<String, Map<String, Object>> hospitalDoctorMap = redisUtil.getJsonStringValue(KernelConstants.HOSPITAL_DOCTOR_MAP);
        String doctorSign = firstCourseRecordDoc.getStructureMap().get("医师签名");
        if (hospitalDoctorMap == null || StringUtil.isBlank(doctorSign)) {
            return false;
        }
        if (hospitalDoctorMap.containsKey(doctorSign)) {
            Object professor = hospitalDoctorMap.get(doctorSign).get("professor");
            if (professor != null) {
                return professor.toString().contains("主治");
            }
        }
        return false;
    }
}