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.*;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.elderly.ElderlyLifeAssistantInspectionDO;
import cn.iocoder.yudao.module.system.dal.dataobject.elderly.ElderlyLifeAssistantInspectionItemDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyInfoMapper;
import cn.iocoder.yudao.module.system.dal.mysql.elderly.ElderlyLifeAssistantInspectionItemMapper;
import cn.iocoder.yudao.module.system.dal.mysql.elderly.ElderlyLifeAssistantInspectionMapper;
import cn.iocoder.yudao.module.system.service.biz.BuildService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

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

@Service
@Validated
public class ElderlyLifeAssistantInspectionServiceImpl implements ElderlyLifeAssistantInspectionService {

    @Resource
    private ElderlyLifeAssistantInspectionMapper inspectionMapper;
    @Resource
    private ElderlyLifeAssistantInspectionItemMapper inspectionItemMapper;
    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;
    @Resource
    private BuildService buildService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(ElderlyLifeAssistantInspectionSaveReqVO createReqVO) {
        ElderlyLifeAssistantInspectionDO inspection = BeanUtils.toBean(createReqVO, ElderlyLifeAssistantInspectionDO.class);
        if (inspection.getTenantId() == null) {
            inspection.setTenantId(TenantContextHolder.getTenantId());
        }
        inspectionMapper.insert(inspection);

        saveItems(inspection.getId(), inspection.getTenantId(), createReqVO.getItems());
        return inspection.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ElderlyLifeAssistantInspectionSaveReqVO updateReqVO) {
        ElderlyLifeAssistantInspectionDO inspection = BeanUtils.toBean(updateReqVO, ElderlyLifeAssistantInspectionDO.class);
        if (inspection.getTenantId() == null) {
            inspection.setTenantId(TenantContextHolder.getTenantId());
        }
        inspectionMapper.updateById(inspection);

        inspectionItemMapper.deleteByInspectionId(inspection.getId());
        saveItems(inspection.getId(), inspection.getTenantId(), updateReqVO.getItems());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        inspectionItemMapper.deleteByInspectionId(id);
        inspectionMapper.deleteById(id);
    }

    @Override
    public ElderlyLifeAssistantInspectionRespVO get(Long id) {
        ElderlyLifeAssistantInspectionDO inspection = inspectionMapper.selectById(id);
        if (inspection == null) {
            return null;
        }

        ElderlyLifeAssistantInspectionRespVO respVO = BeanUtils.toBean(inspection, ElderlyLifeAssistantInspectionRespVO.class);

        ElderlyInfoDO elderly = elderlyInfoMapper.selectById(inspection.getElderId());
        if (elderly != null) {
            respVO.setElderName(elderly.getElderName());
        }
        respVO.setBedName(buildService.getFullBedName(inspection.getElderId()));

        List<ElderlyLifeAssistantInspectionItemDO> items = inspectionItemMapper.selectListByInspectionId(id);
        respVO.setItems(BeanUtils.toBean(items, ElderlyLifeAssistantInspectionItemRespVO.class));
        return respVO;
    }

    @Override
    public PageResult<ElderlyLifeAssistantInspectionRespVO> getPage(ElderlyLifeAssistantInspectionPageReqVO pageReqVO) {
        Long[] tenantIds = pageReqVO.getTenantIds();
        if (tenantIds == null || tenantIds.length == 0) {
            pageReqVO.setTenantIds(new Long[]{TenantContextHolder.getTenantId()});
        }

        // elderName -> elderIds
        List<Long> elderIds;
        if (pageReqVO.getElderName() != null && !pageReqVO.getElderName().trim().isEmpty()) {
            List<ElderlyInfoDO> elders = elderlyInfoMapper.selectList(new LambdaQueryWrapperX<ElderlyInfoDO>()
                            .inIfPresent(ElderlyInfoDO::getTenantId, pageReqVO.getTenantIds())
                            .like(ElderlyInfoDO::getElderName, pageReqVO.getElderName()));
            elderIds = elders.stream().map(ElderlyInfoDO::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
            if (elderIds.isEmpty()) {
                return PageResult.empty();
            }
        } else {
            elderIds = null;
        }

        PageResult<ElderlyLifeAssistantInspectionDO> pageResult = inspectionMapper.selectPage(pageReqVO);
        List<ElderlyLifeAssistantInspectionDO> list = pageResult.getList();

        if (elderIds != null) {
            list = list.stream().filter(r -> elderIds.contains(r.getElderId())).collect(Collectors.toList());
            pageResult.setList(list);
            pageResult.setTotal((long) list.size());
        }

        Map<Long, ElderlyInfoDO> elderMap = new HashMap<>();
        Set<Long> pageElderIds = list.stream().map(ElderlyLifeAssistantInspectionDO::getElderId)
                .filter(Objects::nonNull).collect(Collectors.toSet());
        if (CollectionUtil.isNotEmpty(pageElderIds)) {
            List<ElderlyInfoDO> elders = elderlyInfoMapper.selectBatchIds(pageElderIds);
            elderMap = elders.stream().filter(e -> e.getId() != null)
                    .collect(Collectors.toMap(ElderlyInfoDO::getId, Function.identity(), (a, b) -> a));
        }

        List<ElderlyLifeAssistantInspectionRespVO> voList = BeanUtils.toBean(list, ElderlyLifeAssistantInspectionRespVO.class);
        for (ElderlyLifeAssistantInspectionRespVO vo : voList) {
            ElderlyInfoDO elder = elderMap.get(vo.getElderId());
            if (elder != null) {
                vo.setElderName(elder.getElderName());
            }
            vo.setBedName(buildService.getFullBedName(vo.getElderId()));
        }

        return new PageResult<>(voList, pageResult.getTotal());
    }

    private void saveItems(Long inspectionId, Long tenantId, List<ElderlyLifeAssistantInspectionItemSaveReqVO> itemReqList) {
        if (CollectionUtil.isEmpty(itemReqList)) {
            return;
        }
        for (ElderlyLifeAssistantInspectionItemSaveReqVO itemReq : itemReqList) {
            ElderlyLifeAssistantInspectionItemDO item = BeanUtils.toBean(itemReq, ElderlyLifeAssistantInspectionItemDO.class);
            item.setLifeAssistantInspectionId(inspectionId);
            item.setTenantId(tenantId);
            inspectionItemMapper.insert(item);
        }
    }
}

