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

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.ElderlyMedicationExecutionRespVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.MedicationExecutionPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.MedicationExecutionRecordResVO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.*;
import cn.iocoder.yudao.module.system.dal.mysql.biz.*;
import cn.iocoder.yudao.module.system.enums.common.BooleanEnum;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.util.*;
import java.util.stream.Collectors;

/**
 * 长者用药执行记录 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class MedicationExecutionServiceImpl implements MedicationExecutionService {

    @Resource
    private BuildService buildService;
    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;

    @Resource
    private MedicationMapper medicationMapper;

    @Resource
    private ByodRegistrationMapper byodRegistrationMapper;

    @Resource
    private MedicationExecutionMapper medicationExecutionMapper;

    @Resource
    private ByodRegistrationDrugMapper byodRegistrationDrugMapper;


    @Override
    public PageResult<ElderlyMedicationExecutionRespVO> getElderlyMedicationExecutionPage(MedicationExecutionPageReqVO pageReqVO) {
        Page<ElderlyMedicationExecutionRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        List<ElderlyMedicationExecutionRespVO> list = elderlyInfoMapper.getElderlyMedicationExecutionPage(page, pageReqVO);
        for (ElderlyMedicationExecutionRespVO elderlyMedicationExecutionRespVO : list) {
            elderlyMedicationExecutionRespVO.setBedName(buildService.getFullBedName(elderlyMedicationExecutionRespVO.getElderId()));

            List<ByodRegistrationDO> byodRegistrationList = byodRegistrationMapper.selectList(new LambdaQueryWrapperX<ByodRegistrationDO>()
                    .eq(ByodRegistrationDO::getElderId, elderlyMedicationExecutionRespVO.getElderId()));

            if (CollectionUtil.isNotEmpty(byodRegistrationList)) {
                Long count = 0L;
                for (ByodRegistrationDO byodRegistrationDO : byodRegistrationList) {
                    if (byodRegistrationDO != null) {
                        count += byodRegistrationDrugMapper
                                .selectCount(new LambdaQueryWrapperX<ByodRegistrationDrugDO>()
                                        .eq(ByodRegistrationDrugDO::getByodRegistrationId, byodRegistrationDO.getId()));
                    }
                }
                elderlyMedicationExecutionRespVO.setCount(count.intValue());
            }

        }
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public void changeStatus(Long elderId) {
        ByodRegistrationDO byodRegistrationDO = byodRegistrationMapper
                .selectOne(new LambdaQueryWrapperX<ByodRegistrationDO>()
                        .eq(ByodRegistrationDO::getElderId, elderId));

        if (byodRegistrationDO != null) {
            byodRegistrationDO.setExecuteStatus(BooleanEnum.TRUE.getValue());
            byodRegistrationMapper.updateById(byodRegistrationDO);
        }
    }

    @Override
    public void createMedicationExecution(MedicationExecutionDO createReqVO) {
        createReqVO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
        createReqVO.setCreatedTime(LocalDateTime.now());
        medicationExecutionMapper.insert(createReqVO);
    }

    @Override
    public MedicationExecutionRecordResVO getMedicationExecutionRecords(Long elderId, Long medicationId) {
        MedicationExecutionRecordResVO resVO = new MedicationExecutionRecordResVO();
        List<MedicationExecutionDO> medicationExecutionList = medicationExecutionMapper.selectList(new LambdaQueryWrapperX<MedicationExecutionDO>()
                .eq(MedicationExecutionDO::getMedicationId, medicationId)
                .eq(MedicationExecutionDO::getElderId, elderId)
                .orderByDesc(MedicationExecutionDO::getExecutionTime));


        Optional<MedicationExecutionDO> optional = medicationExecutionList.stream().findFirst();
        if (optional.isPresent()) {
            MedicationExecutionDO medicationExecutionDO = optional.get();
            resVO.setDrugName(medicationExecutionDO.getDrugName());
            MedicationDO medicationDO = medicationMapper.selectById(medicationId);
            resVO.setAdministrationTime(medicationDO == null ? null : medicationDO.getAdministrationTime());

            Map<String, List<MedicationExecutionDO>> collect = medicationExecutionList
                    .stream()
                    .collect(Collectors.groupingBy(item -> item.getExecutionDate().toString()));

            List<Map<String, Object>> dataList = collect.keySet().stream().map(key -> {
                Map<String, Object> map = new HashMap<>();
                map.put("executionDate", key);
                map.put("data", collect.get(key));
                return map;
            }).collect(Collectors.toList());

            resVO.setDataList(dataList);
        }
        return resVO;
    }

    @Override
    public PageResult<MedicationExecutionDO> getMedicationExecutionPage(MedicationExecutionPageReqVO pageReqVO) {
        return medicationExecutionMapper.selectPage(pageReqVO);
    }
}