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

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.module.system.controller.admin.home.vo.HomeElderlyInfoDetailRespVO;
import cn.iocoder.yudao.module.system.controller.admin.home.vo.HomeElderlyInfoPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.home.vo.HomeElderlyInfoPageRespVO;
import cn.iocoder.yudao.module.system.controller.admin.home.vo.HomeElderlyInfoSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyAccountDO;
import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyAccountDetailDO;
import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyFamilyDO;
import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyInfoDO;
import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyAccountDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyAccountMapper;
import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyFamilyMapper;
import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyInfoMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Validated
public class HomeElderlyInfoServiceImpl implements HomeElderlyInfoService {

    @Resource
    private HomeElderlyInfoMapper homeElderlyInfoMapper;

    @Resource
    private HomeElderlyFamilyMapper homeElderlyFamilyMapper;

    @Resource
    private HomeElderlyAccountMapper homeElderlyAccountMapper;

    @Resource
    private HomeElderlyAccountDetailMapper homeElderlyAccountDetailMapper;

    @Override
    public Long createHomeElderlyInfo(HomeElderlyInfoSaveReqVO createReqVO) {
        HomeElderlyInfoDO doObj = BeanUtils.toBean(createReqVO, HomeElderlyInfoDO.class);
        homeElderlyInfoMapper.insert(doObj);
        saveOrUpdateFamilyList(doObj.getId(), createReqVO);
        return doObj.getId();
    }

    @Override
    public void updateHomeElderlyInfo(HomeElderlyInfoSaveReqVO updateReqVO) {
        HomeElderlyInfoDO updateObj = BeanUtils.toBean(updateReqVO, HomeElderlyInfoDO.class);
        homeElderlyInfoMapper.updateById(updateObj);
        saveOrUpdateFamilyList(updateObj.getId(), updateReqVO);
    }

    @Override
    public void deleteHomeElderlyInfo(Long id) {
        homeElderlyInfoMapper.deleteById(id);
        homeElderlyFamilyMapper.delete(new LambdaQueryWrapperX<HomeElderlyFamilyDO>()
                .eq(HomeElderlyFamilyDO::getHomeElderId, id));
    }

    @Override
    public HomeElderlyInfoDetailRespVO getHomeElderlyInfo(Long id) {
        HomeElderlyInfoDO infoDO = homeElderlyInfoMapper.selectById(id);
        if (infoDO == null) {
            return null;
        }
        List<HomeElderlyFamilyDO> familyList = homeElderlyFamilyMapper.selectList(new LambdaQueryWrapperX<HomeElderlyFamilyDO>()
                .eq(HomeElderlyFamilyDO::getHomeElderId, id));
        HomeElderlyInfoDetailRespVO respVO = BeanUtils.toBean(infoDO, HomeElderlyInfoDetailRespVO.class);
        respVO.setFamilyList(familyList.stream().filter(item -> Objects.equals(item.getIsEmergency(), 0)).collect(Collectors.toList()));
        respVO.setEmergencyPerson(familyList.stream().filter(item -> Objects.equals(item.getIsEmergency(), 1)).findFirst().orElse(null));
        fillAccountInfo(respVO, id);
        return respVO;
    }

    @Override
    public PageResult<HomeElderlyInfoPageRespVO> getHomeElderlyInfoPage(HomeElderlyInfoPageReqVO pageReqVO) {
        Page<HomeElderlyInfoPageRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        List<HomeElderlyInfoPageRespVO> list = homeElderlyInfoMapper.selectPageWithAccountInfo(page, pageReqVO);
        return new PageResult<>(list, page.getTotal());
    }

    private void fillAccountInfo(HomeElderlyInfoDetailRespVO respVO, Long homeElderId) {
        HomeElderlyAccountDO accountDO = homeElderlyAccountMapper.selectOne(new LambdaQueryWrapperX<HomeElderlyAccountDO>()
                .eq(HomeElderlyAccountDO::getHomeElderId, homeElderId)
                .last("limit 1"));
        BigDecimal accountAmount = accountDO == null || accountDO.getAmount() == null ? BigDecimal.ZERO : accountDO.getAmount();
        respVO.setAccountBalance(formatAmount(accountAmount));

        BigDecimal voucherAmount = BigDecimal.ZERO;
        BigDecimal cashAmount = BigDecimal.ZERO;
        if (accountDO != null) {
            List<HomeElderlyAccountDetailDO> detailList = homeElderlyAccountDetailMapper.selectList(new LambdaQueryWrapperX<HomeElderlyAccountDetailDO>()
                    .eq(HomeElderlyAccountDetailDO::getAccountId, accountDO.getId()));
            voucherAmount = sumByType(detailList, true);
            cashAmount = sumByType(detailList, false);
        }
        respVO.setVoucherBalance(formatAmount(voucherAmount));
        respVO.setCashBalance(formatAmount(cashAmount));
    }

    private BigDecimal sumByType(List<HomeElderlyAccountDetailDO> detailList, boolean voucher) {
        if (detailList == null || detailList.isEmpty()) {
            return BigDecimal.ZERO;
        }
        return detailList.stream()
                .filter(item -> isVoucherType(item.getType()) == voucher)
                .map(HomeElderlyAccountDetailDO::getAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private boolean isVoucherType(String type) {
        if (type == null) {
            return false;
        }
        String normalized = type.trim().toLowerCase();
        return "voucher".equals(normalized) || "vouch".equals(normalized) || "1".equals(normalized) || "2".equals(normalized);
    }

    private String formatAmount(BigDecimal amount) {
        BigDecimal safeAmount = Optional.ofNullable(amount).orElse(BigDecimal.ZERO);
        return safeAmount.stripTrailingZeros().toPlainString() + "元";
    }

    private void saveOrUpdateFamilyList(Long homeElderId, HomeElderlyInfoSaveReqVO reqVO) {
        homeElderlyFamilyMapper.delete(new LambdaQueryWrapperX<HomeElderlyFamilyDO>()
                .eq(HomeElderlyFamilyDO::getHomeElderId, homeElderId));
        List<HomeElderlyFamilyDO> saveList = new ArrayList<>();
        if (reqVO.getFamilyList() != null) {
            reqVO.getFamilyList().forEach(item -> {
                if (item == null) {
                    return;
                }
                HomeElderlyFamilyDO familyDO = BeanUtils.toBean(item, HomeElderlyFamilyDO.class);
                familyDO.setId(null);
                familyDO.setHomeElderId(homeElderId);
                familyDO.setTenantId(reqVO.getTenantId());
                familyDO.setIsEmergency(0);
                saveList.add(familyDO);
            });
        }
        if (reqVO.getEmergencyPerson() != null) {
            HomeElderlyFamilyDO emergencyPerson = BeanUtils.toBean(reqVO.getEmergencyPerson(), HomeElderlyFamilyDO.class);
            emergencyPerson.setId(null);
            emergencyPerson.setHomeElderId(homeElderId);
            emergencyPerson.setTenantId(reqVO.getTenantId());
            emergencyPerson.setIsEmergency(1);
            saveList.add(emergencyPerson);
        }
        if (!saveList.isEmpty()) {
            homeElderlyFamilyMapper.insertBatch(saveList);
        }
    }
}
