package cn.iocoder.yudao.module.system.service.nursing;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.*;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.service.biz.BuildService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 护理日志 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class NursingLogServiceImpl implements NursingLogService {

    @Resource
    private NursingLogMapper nursingLogMapper;
    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;
    @Resource
    private BuildService buildService;
    @Resource
    private NurseItemMapper nurseItemMapper;
    @Resource
    private NursingPlanItemMapper nursingPlanItemMapper;
    @Resource
    private NursingCategoryMapper nursingCategoryMapper;
    @Resource
    private NursingLogRecordMapper nursingLogRecordMapper;
    @Resource
    private NursingPlanMapper nursingPlanMapper;
    @Resource
    private NurseGroupDetailsMapper nurseGroupDetailsMapper;
    @Resource
    private NursingShiftMapper nursingShiftMapper;
    @Resource
    private ScheduleShiftMapper scheduleShiftMapper;
    @Resource
    private NursingLogRemarksMapper nursingLogRemarksMapper;
    @Resource
    private AdminUserMapper adminUserMapper;
    @Resource
    private NursingInspectionMapper nursingInspectionMapper;


    @Override
    public void createNursingLog(NursingPlanDO nursingPlanDO) {
        ElderlyInfoDO elderlyInfoDO = elderlyInfoMapper.selectById(nursingPlanDO.getElderId());

        NursingLogDO dbNursingLog = nursingLogMapper.selectOne(new LambdaQueryWrapperX<NursingLogDO>()
                .eq(NursingLogDO::getNursingDate, LocalDate.now())
                .eq(NursingLogDO::getElderId, elderlyInfoDO.getId()));

        if (dbNursingLog == null) {
            NursingLogDO nursingLogDO = new NursingLogDO();
            nursingLogDO.setElderId(nursingPlanDO.getElderId());
            nursingLogDO.setElderName(elderlyInfoDO.getElderName());
            nursingLogDO.setNursingGrade(elderlyInfoDO.getNurseLevelName());
            nursingLogDO.setCount(0);
            nursingLogDO.setBedId(elderlyInfoDO.getBedId());
            nursingLogDO.setBedName(buildService.getFullBedName(elderlyInfoDO.getId()));
            nursingLogDO.setNursingDate(LocalDate.now());
            nursingLogDO.setOrgType(elderlyInfoDO.getOrgType());
            nursingLogDO.setTenantId(elderlyInfoDO.getTenantId());
            nursingLogDO.setCreator("系统生成");
            nursingLogMapper.insert(nursingLogDO);
        }
    }

    @Override
    public void supplementNursingLog(NursingLogSaveReqVO createReqVO) {
        Long id = createReqVO.getId();
        NursingLogDO dbNursingLogDO = nursingLogMapper.selectById(id);
        if (dbNursingLogDO != null) {
            //先删除在新增
            nursingLogRecordMapper.delete(new LambdaQueryWrapperX<NursingLogRecordDO>()
                    .eq(NursingLogRecordDO::getNursingLogId, dbNursingLogDO.getId()));

            List<NursingLogRecordDO> nursingLogRecordList = createReqVO.getNursingLogRecords();
            for (NursingLogRecordDO nursingLogRecord : nursingLogRecordList) {
                NursingPlanItemDO nursingPlanItem = nursingPlanItemMapper.selectById(nursingLogRecord.getNursingPlanItemId());
                NurseItemDO nurseItemDO = nurseItemMapper.selectById(nursingPlanItem.getNurseItemId());
                NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectById(nurseItemDO.getCategoryId());
                NursingPlanDO nursingPlanDO = nursingPlanMapper.selectById(nursingPlanItem.getNursingPlanId());

                nursingLogRecord.setNursingLogId(dbNursingLogDO.getId());
                nursingLogRecord.setCategoryId(nursingCategoryDO.getId());
                nursingLogRecord.setCategoryName(nursingCategoryDO.getCategoryName());
                nursingLogRecord.setNurseItemImage(nurseItemDO.getImage());
                nursingLogRecord.setType(nursingPlanDO.getType());
                nursingLogRecord.setFrequency(nursingPlanItem.getFrequency());
                nursingLogRecord.setFrequencyUnit(nursingPlanItem.getFrequencyUnit());
                nursingLogRecord.setOperatingMode(nursingPlanItem.getOperatingMode());
                nursingLogRecordMapper.insert(nursingLogRecord);
            }
            //统计次数
            dbNursingLogDO.setCount(nursingLogRecordList.size());
            nursingLogMapper.updateById(dbNursingLogDO);
        }
    }

    @Override
    public Map<String, List<NursingLogRecordRespVO>> getNursingLogByTime(Long id, Integer type) {
        Map<String, List<NursingLogRecordRespVO>> dataMap = new HashMap<>();
        NursingLogDO nursingLogDO = nursingLogMapper.selectById(id);
        List<NursingLogRecordDO> nursingLogRecordList = nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                .eq(NursingLogRecordDO::getNursingLogId, nursingLogDO.getId())
                .eqIfPresent(NursingLogRecordDO::getType, type));

        //按照时间分组
        int morningStartHour = 6;
        int morningEndHour = 12;
        int afternoonEndHour = 18;
        int nightEnd = 24;

        List<NursingLogRecordRespVO> morningEvents = nursingLogRecordList.stream()
                .filter(e -> e.getNursingTime().getHour() >= morningStartHour && e.getNursingTime().getHour() < morningEndHour)
                .map(e -> {
                    NursingLogRecordRespVO respVO = new NursingLogRecordRespVO();
                    BeanUtils.copyProperties(e, respVO);
                    return respVO;
                })
                .sorted(Comparator.comparing(e -> e.getNursingTime().toLocalTime()))
                .collect(Collectors.toList());

        List<NursingLogRecordRespVO> afternoonEvents = nursingLogRecordList.stream().
                filter(e -> e.getNursingTime().getHour() >= morningEndHour && e.getNursingTime().getHour() < afternoonEndHour)
                .map(e -> {
                    NursingLogRecordRespVO respVO = new NursingLogRecordRespVO();
                    BeanUtils.copyProperties(e, respVO);
                    return respVO;
                }).sorted(Comparator.comparing(e -> e.getNursingTime().toLocalTime()))
                .collect(Collectors.toList());

        List<NursingLogRecordRespVO> nightEvents = nursingLogRecordList.stream().
                filter(e -> e.getNursingTime().getHour() >= afternoonEndHour && e.getNursingTime().getHour() < nightEnd)
                .map(e -> {
                    NursingLogRecordRespVO respVO = new NursingLogRecordRespVO();
                    BeanUtils.copyProperties(e, respVO);
                    return respVO;
                }).sorted(Comparator.comparing(e -> e.getNursingTime().toLocalTime()))
                .collect(Collectors.toList());


        List<NursingLogRecordRespVO> beforeDawnEvents = nursingLogRecordList.stream().
                filter(e -> e.getNursingTime().getHour() >= nightEnd && e.getNursingTime().getHour() < morningStartHour)
                .map(e -> {
                    NursingLogRecordRespVO respVO = new NursingLogRecordRespVO();
                    BeanUtils.copyProperties(e, respVO);
                    return respVO;
                }).sorted(Comparator.comparing(e -> e.getNursingTime().toLocalTime()))
                .collect(Collectors.toList());

        dataMap.put("morningEvents", morningEvents);   //6-12
        dataMap.put("afternoonEvents", afternoonEvents); //12-18
        dataMap.put("nightEvents", nightEvents);   //18-24
        dataMap.put("beforeDawnEvents", beforeDawnEvents); //24-6
        return dataMap;
    }

    @Override
    public List<NursingPlanItemRespVO> getDetails(Long elderId, Integer type, Long nursingLogId) {
        List<NursingPlanItemRespVO> dataList = new ArrayList<>();
        List<NursingPlanDO> nursingPlanList = nursingPlanMapper.selectList(new LambdaQueryWrapperX<NursingPlanDO>()
                .eq(NursingPlanDO::getElderId, elderId)
                .eqIfPresent(NursingPlanDO::getType, type));

        for (NursingPlanDO nursingPlan : nursingPlanList) {
            List<NursingPlanItemDO> nursingPlanItems = nursingPlanItemMapper.selectList(new LambdaQueryWrapperX<NursingPlanItemDO>()
                    .eq(NursingPlanItemDO::getNursingPlanId, nursingPlan.getId())
                    .eq(NursingPlanItemDO::getIsDelete, 0));

            List<NursingPlanItemRespVO> collect = nursingPlanItems.stream().map(e -> {
                NursingPlanItemRespVO respVO = new NursingPlanItemRespVO();
                BeanUtils.copyProperties(e, respVO);

                NurseItemDO nurseItemDO = nurseItemMapper.selectById(e.getNurseItemId());
                NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectById(nurseItemDO.getCategoryId());

                respVO.setCategoryId(nursingCategoryDO.getId());
                respVO.setCategoryName(nursingCategoryDO.getCategoryName());
                respVO.setNurseItemImage(nurseItemDO.getImage());

                //查询护理日志详情
                List<NursingLogRecordDO> nursingLogRecords = nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                        .eq(NursingLogRecordDO::getNursingPlanItemId, e.getId())
                        .eqIfPresent(NursingLogRecordDO::getNursingLogId, nursingLogId)
                        .orderByAsc(NursingLogRecordDO::getNursingTime));
                respVO.setActualFrequency(nursingLogRecords.size()); //实际次数
                respVO.setRecords(nursingLogRecords);
                return respVO;
            }).collect(Collectors.toList());
            dataList.addAll(collect);
        }
        return dataList;
    }

    @Override
    public List<Map<String, Object>> getNursingLogByItem(Long id, Integer type, String caregiverName, String nurseItemName) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        NursingLogDO nursingLog = nursingLogMapper.selectById(id);
        if (StringUtils.isBlank(caregiverName) && StringUtils.isBlank(nurseItemName)) {
            //查询护理分组
            List<NurseGroupDetailsDO> nurseGroupDetails = nurseGroupDetailsMapper.selectList(new LambdaQueryWrapperX<NurseGroupDetailsDO>()
                    .eq(NurseGroupDetailsDO::getElderId, nursingLog.getElderId()));
            //根据护理分组查询班次信息，护理信息
            for (NurseGroupDetailsDO nurseGroupDetail : nurseGroupDetails) {
                Map<String, Object> dataMap = new HashMap<>();
                String[] splitIds = nurseGroupDetail.getNursingPersonnelIds().split(",");
                for (String nurseId : splitIds) {
                    //查询当天班次信息
                    ScheduleShiftDO scheduleShiftDO = scheduleShiftMapper.selectOne(new LambdaQueryWrapperX<ScheduleShiftDO>()
                            .eq(ScheduleShiftDO::getNurseId, nurseId)
                            .eq(ScheduleShiftDO::getWorkDate, nursingLog.getNursingDate())
                            .eq(ScheduleShiftDO::getDeleted,0)
                            .notLike(ScheduleShiftDO::getShiftName, "休"));


                    //判断当天有没有班次
                    if (scheduleShiftDO != null) {
                        //排班信息
                        ScheduleShiftDetailVO detailVO = new ScheduleShiftDetailVO();
                        BeanUtils.copyProperties(scheduleShiftDO, detailVO);
                        AdminUserDO adminUserDO = adminUserMapper.selectById(scheduleShiftDO.getNurseId());
                        detailVO.setNurseName(adminUserDO.getNickname());

                        int count;
                        List<NursingPlanItemRespVO> dataList = new ArrayList<>();
                        //查询长者护理项目
                        List<NursingPlanDO> nursingPlanList = nursingPlanMapper.selectList(new LambdaQueryWrapperX<NursingPlanDO>()
                                .eq(NursingPlanDO::getElderId, nursingLog.getElderId())
                                .eqIfPresent(NursingPlanDO::getType, type));

                        for (NursingPlanDO nursingPlanDO : nursingPlanList) {
                            List<NursingPlanItemDO> nursingPlanItems = nursingPlanItemMapper.selectList(new LambdaQueryWrapperX<NursingPlanItemDO>()
                                    .eq(NursingPlanItemDO::getNursingPlanId, nursingPlanDO.getId())
                                    .eq(NursingPlanItemDO::getIsDelete, 0));

                            List<NursingPlanItemRespVO> collect = nursingPlanItems.stream().map(e -> {
                                NursingPlanItemRespVO respVO = new NursingPlanItemRespVO();
                                BeanUtils.copyProperties(e, respVO);

                                NurseItemDO nurseItemDO = nurseItemMapper.selectById(e.getNurseItemId());
                                NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectById(nurseItemDO.getCategoryId());

                                respVO.setCategoryId(nursingCategoryDO.getId());
                                respVO.setCategoryName(nursingCategoryDO.getCategoryName());
                                respVO.setNurseItemImage(nurseItemDO.getImage());

                                //查询护理日志详情
                                List<NursingLogRecordDO> nursingLogRecords = nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                                        .eq(NursingLogRecordDO::getNursingPlanItemId, e.getId())
                                        .eqIfPresent(NursingLogRecordDO::getNursingLogId, id)
                                        .orderByAsc(NursingLogRecordDO::getNursingTime));
                                respVO.setActualFrequency(nursingLogRecords.size()); //实际次数
                                respVO.setRecords(nursingLogRecords);
                                return respVO;
                            }).sorted(Comparator.comparing(NursingPlanItemRespVO::getActualFrequency).reversed()).collect(Collectors.toList());
                            dataList.addAll(collect);
                        }
                        if (CollectionUtil.isNotEmpty(dataList)) {
                            count = dataList.stream().mapToInt(NursingPlanItemRespVO::getActualFrequency).sum();
                            detailVO.setCount(count);
                            dataMap.put("scheduleShift", detailVO); //班次信息
                            dataMap.put("nurseItems", dataList);           //护理项目信息
                            resultList.add(dataMap);
                        }
                    }
                }
            }
        } else {
            List<NurseGroupDetailsDO> nurseGroupDetails = nurseGroupDetailsMapper.selectList(new LambdaQueryWrapperX<NurseGroupDetailsDO>()
                    .eq(NurseGroupDetailsDO::getElderId, nursingLog.getElderId())
                    .likeIfPresent(NurseGroupDetailsDO::getNursingPersonnel, caregiverName));

            for (NurseGroupDetailsDO nurseGroupDetail : nurseGroupDetails) {
                Map<String, Object> dataMap = new HashMap<>();
                String[] splitIds = nurseGroupDetail.getNursingPersonnelIds().split(",");
                for (String nurseId : splitIds) {
                    //查询当天班次信息
                    ScheduleShiftDO scheduleShiftDO = scheduleShiftMapper.selectOne(new LambdaQueryWrapperX<ScheduleShiftDO>()
                            .eq(ScheduleShiftDO::getNurseId, nurseId)
                            .eq(ScheduleShiftDO::getWorkDate, nursingLog.getNursingDate())
                            .notLike(ScheduleShiftDO::getShiftName, "休"));

                    //判断当天有没有班次
                    if (scheduleShiftDO != null) {
                        //排班信息
                        ScheduleShiftDetailVO detailVO = new ScheduleShiftDetailVO();
                        BeanUtils.copyProperties(scheduleShiftDO, detailVO);
                        AdminUserDO adminUserDO = adminUserMapper.selectById(scheduleShiftDO.getNurseId());
                        detailVO.setNurseName(adminUserDO.getNickname());

                        int count;
                        List<NursingPlanItemRespVO> dataList = new ArrayList<>();
                        //查询长者护理项目
                        List<NursingPlanDO> nursingPlanList = nursingPlanMapper.selectList(new LambdaQueryWrapperX<NursingPlanDO>()
                                .eq(NursingPlanDO::getElderId, nursingLog.getElderId())
                                .eqIfPresent(NursingPlanDO::getType, type));  //根据护理类型分裂

                        for (NursingPlanDO nursingPlanDO : nursingPlanList) {
                            List<NursingPlanItemDO> nursingPlanItems = nursingPlanItemMapper.selectList(new LambdaQueryWrapperX<NursingPlanItemDO>()
                                    .eq(NursingPlanItemDO::getNursingPlanId, nursingPlanDO.getId())
                                    .eqIfPresent(NursingPlanItemDO::getNurseItemName, nurseItemName)  //按照护理名称查询
                                    .eq(NursingPlanItemDO::getIsDelete, 0));

                            if (CollectionUtil.isNotEmpty(nursingPlanItems)) {
                                List<NursingPlanItemRespVO> collect = nursingPlanItems.stream().map(e -> {
                                    NursingPlanItemRespVO respVO = new NursingPlanItemRespVO();
                                    BeanUtils.copyProperties(e, respVO);

                                    NurseItemDO nurseItemDO = nurseItemMapper.selectById(e.getNurseItemId());
                                    NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectById(nurseItemDO.getCategoryId());

                                    respVO.setCategoryId(nursingCategoryDO.getId());
                                    respVO.setCategoryName(nursingCategoryDO.getCategoryName());
                                    respVO.setNurseItemImage(nurseItemDO.getImage());

                                    //查询护理日志详情
                                    List<NursingLogRecordDO> nursingLogRecords = nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                                            .eq(NursingLogRecordDO::getNursingPlanItemId, e.getId())
                                            .eqIfPresent(NursingLogRecordDO::getNursingLogId, id)
                                            .orderByAsc(NursingLogRecordDO::getNursingTime));
                                    respVO.setActualFrequency(nursingLogRecords.size()); //实际次数
                                    respVO.setRecords(nursingLogRecords);
                                    return respVO;
                                }).sorted(Comparator.comparing(NursingPlanItemRespVO::getActualFrequency).reversed()).collect(Collectors.toList());
                                dataList.addAll(collect);
                            }

                        }
                        if (CollectionUtil.isNotEmpty(dataList)) {
                            count = dataList.stream().mapToInt(NursingPlanItemRespVO::getActualFrequency).sum();
                            detailVO.setCount(count);
                            dataMap.put("scheduleShift", scheduleShiftDO); //班次信息
                            dataMap.put("nurseItems", dataList);           //护理项目信息
                            resultList.add(dataMap);
                        }
                    }
                }
            }
        }
        return resultList;
    }

    @Override
    public void addNursingRemarks(NursingLogRemarksDO logRemarksDO) {
        logRemarksDO.setCreatedTime(new Date());
        logRemarksDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
        nursingLogRemarksMapper.insert(logRemarksDO);
    }

    @Override
    public List<NursingLogRemarksDO> getNursingRemarks(Long id) {
        return nursingLogRemarksMapper.selectList(new LambdaQueryWrapperX<NursingLogRemarksDO>()
                .eq(NursingLogRemarksDO::getNursingLogId, id)
                .orderByDesc(NursingLogRemarksDO::getCreatedTime));
    }

    @Override
    public List<NursingLogDO> getMobileNursingLog(String elderName, Long bedId) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        //根据当前登录的护理人员ID
        //查询当前是否有班次
        List<ScheduleShiftDO> scheduleShift = scheduleShiftMapper.selectList(new LambdaQueryWrapperX<ScheduleShiftDO>()
                .eq(ScheduleShiftDO::getNurseId, loginUserId)
                .eq(ScheduleShiftDO::getWorkDate, LocalDate.now())
                .notLike(ScheduleShiftDO::getShiftName, "休"));

        boolean flag = false;
        //查询班次时间
        for (ScheduleShiftDO scheduleShiftDO : scheduleShift) {
            String shiftName = scheduleShiftDO.getShiftName();
            NursingShiftDO shiftDO = nursingShiftMapper.selectOne(new LambdaQueryWrapperX<NursingShiftDO>()
                    .eq(NursingShiftDO::getAbbreviation, shiftName));
            if (shiftDO != null && !shiftDO.getConfigs().equals("[]")) {
                String configs = shiftDO.getConfigs();
                JSONArray jsonArray = JSONArray.parseArray(configs);
                for (Object object : jsonArray) {
                    JSONObject jsonObject = JSONObject.parseObject(object.toString());
                    LocalTime startTime = LocalTime.parse((String) jsonObject.get("startTime"));
                    LocalTime endTime = LocalTime.parse((String) jsonObject.get("endTime"));
                    LocalTime timeToCheck = LocalDateTime.now().toLocalTime();
                    flag = timeToCheck.compareTo(startTime) >= 0 && timeToCheck.compareTo(endTime) <= 0;
                }
            }
        }
        List<NursingLogDO> nursingLogList = new ArrayList<>();
        if (flag) {
            //在班次时间范围里面查询当天关联的护理日志
            List<Long> elderIds = nurseGroupDetailsMapper.selectList(new LambdaQueryWrapperX<NurseGroupDetailsDO>()
                            .likeIfPresent(NurseGroupDetailsDO::getNursingPersonnelIds, loginUserId.toString())
                            .likeIfPresent(NurseGroupDetailsDO::getElderName, elderName)).stream()
                    .map(NurseGroupDetailsDO::getElderId).collect(Collectors.toList());

            nursingLogList = nursingLogMapper.selectList(new LambdaQueryWrapperX<NursingLogDO>()
                    .in(NursingLogDO::getElderId, elderIds));

            for (NursingLogDO nursingLogDO : nursingLogList) {
                ElderlyInfoDO elderlyInfo = elderlyInfoMapper.selectById(nursingLogDO.getElderId());
                nursingLogDO.setElderImage(elderlyInfo == null ? null : elderlyInfo.getElderImage());
            }

        }
        return nursingLogList;
    }

    @Override
    public void addNurseLogDetail(NursingLogRecordDO nursingLogRecordDO) {
        NursingLogDO dbNursingLogDO = nursingLogMapper.selectById(nursingLogRecordDO.getNursingLogId());

        NursingPlanItemDO nursingPlanItem = nursingPlanItemMapper.selectById(nursingLogRecordDO.getNursingPlanItemId());
        NurseItemDO nurseItemDO = nurseItemMapper.selectById(nursingPlanItem.getNurseItemId());
        NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectById(nurseItemDO.getCategoryId());
        NursingPlanDO nursingPlanDO = nursingPlanMapper.selectById(nursingPlanItem.getNursingPlanId());

        nursingLogRecordDO.setNursingLogId(dbNursingLogDO.getId());
        nursingLogRecordDO.setCategoryId(nursingCategoryDO.getId());
        nursingLogRecordDO.setCategoryName(nursingCategoryDO.getCategoryName());
        nursingLogRecordDO.setNurseItemImage(nurseItemDO.getImage());
        nursingLogRecordDO.setType(nursingPlanDO.getType());
        nursingLogRecordDO.setDataSource(2); //数据来源，1.PC 2.移动端
        nursingLogRecordMapper.insert(nursingLogRecordDO);

        //修改次数
        dbNursingLogDO.setCount(dbNursingLogDO.getCount() + 1);
        nursingLogMapper.updateById(dbNursingLogDO);
    }

    @Override
    public List<NursingLogRecordDO> getNursingRecordList(Long nursingLogId) {
        return nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                .eq(NursingLogRecordDO::getNursingLogId, nursingLogId));
    }

    @Override
    public Map<String, List<NursingPlanItemRespVO>> getNursingItemPlanList(Long nursingLogId) {
        NursingLogDO nursingLogDO = nursingLogMapper.selectById(nursingLogId);
        Long elderId = nursingLogDO.getElderId();

        List<NursingPlanDO> nursingPlanList = nursingPlanMapper.selectList(new LambdaQueryWrapperX<NursingPlanDO>()
                .eq(NursingPlanDO::getElderId, elderId));

//        List<NursingPlanItemDO> collect = nursingPlanList.stream().map(e -> nursingPlanItemMapper.
//                selectList(new LambdaQueryWrapperX<NursingPlanItemDO>()
//                        .eq(NursingPlanItemDO::getNursingPlanId, e.getId()))).flatMap(List::stream).collect(Collectors.toList());


        List<NursingPlanItemRespVO> collect = nursingPlanList.stream().map(e -> {
            List<NursingPlanItemDO> nursingPlanItems = nursingPlanItemMapper.
                    selectList(new LambdaQueryWrapperX<NursingPlanItemDO>().eq(NursingPlanItemDO::getNursingPlanId, e.getId()));

            List<NursingPlanItemRespVO> list = new ArrayList<>();
            for (NursingPlanItemDO nursingPlanItem : nursingPlanItems) {
                NursingPlanItemRespVO respVO = new NursingPlanItemRespVO();
                BeanUtils.copyProperties(nursingPlanItem, respVO);
                //查询护理日志详情
                List<NursingLogRecordDO> nursingLogRecords = nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                        .eq(NursingLogRecordDO::getNursingPlanItemId, nursingPlanItem.getId())
                        .orderByAsc(NursingLogRecordDO::getNursingTime));
                respVO.setActualFrequency(nursingLogRecords.size()); //实际次数
                respVO.setRecords(nursingLogRecords);
                list.add(respVO);
            }
            return list;
        }).flatMap(List::stream).collect(Collectors.toList());

        //根据年，月，周，日进行排序
        List<NursingPlanItemRespVO> yearList = collect.stream()
                .filter(e -> e.getFrequencyUnit().equals("4")).sorted(Comparator.comparing(NursingPlanItemRespVO::getActualFrequency).reversed())
                .collect(Collectors.toList());

        List<NursingPlanItemRespVO> monthList = collect.stream()
                .filter(e -> e.getFrequencyUnit().equals("3")).sorted(Comparator.comparing(NursingPlanItemRespVO::getActualFrequency).reversed())
                .collect(Collectors.toList());

        List<NursingPlanItemRespVO> weekList = collect.stream()
                .filter(e -> e.getFrequencyUnit().equals("2")).sorted(Comparator.comparing(NursingPlanItemRespVO::getActualFrequency).reversed())
                .collect(Collectors.toList());

        List<NursingPlanItemRespVO> dayList = collect.stream()
                .filter(e -> e.getFrequencyUnit().equals("1")).sorted(Comparator.comparing(NursingPlanItemRespVO::getActualFrequency).reversed())
                .collect(Collectors.toList());

        Map<String, List<NursingPlanItemRespVO>> dataMap = new HashMap<>();
        dataMap.put("yearList", yearList);
        dataMap.put("monthList", monthList);
        dataMap.put("weekList", weekList);
        dataMap.put("dayList", dayList);
        return dataMap;
    }

    @Override
    public PageResult<NursingLogDO> getNursingLogPage(NursingLogPageReqVO pageReqVO) {
        return nursingLogMapper.selectPage(pageReqVO);
    }

    @Override
    public List<NursingLogRespVO> getInspectionRecords(NursingInspectionQueryVO queryVO) {
        List<NurseGroupDetailsDO> nurseGroupDetails = nurseGroupDetailsMapper.selectList(new LambdaQueryWrapperX<NurseGroupDetailsDO>()
                .likeIfPresent(NurseGroupDetailsDO::getNursingPersonnelIds, SecurityFrameworkUtils.getLoginUserId().toString()));

        if (StringUtils.isNotBlank(queryVO.getCaregiver())) {
            nurseGroupDetails = nurseGroupDetails.stream()
                    .filter(e -> e.getNursingPersonnel().contains(queryVO.getCaregiver()))
                    .collect(Collectors.toList());
        }
        List<Long> elderIds = nurseGroupDetails.stream().map(NurseGroupDetailsDO::getElderId).collect(Collectors.toList());
        List<NursingLogDO> nursingLogList = nursingLogMapper.selectList(new LambdaQueryWrapperX<NursingLogDO>()
                .eqIfPresent(NursingLogDO::getNursingDate, queryVO.getQueryDate())
                .likeIfPresent(NursingLogDO::getElderName, queryVO.getElderName())
                .eqIfPresent(NursingLogDO::getBedId, queryVO.getBedId())
                .inIfPresent(NursingLogDO::getElderId, elderIds)
                .eqIfPresent(NursingLogDO::getNursingStatus, queryVO.getNursingStatus()));

        List<NursingLogRespVO> dataList = cn.iocoder.yudao.framework.common.util.object.BeanUtils.toBean(nursingLogList, NursingLogRespVO.class);
        for (NursingLogRespVO nursingLogRespVO : dataList) {
            NurseGroupDetailsDO nurseGroupDetailsDO = nurseGroupDetailsMapper.selectOne(new LambdaQueryWrapperX<NurseGroupDetailsDO>()
                    .eq(NurseGroupDetailsDO::getElderId, nursingLogRespVO.getElderId()));
            nursingLogRespVO.setNurseName(nurseGroupDetailsDO == null ? null : nurseGroupDetailsDO.getNursingPersonnel());
        }
        return dataList;
    }

    @Override
    public List<ElderlyInspectionRespVO> getInspectionDetails(Long nursingLogId) {
        NursingLogDO nursingLogDO = nursingLogMapper.selectById(nursingLogId);

        List<NursingPlanDO> nursingPlanList = nursingPlanMapper.selectList(new LambdaQueryWrapperX<NursingPlanDO>()
                .eq(NursingPlanDO::getElderId, nursingLogDO.getElderId()));

        List<NursingPlanItemDO> nursingPlanItems = nursingPlanList.stream().map(e -> nursingPlanItemMapper.selectList(new LambdaQueryWrapperX<NursingPlanItemDO>()
                .eq(NursingPlanItemDO::getNursingPlanId, e.getId()))).flatMap(List::stream).collect(Collectors.toList());

        for (NursingPlanItemDO nursingPlanItem : nursingPlanItems) {
            NurseItemDO itemDO = nurseItemMapper.selectById(nursingPlanItem.getNurseItemId());
            NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectById(itemDO.getCategoryId());
            nursingPlanItem.setCategoryName(nursingCategoryDO.getCategoryName());
        }
        Map<String, List<NursingPlanItemDO>> groupedByCategory = nursingPlanItems.stream()
                .collect(Collectors.groupingBy(NursingPlanItemDO::getCategoryName));

        List<ElderlyInspectionRespVO> dataList = new ArrayList<>();
        groupedByCategory.forEach((categoryName, items) -> {


            ElderlyInspectionRespVO respVO = new ElderlyInspectionRespVO();
            respVO.setNurseItemCategoryName(categoryName);

            List<NursingPlanItemRespVO> collect = items.stream().map(e -> {
                NursingPlanItemRespVO nursingPlanItemRespVO = new NursingPlanItemRespVO();
                BeanUtils.copyProperties(e, nursingPlanItemRespVO);

                NurseItemDO nurseItemDO = nurseItemMapper.selectById(e.getNurseItemId());

                nursingPlanItemRespVO.setNurseItemImage(nurseItemDO.getImage());

                //查询护理日志详情
                List<NursingLogRecordDO> nursingLogRecords = nursingLogRecordMapper.selectList(new LambdaQueryWrapperX<NursingLogRecordDO>()
                        .eq(NursingLogRecordDO::getNursingPlanItemId, e.getId())
                        .eqIfPresent(NursingLogRecordDO::getNursingLogId, nursingLogDO.getId())
                        .orderByAsc(NursingLogRecordDO::getNursingTime));
                nursingPlanItemRespVO.setActualFrequency(nursingLogRecords.size()); //实际次数

                //todo 计算巡检次数
                Long count = nursingInspectionMapper.selectCount(new LambdaQueryWrapperX<NursingInspectionDO>()
                        .eq(NursingInspectionDO::getNursingPlanItemId, e.getId())
                        .eq(NursingInspectionDO::getNursingLogId,nursingLogDO.getId()));
                nursingPlanItemRespVO.setInspectionCount(count.intValue());
                return nursingPlanItemRespVO;

            }).collect (Collectors.toList());
            respVO.setRecords(collect);
            dataList.add(respVO);
        });
        return dataList;
    }
}