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

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageRespVO;
import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckRespVO;
import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.elderly.ElderlySafeCheckDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyInfoMapper;
import cn.iocoder.yudao.module.system.dal.mysql.elderly.ElderlySafeCheckMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.COMMON_NOT_FOUND;

@Service
@Validated
public class ElderlySafeCheckServiceImpl implements ElderlySafeCheckService {

    @Resource
    private ElderlySafeCheckMapper safeCheckMapper;
    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createBatch(List<ElderlySafeCheckSaveReqVO> createReqList) {
        if (CollectionUtil.isEmpty(createReqList)) {
            return 0;
        }
        List<ElderlySafeCheckDO> saveList = new ArrayList<>();
        for (ElderlySafeCheckSaveReqVO createReqVO : createReqList) {
            ElderlySafeCheckDO safeCheck = BeanUtils.toBean(createReqVO, ElderlySafeCheckDO.class);
            if (safeCheck.getTenantId() == null) {
                safeCheck.setTenantId(TenantContextHolder.getTenantId());
            }
            saveList.add(safeCheck);
        }
        safeCheckMapper.insertBatch(saveList);
        return saveList.size();
    }

    @Override
    public void update(ElderlySafeCheckSaveReqVO updateReqVO) {
        validateExists(updateReqVO.getId());
        ElderlySafeCheckDO updateObj = BeanUtils.toBean(updateReqVO, ElderlySafeCheckDO.class);
        if (updateObj.getTenantId() == null) {
            updateObj.setTenantId(TenantContextHolder.getTenantId());
        }
        safeCheckMapper.updateById(updateObj);
    }

    @Override
    public void delete(Long id) {
        validateExists(id);
        safeCheckMapper.deleteById(id);
    }

    @Override
    public ElderlySafeCheckRespVO get(Long id) {
        ElderlySafeCheckDO safeCheck = safeCheckMapper.selectById(id);
        if (safeCheck == null) {
            return null;
        }
        ElderlySafeCheckRespVO respVO = BeanUtils.toBean(safeCheck, ElderlySafeCheckRespVO.class);
        fillElderInfo(Collections.singletonList(respVO));
        return respVO;
    }

    @Override
    public PageResult<ElderlySafeCheckElderPageRespVO> getElderPage(ElderlySafeCheckElderPageReqVO pageReqVO) {
        if (pageReqVO.getTenantIds() == null || pageReqVO.getTenantIds().length == 0) {
            pageReqVO.setTenantIds(new Long[]{TenantContextHolder.getTenantId()});
        }
        Page<Object> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        List<ElderlySafeCheckElderPageRespVO> list = safeCheckMapper.selectElderPage(page, pageReqVO);
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public PageResult<ElderlySafeCheckRespVO> getPage(ElderlySafeCheckPageReqVO pageReqVO) {
        if (pageReqVO.getTenantIds() == null || pageReqVO.getTenantIds().length == 0) {
            pageReqVO.setTenantIds(new Long[]{TenantContextHolder.getTenantId()});
        }
        LocalDateTime startTime = null;
        LocalDateTime endTimeExclusive = null;
        LocalDate[] checkDate = pageReqVO.getCheckDate();
        if (checkDate != null) {
            if (checkDate.length > 0 && checkDate[0] != null) {
                startTime = checkDate[0].atStartOfDay();
            }
            if (checkDate.length > 1 && checkDate[1] != null) {
                endTimeExclusive = checkDate[1].plusDays(1).atStartOfDay();
            }
        }

        PageResult<ElderlySafeCheckDO> pageResult = safeCheckMapper.selectRecordPage(pageReqVO, startTime, endTimeExclusive);
        List<ElderlySafeCheckRespVO> list = BeanUtils.toBean(pageResult.getList(), ElderlySafeCheckRespVO.class);
//        fillElderInfo(list);
        return new PageResult<>(list, pageResult.getTotal());
    }

    private void fillElderInfo(List<ElderlySafeCheckRespVO> list) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        Set<Long> elderIds = list.stream().map(ElderlySafeCheckRespVO::getElderId)
                .filter(Objects::nonNull).collect(Collectors.toSet());
        if (CollectionUtil.isEmpty(elderIds)) {
            return;
        }
        Map<Long, ElderlyInfoDO> elderMap = elderlyInfoMapper.selectBatchIds(elderIds).stream()
                .filter(e -> e.getId() != null)
                .collect(Collectors.toMap(ElderlyInfoDO::getId, Function.identity(), (a, b) -> a));
        for (ElderlySafeCheckRespVO vo : list) {
            ElderlyInfoDO elder = elderMap.get(vo.getElderId());
            if (elder == null) {
                continue;
            }
            vo.setElderName(elder.getElderName());
            vo.setRoomName(elder.getRoomName());
            vo.setBedName(elder.getBedName());
        }
    }

    private void validateExists(Long id) {
        if (id == null || safeCheckMapper.selectById(id) == null) {
            throw exception(COMMON_NOT_FOUND);
        }
    }
}
