package cn.iocoder.yudao.module.member.service.money;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.money.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.money.MoneyDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.member.dal.mysql.money.MoneyMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

/**
 * 金额 Service 实现类
 *
 * @author 秦俊旗
 */
@Service
@Validated
public class MoneyServiceImpl implements MoneyService {

    @Resource
    private MoneyMapper moneyMapper;

    @Override
    public Long createMoney(MoneySaveReqVO createReqVO) {
        // 插入
        MoneyDO money = BeanUtils.toBean(createReqVO, MoneyDO.class);
        moneyMapper.insert(money);
        // 返回
        return money.getId();
    }

    @Override
    public void updateMoney(MoneySaveReqVO updateReqVO) {
        // 校验存在
        validateMoneyExists(updateReqVO.getId());
        // 更新
        MoneyDO updateObj = BeanUtils.toBean(updateReqVO, MoneyDO.class);
        moneyMapper.updateById(updateObj);
    }

    @Override
    public void deleteMoney(Long id) {
        // 校验存在
        validateMoneyExists(id);
        // 删除
        moneyMapper.deleteById(id);
    }

    private void validateMoneyExists(Long id) {
        if (moneyMapper.selectById(id) == null) {
            throw exception(MONEY_NOT_EXISTS);
        }
    }

    @Override
    public MoneyDO getMoney(Long id) {
        return moneyMapper.selectById(id);
    }

    @Override
    public PageResult<MoneyDO> getMoneyPage(MoneyPageReqVO pageReqVO) {
        return moneyMapper.selectPage(pageReqVO);
    }

    @Override
    public MoneyDO getMoney(Long userId, Long carteenId) {
        return moneyMapper.selectOne(new LambdaQueryWrapper<MoneyDO>().eq(MoneyDO::getUserId, userId).eq(MoneyDO::getCarteenId, carteenId));
    }

    @Override
    public BigDecimal getAllMoney(Long userId) {
        List<MoneyDO> moneyDOS = moneyMapper.selectList(new LambdaQueryWrapper<MoneyDO>().eq(MoneyDO::getUserId, userId));
        if(CollectionUtil.isNotEmpty(moneyDOS)){
            return moneyDOS.stream().map(MoneyDO::getCashAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        return BigDecimal.ZERO;
    }

    @Override
    public List<MoneyDO> getAllDebt(Long userId) {

        return moneyMapper.selectList(new LambdaQueryWrapper<MoneyDO>().eq(MoneyDO::getUserId, userId));
    }

    @Override
    public void updateById(MoneyDO moneyDO) {
        moneyMapper.updateById(moneyDO);
    }

    @Override
    public void insertOne(MoneyDO moneyDO) {
        moneyMapper.insert(moneyDO);
    }

    @Override
    public void updateList(List<MoneyDO> moneyDOs) {
        moneyMapper.updateBatch(moneyDOs);
    }

    @Override
    public void cleanDebt(List<Long> debtId) {
        if(CollectionUtil.isNotEmpty(debtId)){
            moneyMapper.update(new LambdaUpdateWrapper<MoneyDO>().in(MoneyDO::getId, debtId)
                    .set(MoneyDO::getDebtAmount, BigDecimal.ZERO));
        }

    }
}