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

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.ElderlyHealthFollowUpPageVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.HealthFollowUpPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.HealthFollowUpSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyHealthFollowUpDO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.FollowUpConfigDO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.SysChargeCategoryDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyHealthFollowUpMapper;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyInfoMapper;
import cn.iocoder.yudao.module.system.dal.mysql.biz.FollowUpConfigMapper;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.util.List;
import java.util.Optional;

/**
 * 长者健康随访 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class ElderlyHealthFollowUpServiceImpl implements ElderlyHealthFollowUpService {

    @Resource
    private ElderlyHealthFollowUpMapper elderlyHealthFollowUpMapper;
    @Resource
    private FollowUpConfigMapper followUpConfigMapper;
    @Resource
    private BuildService buildService;
    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;
    @Resource
    private TenantService tenantService;


    @Override
    public PageResult<ElderlyHealthFollowUpPageVO> getHealthFollowUpPage(HealthFollowUpPageReqVO pageReqVO) {
        Page<ElderlyHealthFollowUpPageVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        List<ElderlyHealthFollowUpPageVO> list = elderlyHealthFollowUpMapper.getHealthFollowUpPage(page, pageReqVO);
        //todo 下次随访时间要根据配置结算
        for (ElderlyHealthFollowUpPageVO elderlyHealthFollowUpPageVO : list) {
            elderlyHealthFollowUpPageVO.setBedName(buildService.getFullBedNameByBedId(elderlyHealthFollowUpPageVO.getBedId()));
            ElderlyInfoDO elderlyInfoDO = elderlyInfoMapper.selectById(elderlyHealthFollowUpPageVO.getElderId());
            if (elderlyInfoDO != null) {
                if (elderlyInfoDO.getFollowUpConfigId() != null) {
                    FollowUpConfigDO followUpConfigDO = followUpConfigMapper.selectById(elderlyInfoDO.getFollowUpConfigId());
                    elderlyHealthFollowUpPageVO.setFollowUpGrade(followUpConfigDO == null ? null : followUpConfigDO.getGradeName());

                    Optional<ElderlyHealthFollowUpDO> optional = elderlyHealthFollowUpMapper.selectList(new LambdaQueryWrapperX<ElderlyHealthFollowUpDO>()
                                    .eq(ElderlyHealthFollowUpDO::getElderId, elderlyInfoDO.getId()).orderByDesc(ElderlyHealthFollowUpDO::getFollowUpTime))
                            .stream().findFirst();
                    if (optional.isPresent()){
                        ElderlyHealthFollowUpDO elderlyHealthFollowUpDO = optional.get();
                        elderlyHealthFollowUpPageVO.setFollowUpTime(elderlyHealthFollowUpDO.getFollowUpTime());
                    }
                    TenantDO tenant = tenantService.getTenant(elderlyInfoDO.getTenantId());
                    elderlyHealthFollowUpPageVO.setTenantName(tenant == null ? null : tenant.getName());
                    if (followUpConfigDO != null && elderlyHealthFollowUpPageVO.getFollowUpTime() != null) {
                        Integer gradeValue = followUpConfigDO.getGradeValue();
                        LocalDateTime lastFollowUpDate = elderlyHealthFollowUpPageVO.getFollowUpTime();
                        elderlyHealthFollowUpPageVO.setNextFollowUpTime(lastFollowUpDate.plusDays(gradeValue));
                    }
                }
            }
        }
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public void createHealthFollowUpGrade(List<FollowUpConfigDO> configs) {
        for (FollowUpConfigDO config : configs) {
            if (config.getId() != null) {
                followUpConfigMapper.updateById(config);
            } else {
                followUpConfigMapper.insert(config);
            }
        }
    }

    @Override
    public void createHealthFollowUp(HealthFollowUpSaveReqVO createReqVO) {
        ElderlyHealthFollowUpDO elderlyHealthFollowUpDO = new ElderlyHealthFollowUpDO();
        BeanUtils.copyProperties(createReqVO, elderlyHealthFollowUpDO);
        elderlyHealthFollowUpMapper.insert(elderlyHealthFollowUpDO);
    }

    @Override
    public void updateHealthFollowUp(HealthFollowUpSaveReqVO updateReqVO) {
        ElderlyHealthFollowUpDO elderlyHealthFollowUpDO = elderlyHealthFollowUpMapper.selectById(updateReqVO.getId());
        BeanUtils.copyProperties(updateReqVO, elderlyHealthFollowUpDO);
        elderlyHealthFollowUpMapper.updateById(elderlyHealthFollowUpDO);
    }

    @Override
    public List<ElderlyHealthFollowUpDO> getHealthFollowUpByConditions(HealthFollowUpPageReqVO pageReqVO) {
        return elderlyHealthFollowUpMapper.selectList(new LambdaQueryWrapperX<ElderlyHealthFollowUpDO>()
                .eqIfPresent(ElderlyHealthFollowUpDO::getElderId, pageReqVO.getElderId())
                .eqIfPresent(ElderlyHealthFollowUpDO::getType, pageReqVO.getType())
                .betweenIfPresent(ElderlyHealthFollowUpDO::getFollowUpTime, pageReqVO.getFollowUpTime())
                .orderByDesc(ElderlyHealthFollowUpDO::getFollowUpTime));
    }

    @Override
    public List<FollowUpConfigDO> getHealthFollowUpGrade(Long tenantId) {
        return followUpConfigMapper.selectList(new LambdaQueryWrapperX<FollowUpConfigDO>()
                .eq(FollowUpConfigDO::getTenantId, tenantId));
    }

    @Override
    public List<ElderlyHealthFollowUpDO> getLastElderlyHealthFollowRecords(Long elderId) {
        return elderlyHealthFollowUpMapper.selectList(new LambdaQueryWrapperX<ElderlyHealthFollowUpDO>()
                .eq(ElderlyHealthFollowUpDO::getElderId, elderId).last("LIMIT 7"));
    }

    @Override
    public ElderlyHealthFollowUpDO getElderlyHealthFollowDetail(Long id) {
        ElderlyHealthFollowUpDO elderlyHealthFollowUpDO = elderlyHealthFollowUpMapper.selectById(id);
        if (elderlyHealthFollowUpDO != null){
            elderlyHealthFollowUpDO.setBedName(buildService.getFullBedNameByBedId(elderlyHealthFollowUpDO.getBedId()));
        }
        return elderlyHealthFollowUpDO;
    }

    @Override
    public void updateFollowUpGrade(Long elderId, Long followUpGradeId) {
        ElderlyInfoDO elderlyInfoDO = elderlyInfoMapper.selectById(elderId);
        elderlyInfoDO.setFollowUpConfigId(followUpGradeId);
        elderlyInfoMapper.updateById(elderlyInfoDO);
    }
}